[clang] Implement the `fmod` intrinsic (PR #130320)
Kaitlin Peng via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 12 09:38:39 PDT 2025
https://github.com/kmpeng updated https://github.com/llvm/llvm-project/pull/130320
>From 0f6a8ea36c8f3d2abac4f836433d091463f9e393 Mon Sep 17 00:00:00 2001
From: kmpeng <kaitlinpeng at microsoft.com>
Date: Tue, 25 Feb 2025 14:50:09 -0800
Subject: [PATCH 01/11] start implementation
---
clang/lib/Headers/hlsl/hlsl_detail.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h b/clang/lib/Headers/hlsl/hlsl_detail.h
index c691d85283de4..c6dd5494f149f 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -45,6 +45,20 @@ template <typename T> struct is_arithmetic {
static const bool Value = __is_arithmetic(T);
};
+template <typename T, int N>
+constexpr enable_if_t<is_same<float, T>::value || is_same<half, T>::value, T>
+fmod_vec_impl(vector<T, N> X, vector<T, N> Y) {
+#if !defined(__DirectX__)
+ return __builtin_elementwise_fmod(X, Y);
+#else
+ vector<T, N> div = X / Y;
+ vector<T, N> result = __builtin_hlsl_elementwise_frac(__builtin_elementwise_abs(div)) * Y;
+ vector<bool, N> condition = (div >= -div);
+ vector<T, N> realResult = __builtin_hlsl_select(condition, result, -result);
+ return realResult;
+#endif
+}
+
} // namespace __detail
} // namespace hlsl
#endif //_HLSL_HLSL_DETAILS_H_
>From 071717aa974eab61ae95ace845115c845725096b Mon Sep 17 00:00:00 2001
From: kmpeng <kaitlinpeng at microsoft.com>
Date: Wed, 26 Feb 2025 15:57:59 -0800
Subject: [PATCH 02/11] finished implementation, working on fmod.hlsl tests
---
clang/lib/Headers/hlsl/hlsl_detail.h | 14 +++++++---
clang/test/CodeGenHLSL/builtins/fmod.hlsl | 32 +++++++++++------------
2 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h b/clang/lib/Headers/hlsl/hlsl_detail.h
index c6dd5494f149f..f43d449ce8b7b 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -45,6 +45,12 @@ template <typename T> struct is_arithmetic {
static const bool Value = __is_arithmetic(T);
};
+template <typename T>
+constexpr enable_if_t<is_same<float, T>::value || is_same<half, T>::value, T>
+fmod_impl(T X, T Y) {
+ return __builtin_elementwise_fmod(X, Y);
+}
+
template <typename T, int N>
constexpr enable_if_t<is_same<float, T>::value || is_same<half, T>::value, T>
fmod_vec_impl(vector<T, N> X, vector<T, N> Y) {
@@ -52,10 +58,10 @@ fmod_vec_impl(vector<T, N> X, vector<T, N> Y) {
return __builtin_elementwise_fmod(X, Y);
#else
vector<T, N> div = X / Y;
- vector<T, N> result = __builtin_hlsl_elementwise_frac(__builtin_elementwise_abs(div)) * Y;
- vector<bool, N> condition = (div >= -div);
- vector<T, N> realResult = __builtin_hlsl_select(condition, result, -result);
- return realResult;
+ vector<bool, N> ge = div >= -div;
+ vector<T, N> frc = __builtin_hlsl_elementwise_frac(__builtin_elementwise_abs(div));
+ vector<T, N> realFrc = __builtin_hlsl_select(ge, frc, -frc);
+ return realFrc * Y;
#endif
}
diff --git a/clang/test/CodeGenHLSL/builtins/fmod.hlsl b/clang/test/CodeGenHLSL/builtins/fmod.hlsl
index b62967114d456..22376638bd093 100644
--- a/clang/test/CodeGenHLSL/builtins/fmod.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/fmod.hlsl
@@ -36,42 +36,42 @@
// CHECK: define [[FNATTRS]] [[TYPE]] @
-// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn [[TYPE]]
-// CHECK: ret [[TYPE]] %fmod
+// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}([[TYPE]] noundef nofpclass(nan inf) %{{.*}}, [[TYPE]] noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
+// CHECK: ret [[TYPE]] %call
half test_fmod_half(half p0, half p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <2 x [[TYPE]]> @
-// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
-// CHECK: ret <2 x [[TYPE]]> %fmod
+// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}(<2 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}, <2 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
+// CHECK: ret <2 x [[TYPE]]> %splat.splat
half2 test_fmod_half2(half2 p0, half2 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <3 x [[TYPE]]> @
-// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
-// CHECK: ret <3 x [[TYPE]]> %fmod
+// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}(<3 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}, <3 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}} #{{.*}}
+// CHECK: ret <3 x [[TYPE]]> %splat.splat
half3 test_fmod_half3(half3 p0, half3 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <4 x [[TYPE]]> @
-// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
-// CHECK: ret <4 x [[TYPE]]> %fmod
+// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}(<4 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}, <4 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
+// CHECK: ret <4 x [[TYPE]]> %splat.splat
half4 test_fmod_half4(half4 p0, half4 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] float @
-// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn float
-// CHECK: ret float %fmod
+// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(float noundef nofpclass(nan inf) %{{.*}}, float noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
+// CHECK: ret float %call
float test_fmod_float(float p0, float p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <2 x float> @
-// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <2 x float>
-// CHECK: ret <2 x float> %fmod
+// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(<2 x float> noundef nofpclass(nan inf) %{{.*}}, <2 x float> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
+// CHECK: ret <2 x float> %splat.splat
float2 test_fmod_float2(float2 p0, float2 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <3 x float> @
-// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <3 x float>
-// CHECK: ret <3 x float> %fmod
+// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(<3 x float> noundef nofpclass(nan inf) %{{.*}}, <3 x float> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
+// CHECK: ret <3 x float> %splat.splat
float3 test_fmod_float3(float3 p0, float3 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <4 x float> @
-// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <4 x float>
-// CHECK: ret <4 x float> %fmod
+// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(<4 x float> noundef nofpclass(nan inf) %{{.*}}, <4 x float> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
+// CHECK: ret <4 x float> %splat.splat
float4 test_fmod_float4(float4 p0, float4 p1) { return fmod(p0, p1); }
>From 806c1767a3973d9f41f022be35c09eb34f9455c0 Mon Sep 17 00:00:00 2001
From: kmpeng <kaitlinpeng at microsoft.com>
Date: Thu, 27 Feb 2025 13:40:52 -0800
Subject: [PATCH 03/11] tweaked implementation to exclude vec1 & restrict to
vec4, created new fmod-directx.hlsl test file, removed directx tests from
fmod.hlsl
---
clang/lib/Headers/hlsl/hlsl_detail.h | 13 ++--
.../CodeGenHLSL/builtins/fmod-directx.hlsl | 59 +++++++++++++++++++
clang/test/CodeGenHLSL/builtins/fmod.hlsl | 50 +++++-----------
3 files changed, 84 insertions(+), 38 deletions(-)
create mode 100644 clang/test/CodeGenHLSL/builtins/fmod-directx.hlsl
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h b/clang/lib/Headers/hlsl/hlsl_detail.h
index f43d449ce8b7b..f6f2e1a8c3b97 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -48,20 +48,25 @@ template <typename T> struct is_arithmetic {
template <typename T>
constexpr enable_if_t<is_same<float, T>::value || is_same<half, T>::value, T>
fmod_impl(T X, T Y) {
+#if !defined(__DirectX__)
return __builtin_elementwise_fmod(X, Y);
+#else
+ T div = X / Y;
+ bool ge = div >= -div;
+ T frc = __builtin_hlsl_elementwise_frac(__builtin_elementwise_abs(div));
+ return __builtin_hlsl_select(ge, frc, -frc) * Y;
+#endif
}
template <typename T, int N>
-constexpr enable_if_t<is_same<float, T>::value || is_same<half, T>::value, T>
-fmod_vec_impl(vector<T, N> X, vector<T, N> Y) {
+constexpr vector<T, N> fmod_vec_impl(vector<T, N> X, vector<T, N> Y) {
#if !defined(__DirectX__)
return __builtin_elementwise_fmod(X, Y);
#else
vector<T, N> div = X / Y;
vector<bool, N> ge = div >= -div;
vector<T, N> frc = __builtin_hlsl_elementwise_frac(__builtin_elementwise_abs(div));
- vector<T, N> realFrc = __builtin_hlsl_select(ge, frc, -frc);
- return realFrc * Y;
+ return __builtin_hlsl_select(ge, frc, -frc) * Y;
#endif
}
diff --git a/clang/test/CodeGenHLSL/builtins/fmod-directx.hlsl b/clang/test/CodeGenHLSL/builtins/fmod-directx.hlsl
new file mode 100644
index 0000000000000..9b5c0f595cfd3
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/fmod-directx.hlsl
@@ -0,0 +1,59 @@
+// DirectX target:
+//
+// ---------- Native Half support test -----------
+//
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
+// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTYPE=half
+
+//
+// ---------- No Native Half support test -----------
+//
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
+// RUN: -o - | FileCheck %s \
+// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTYPE=float
+
+
+
+// CHECK: define [[FNATTRS]] [[TYPE]] @
+// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}([[TYPE]] noundef nofpclass(nan inf) %{{.*}}, [[TYPE]] noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
+// CHECK: ret [[TYPE]] %call
+half test_fmod_half(half p0, half p1) { return fmod(p0, p1); }
+
+// CHECK: define [[FNATTRS]] <2 x [[TYPE]]> @
+// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}(<2 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}, <2 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
+// CHECK: ret <2 x [[TYPE]]> %splat.splat
+half2 test_fmod_half2(half2 p0, half2 p1) { return fmod(p0, p1); }
+
+// CHECK: define [[FNATTRS]] <3 x [[TYPE]]> @
+// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}(<3 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}, <3 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}} #{{.*}}
+// CHECK: ret <3 x [[TYPE]]> %splat.splat
+half3 test_fmod_half3(half3 p0, half3 p1) { return fmod(p0, p1); }
+
+// CHECK: define [[FNATTRS]] <4 x [[TYPE]]> @
+// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}(<4 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}, <4 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
+// CHECK: ret <4 x [[TYPE]]> %splat.splat
+half4 test_fmod_half4(half4 p0, half4 p1) { return fmod(p0, p1); }
+
+// CHECK: define [[FNATTRS]] float @
+// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(float noundef nofpclass(nan inf) %{{.*}}, float noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
+// CHECK: ret float %call
+float test_fmod_float(float p0, float p1) { return fmod(p0, p1); }
+
+// CHECK: define [[FNATTRS]] <2 x float> @
+// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(<2 x float> noundef nofpclass(nan inf) %{{.*}}, <2 x float> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
+// CHECK: ret <2 x float> %splat.splat
+float2 test_fmod_float2(float2 p0, float2 p1) { return fmod(p0, p1); }
+
+// CHECK: define [[FNATTRS]] <3 x float> @
+// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(<3 x float> noundef nofpclass(nan inf) %{{.*}}, <3 x float> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
+// CHECK: ret <3 x float> %splat.splat
+float3 test_fmod_float3(float3 p0, float3 p1) { return fmod(p0, p1); }
+
+// CHECK: define [[FNATTRS]] <4 x float> @
+// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(<4 x float> noundef nofpclass(nan inf) %{{.*}}, <4 x float> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
+// CHECK: ret <4 x float> %splat.splat
+float4 test_fmod_float4(float4 p0, float4 p1) { return fmod(p0, p1); }
+
diff --git a/clang/test/CodeGenHLSL/builtins/fmod.hlsl b/clang/test/CodeGenHLSL/builtins/fmod.hlsl
index 22376638bd093..db0c97e066430 100644
--- a/clang/test/CodeGenHLSL/builtins/fmod.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/fmod.hlsl
@@ -1,21 +1,3 @@
-// DirectX target:
-//
-// ---------- Native Half support test -----------
-//
-// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
-// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
-// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
-// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTYPE=half
-
-//
-// ---------- No Native Half support test -----------
-//
-// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
-// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
-// RUN: -o - | FileCheck %s \
-// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTYPE=float
-
-
// Spirv target:
//
// ---------- Native Half support test -----------
@@ -36,42 +18,42 @@
// CHECK: define [[FNATTRS]] [[TYPE]] @
-// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}([[TYPE]] noundef nofpclass(nan inf) %{{.*}}, [[TYPE]] noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
-// CHECK: ret [[TYPE]] %call
+// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn [[TYPE]]
+// CHECK: ret [[TYPE]] %fmod
half test_fmod_half(half p0, half p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <2 x [[TYPE]]> @
-// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}(<2 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}, <2 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
-// CHECK: ret <2 x [[TYPE]]> %splat.splat
+// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
+// CHECK: ret <2 x [[TYPE]]> %fmod
half2 test_fmod_half2(half2 p0, half2 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <3 x [[TYPE]]> @
-// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}(<3 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}, <3 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}} #{{.*}}
-// CHECK: ret <3 x [[TYPE]]> %splat.splat
+// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
+// CHECK: ret <3 x [[TYPE]]> %fmod
half3 test_fmod_half3(half3 p0, half3 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <4 x [[TYPE]]> @
-// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}(<4 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}, <4 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
-// CHECK: ret <4 x [[TYPE]]> %splat.splat
+// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
+// CHECK: ret <4 x [[TYPE]]> %fmod
half4 test_fmod_half4(half4 p0, half4 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] float @
-// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(float noundef nofpclass(nan inf) %{{.*}}, float noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
-// CHECK: ret float %call
+// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn float
+// CHECK: ret float %fmod
float test_fmod_float(float p0, float p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <2 x float> @
-// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(<2 x float> noundef nofpclass(nan inf) %{{.*}}, <2 x float> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
-// CHECK: ret <2 x float> %splat.splat
+// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <2 x float>
+// CHECK: ret <2 x float> %fmod
float2 test_fmod_float2(float2 p0, float2 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <3 x float> @
-// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(<3 x float> noundef nofpclass(nan inf) %{{.*}}, <3 x float> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
-// CHECK: ret <3 x float> %splat.splat
+// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <3 x float>
+// CHECK: ret <3 x float> %fmod
float3 test_fmod_float3(float3 p0, float3 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <4 x float> @
-// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(<4 x float> noundef nofpclass(nan inf) %{{.*}}, <4 x float> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
-// CHECK: ret <4 x float> %splat.splat
+// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <4 x float>
+// CHECK: ret <4 x float> %fmod
float4 test_fmod_float4(float4 p0, float4 p1) { return fmod(p0, p1); }
>From 51ed6ef6225db6221ddaee4a7ebbd8f67eef6f2e Mon Sep 17 00:00:00 2001
From: kmpeng <kaitlinpeng at microsoft.com>
Date: Thu, 27 Feb 2025 16:30:12 -0800
Subject: [PATCH 04/11] fixed hlsl_intrinsics header return types, disabled
llvm passes in spirv tests
---
.../CodeGenHLSL/builtins/fmod-directx.hlsl | 6 ++--
clang/test/CodeGenHLSL/builtins/fmod.hlsl | 36 +++++++++----------
2 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/clang/test/CodeGenHLSL/builtins/fmod-directx.hlsl b/clang/test/CodeGenHLSL/builtins/fmod-directx.hlsl
index 9b5c0f595cfd3..f2ac50155597a 100644
--- a/clang/test/CodeGenHLSL/builtins/fmod-directx.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/fmod-directx.hlsl
@@ -4,7 +4,7 @@
//
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
-// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
+// RUN: -emit-llvm -disable-llvm-passes -O1 -o - | FileCheck %s \
// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTYPE=half
//
@@ -12,13 +12,13 @@
//
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
-// RUN: -o - | FileCheck %s \
+// RUN: -O1 -o - | FileCheck %s \
// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTYPE=float
// CHECK: define [[FNATTRS]] [[TYPE]] @
-// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}([[TYPE]] noundef nofpclass(nan inf) %{{.*}}, [[TYPE]] noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
+// CHECK: call nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}([[TYPE]] noundef nofpclass(nan inf) %{{.*}}, [[TYPE]] noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
// CHECK: ret [[TYPE]] %call
half test_fmod_half(half p0, half p1) { return fmod(p0, p1); }
diff --git a/clang/test/CodeGenHLSL/builtins/fmod.hlsl b/clang/test/CodeGenHLSL/builtins/fmod.hlsl
index db0c97e066430..facb9f46cff21 100644
--- a/clang/test/CodeGenHLSL/builtins/fmod.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/fmod.hlsl
@@ -4,56 +4,56 @@
//
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \
-// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
+// RUN: -emit-llvm -o - | FileCheck %s \
// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTYPE=half
//
// ---------- No Native Half support test -----------
//
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
-// RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \
+// RUN: spirv-unknown-vulkan-compute %s -emit-llvm \
// RUN: -o - | FileCheck %s \
// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTYPE=float
// CHECK: define [[FNATTRS]] [[TYPE]] @
-// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn [[TYPE]]
-// CHECK: ret [[TYPE]] %fmod
+// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn [[TYPE]]
+// CHECK: ret [[TYPE]] %fmod.i
half test_fmod_half(half p0, half p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <2 x [[TYPE]]> @
-// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
-// CHECK: ret <2 x [[TYPE]]> %fmod
+// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
+// CHECK: ret <2 x [[TYPE]]> %fmod.i
half2 test_fmod_half2(half2 p0, half2 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <3 x [[TYPE]]> @
-// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
-// CHECK: ret <3 x [[TYPE]]> %fmod
+// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
+// CHECK: ret <3 x [[TYPE]]> %fmod.i
half3 test_fmod_half3(half3 p0, half3 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <4 x [[TYPE]]> @
-// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
-// CHECK: ret <4 x [[TYPE]]> %fmod
+// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
+// CHECK: ret <4 x [[TYPE]]> %fmod.i
half4 test_fmod_half4(half4 p0, half4 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] float @
-// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn float
-// CHECK: ret float %fmod
+// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn float
+// CHECK: ret float %fmod.i
float test_fmod_float(float p0, float p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <2 x float> @
-// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <2 x float>
-// CHECK: ret <2 x float> %fmod
+// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x float>
+// CHECK: ret <2 x float> %fmod.i
float2 test_fmod_float2(float2 p0, float2 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <3 x float> @
-// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <3 x float>
-// CHECK: ret <3 x float> %fmod
+// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x float>
+// CHECK: ret <3 x float> %fmod.i
float3 test_fmod_float3(float3 p0, float3 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <4 x float> @
-// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <4 x float>
-// CHECK: ret <4 x float> %fmod
+// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x float>
+// CHECK: ret <4 x float> %fmod.i
float4 test_fmod_float4(float4 p0, float4 p1) { return fmod(p0, p1); }
>From 3bf7314fbe712c4ba36d2cea0fe0dce3f8817e31 Mon Sep 17 00:00:00 2001
From: kmpeng <kaitlinpeng at microsoft.com>
Date: Wed, 5 Mar 2025 15:21:06 -0800
Subject: [PATCH 05/11] Modified implementation after reorganization of
instrinsics, finished fmod-directx.hlsl tests
---
.../lib/Headers/hlsl/hlsl_alias_intrinsics.h | 34 --------
clang/lib/Headers/hlsl/hlsl_detail.h | 12 +--
clang/lib/Headers/hlsl/hlsl_intrinsics.h | 32 +++++++
.../CodeGenHLSL/builtins/fmod-directx.hlsl | 85 ++++++++++++++-----
4 files changed, 104 insertions(+), 59 deletions(-)
diff --git a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
index 89dfeb475488e..62054b368691d 100644
--- a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
@@ -1237,40 +1237,6 @@ float3 floor(float3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_floor)
float4 floor(float4);
-//===----------------------------------------------------------------------===//
-// fmod builtins
-//===----------------------------------------------------------------------===//
-
-/// \fn T fmod(T x, T y)
-/// \brief Returns the linear interpolation of x to y.
-/// \param x [in] The dividend.
-/// \param y [in] The divisor.
-///
-/// Return the floating-point remainder of the x parameter divided by the y
-/// parameter.
-
-_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_fmod)
-half fmod(half, half);
-_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_fmod)
-half2 fmod(half2, half2);
-_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_fmod)
-half3 fmod(half3, half3);
-_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_fmod)
-half4 fmod(half4, half4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_fmod)
-float fmod(float, float);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_fmod)
-float2 fmod(float2, float2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_fmod)
-float3 fmod(float3, float3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_fmod)
-float4 fmod(float4, float4);
-
//===----------------------------------------------------------------------===//
// frac builtins
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h b/clang/lib/Headers/hlsl/hlsl_detail.h
index f6f2e1a8c3b97..1d61abb5dff88 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -48,25 +48,25 @@ template <typename T> struct is_arithmetic {
template <typename T>
constexpr enable_if_t<is_same<float, T>::value || is_same<half, T>::value, T>
fmod_impl(T X, T Y) {
-#if !defined(__DirectX__)
+#if !defined(__DIRECTX__)
return __builtin_elementwise_fmod(X, Y);
#else
T div = X / Y;
bool ge = div >= -div;
- T frc = __builtin_hlsl_elementwise_frac(__builtin_elementwise_abs(div));
- return __builtin_hlsl_select(ge, frc, -frc) * Y;
+ T frc = frac(abs(div));
+ return select<T>(ge, frc, -frc) * Y;
#endif
}
template <typename T, int N>
constexpr vector<T, N> fmod_vec_impl(vector<T, N> X, vector<T, N> Y) {
-#if !defined(__DirectX__)
+#if !defined(__DIRECTX__)
return __builtin_elementwise_fmod(X, Y);
#else
vector<T, N> div = X / Y;
vector<bool, N> ge = div >= -div;
- vector<T, N> frc = __builtin_hlsl_elementwise_frac(__builtin_elementwise_abs(div));
- return __builtin_hlsl_select(ge, frc, -frc) * Y;
+ vector<T, N> frc = frac(abs(div));
+ return select<T>(ge, frc, -frc) * Y;
#endif
}
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index cd6d836578787..e625aa8a654e8 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -109,6 +109,38 @@ const inline float distance(vector<float, N> X, vector<float, N> Y) {
return __detail::distance_vec_impl(X, Y);
}
+//===----------------------------------------------------------------------===//
+// fmod builtins
+//===----------------------------------------------------------------------===//
+
+/// \fn T fmod(T x, T y)
+/// \brief Returns the linear interpolation of x to y.
+/// \param x [in] The dividend.
+/// \param y [in] The divisor.
+///
+/// Return the floating-point remainder of the x parameter divided by the y
+/// parameter.
+
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+const inline half fmod(half X, half Y) {
+ return __detail::fmod_impl(X, Y);
+}
+
+const inline float fmod(float X, float Y) {
+ return __detail::fmod_impl(X, Y);
+}
+
+template <int N>
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+const inline vector<half, N> fmod(vector<half, N> X, vector<half, N> Y) {
+ return __detail::fmod_vec_impl(X, Y);
+}
+
+template <int N>
+const inline vector<float, N> fmod(vector<float, N> X, vector<float, N> Y) {
+ return __detail::fmod_vec_impl(X, Y);
+}
+
//===----------------------------------------------------------------------===//
// length builtins
//===----------------------------------------------------------------------===//
diff --git a/clang/test/CodeGenHLSL/builtins/fmod-directx.hlsl b/clang/test/CodeGenHLSL/builtins/fmod-directx.hlsl
index f2ac50155597a..d995edddeb814 100644
--- a/clang/test/CodeGenHLSL/builtins/fmod-directx.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/fmod-directx.hlsl
@@ -4,56 +4,103 @@
//
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
-// RUN: -emit-llvm -disable-llvm-passes -O1 -o - | FileCheck %s \
+// RUN: -emit-llvm -O1 -o - | FileCheck %s \
// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTYPE=half
-
//
// ---------- No Native Half support test -----------
//
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
-// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
+// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm \
// RUN: -O1 -o - | FileCheck %s \
// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTYPE=float
// CHECK: define [[FNATTRS]] [[TYPE]] @
-// CHECK: call nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}([[TYPE]] noundef nofpclass(nan inf) %{{.*}}, [[TYPE]] noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
-// CHECK: ret [[TYPE]] %call
+// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn [[TYPE]]
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge [[TYPE]]
+// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.fabs.f
+// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.dx.frac.f
+// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn [[TYPE]]
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn [[TYPE]]
+// CHECK: ret [[TYPE]] %mul.i
half test_fmod_half(half p0, half p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <2 x [[TYPE]]> @
-// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}(<2 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}, <2 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
-// CHECK: ret <2 x [[TYPE]]> %splat.splat
+// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x [[TYPE]]>
+// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.fabs.v2f
+// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.dx.frac.v2f
+// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1>
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
+// CHECK: ret <2 x [[TYPE]]> %mul.i
half2 test_fmod_half2(half2 p0, half2 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <3 x [[TYPE]]> @
-// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}(<3 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}, <3 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}} #{{.*}}
-// CHECK: ret <3 x [[TYPE]]> %splat.splat
+// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x [[TYPE]]>
+// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.fabs.v3f
+// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.dx.frac.v3f
+// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1>
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
+// CHECK: ret <3 x [[TYPE]]> %mul.i
half3 test_fmod_half3(half3 p0, half3 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <4 x [[TYPE]]> @
-// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}(<4 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}, <4 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
-// CHECK: ret <4 x [[TYPE]]> %splat.splat
+// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x [[TYPE]]>
+// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.fabs.v4f
+// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.dx.frac.v4f
+// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1>
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
+// CHECK: ret <4 x [[TYPE]]> %mul.i
half4 test_fmod_half4(half4 p0, half4 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] float @
-// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(float noundef nofpclass(nan inf) %{{.*}}, float noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
-// CHECK: ret float %call
+// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn float
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge float
+// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f
+// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn float @llvm.dx.frac.f
+// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn float
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float
+// CHECK: ret float %mul.i
float test_fmod_float(float p0, float p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <2 x float> @
-// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(<2 x float> noundef nofpclass(nan inf) %{{.*}}, <2 x float> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
-// CHECK: ret <2 x float> %splat.splat
+// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x float>
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x float>
+// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.fabs.v2f
+// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.dx.frac.v2f
+// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <2 x float>
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1>
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x float>
+// CHECK: ret <2 x float> %mul.i
float2 test_fmod_float2(float2 p0, float2 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <3 x float> @
-// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(<3 x float> noundef nofpclass(nan inf) %{{.*}}, <3 x float> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
-// CHECK: ret <3 x float> %splat.splat
+// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x float>
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x float>
+// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.fabs.v3f
+// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.dx.frac.v3f
+// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <3 x float>
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1>
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x float>
+// CHECK: ret <3 x float> %mul.i
float3 test_fmod_float3(float3 p0, float3 p1) { return fmod(p0, p1); }
// CHECK: define [[FNATTRS]] <4 x float> @
-// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(<4 x float> noundef nofpclass(nan inf) %{{.*}}, <4 x float> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
-// CHECK: ret <4 x float> %splat.splat
+// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x float>
+// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x float>
+// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f
+// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.frac.v4f
+// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <4 x float>
+// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1>
+// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x float>
+// CHECK: ret <4 x float> %mul.i
float4 test_fmod_float4(float4 p0, float4 p1) { return fmod(p0, p1); }
>From 7da401dba1362df9ced46b83bd67f58c25df5e30 Mon Sep 17 00:00:00 2001
From: kmpeng <kaitlinpeng at microsoft.com>
Date: Wed, 5 Mar 2025 15:45:01 -0800
Subject: [PATCH 06/11] Added fmod Sema error checks
---
clang/test/SemaHLSL/BuiltIns/fmod-errors.hlsl | 33 +++++++++++++++++++
1 file changed, 33 insertions(+)
create mode 100644 clang/test/SemaHLSL/BuiltIns/fmod-errors.hlsl
diff --git a/clang/test/SemaHLSL/BuiltIns/fmod-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/fmod-errors.hlsl
new file mode 100644
index 0000000000000..86f5a6f7bea9c
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/fmod-errors.hlsl
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify
+
+float test_no_second_arg(float2 p0) {
+ return fmod(p0);
+ // expected-error at -1 {{no matching function for call to 'fmod'}}
+ // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 1 was provided}}
+ // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 1 was provided}}
+ // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 1 was provided}}
+ // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 1 was provided}}
+}
+
+float test_too_many_arg(float2 p0) {
+ return fmod(p0, p0, p0);
+ // expected-error at -1 {{no matching function for call to 'fmod'}}
+ // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 3 were provided}}
+ // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 3 were provided}}
+ // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 3 were provided}}
+ // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 3 were provided}}
+}
+
+float test_double_inputs(double p0, double p1) {
+ return fmod(p0, p1);
+ // expected-error at -1 {{call to 'fmod' is ambiguous}}
+ // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function}}
+ // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function}}
+}
+
+float test_int_inputs(int p0, int p1) {
+ return fmod(p0, p1);
+ // expected-error at -1 {{call to 'fmod' is ambiguous}}
+ // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function}}
+ // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function}}
+}
>From b355e0c77d20b346317d827c73fc75f2f2e3a5d4 Mon Sep 17 00:00:00 2001
From: kmpeng <kaitlinpeng at microsoft.com>
Date: Thu, 6 Mar 2025 14:42:13 -0800
Subject: [PATCH 07/11] Merge fmod-directx.hlsl tests back into fmod.hlsl
---
.../CodeGenHLSL/builtins/fmod-directx.hlsl | 106 ------------------
clang/test/CodeGenHLSL/builtins/fmod.hlsl | 106 ++++++++++++++++++
2 files changed, 106 insertions(+), 106 deletions(-)
delete mode 100644 clang/test/CodeGenHLSL/builtins/fmod-directx.hlsl
diff --git a/clang/test/CodeGenHLSL/builtins/fmod-directx.hlsl b/clang/test/CodeGenHLSL/builtins/fmod-directx.hlsl
deleted file mode 100644
index d995edddeb814..0000000000000
--- a/clang/test/CodeGenHLSL/builtins/fmod-directx.hlsl
+++ /dev/null
@@ -1,106 +0,0 @@
-// DirectX target:
-//
-// ---------- Native Half support test -----------
-//
-// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
-// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
-// RUN: -emit-llvm -O1 -o - | FileCheck %s \
-// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTYPE=half
-//
-// ---------- No Native Half support test -----------
-//
-// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
-// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm \
-// RUN: -O1 -o - | FileCheck %s \
-// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTYPE=float
-
-
-
-// CHECK: define [[FNATTRS]] [[TYPE]] @
-// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn [[TYPE]]
-// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge [[TYPE]]
-// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.fabs.f
-// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.dx.frac.f
-// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn [[TYPE]]
-// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1
-// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn [[TYPE]]
-// CHECK: ret [[TYPE]] %mul.i
-half test_fmod_half(half p0, half p1) { return fmod(p0, p1); }
-
-// CHECK: define [[FNATTRS]] <2 x [[TYPE]]> @
-// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
-// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x [[TYPE]]>
-// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.fabs.v2f
-// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.dx.frac.v2f
-// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
-// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1>
-// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
-// CHECK: ret <2 x [[TYPE]]> %mul.i
-half2 test_fmod_half2(half2 p0, half2 p1) { return fmod(p0, p1); }
-
-// CHECK: define [[FNATTRS]] <3 x [[TYPE]]> @
-// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
-// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x [[TYPE]]>
-// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.fabs.v3f
-// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.dx.frac.v3f
-// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
-// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1>
-// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
-// CHECK: ret <3 x [[TYPE]]> %mul.i
-half3 test_fmod_half3(half3 p0, half3 p1) { return fmod(p0, p1); }
-
-// CHECK: define [[FNATTRS]] <4 x [[TYPE]]> @
-// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
-// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x [[TYPE]]>
-// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.fabs.v4f
-// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.dx.frac.v4f
-// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
-// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1>
-// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
-// CHECK: ret <4 x [[TYPE]]> %mul.i
-half4 test_fmod_half4(half4 p0, half4 p1) { return fmod(p0, p1); }
-
-// CHECK: define [[FNATTRS]] float @
-// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn float
-// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge float
-// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f
-// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn float @llvm.dx.frac.f
-// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn float
-// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1
-// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float
-// CHECK: ret float %mul.i
-float test_fmod_float(float p0, float p1) { return fmod(p0, p1); }
-
-// CHECK: define [[FNATTRS]] <2 x float> @
-// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x float>
-// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x float>
-// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.fabs.v2f
-// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.dx.frac.v2f
-// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <2 x float>
-// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1>
-// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x float>
-// CHECK: ret <2 x float> %mul.i
-float2 test_fmod_float2(float2 p0, float2 p1) { return fmod(p0, p1); }
-
-// CHECK: define [[FNATTRS]] <3 x float> @
-// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x float>
-// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x float>
-// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.fabs.v3f
-// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.dx.frac.v3f
-// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <3 x float>
-// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1>
-// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x float>
-// CHECK: ret <3 x float> %mul.i
-float3 test_fmod_float3(float3 p0, float3 p1) { return fmod(p0, p1); }
-
-// CHECK: define [[FNATTRS]] <4 x float> @
-// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x float>
-// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x float>
-// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f
-// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.frac.v4f
-// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <4 x float>
-// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1>
-// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x float>
-// CHECK: ret <4 x float> %mul.i
-float4 test_fmod_float4(float4 p0, float4 p1) { return fmod(p0, p1); }
-
diff --git a/clang/test/CodeGenHLSL/builtins/fmod.hlsl b/clang/test/CodeGenHLSL/builtins/fmod.hlsl
index facb9f46cff21..359463b914c98 100644
--- a/clang/test/CodeGenHLSL/builtins/fmod.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/fmod.hlsl
@@ -1,3 +1,21 @@
+// DirectX target:
+//
+// ---------- Native Half support test -----------
+//
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
+// RUN: -emit-llvm -o - | FileCheck %s -DFNATTRS="noundef nofpclass(nan inf)" \
+// RUN: -DTYPE=half --check-prefixes=DXCHECK,DXNATIVE_HALF
+
+//
+// ---------- No Native Half support test -----------
+//
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm \
+// RUN: -o - | FileCheck %s -DFNATTRS="noundef nofpclass(nan inf)" \
+// RUN: -DTYPE=float --check-prefixes=DXCHECK,DXNO_HALF
+
+
// Spirv target:
//
// ---------- Native Half support test -----------
@@ -17,41 +35,129 @@
+// DXCHECK: define [[FNATTRS]] [[TYPE]] @
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn [[TYPE]]
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn [[TYPE]]
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge [[TYPE]]
+// DXNATIVE_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.fabs.f16([[TYPE]]
+// DXNO_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.fabs.f32([[TYPE]]
+// DXNATIVE_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.dx.frac.f16([[TYPE]]
+// DXNO_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.dx.frac.f32([[TYPE]]
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn [[TYPE]]
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn [[TYPE]]
+// DXCHECK: ret [[TYPE]] %mul.i
// CHECK: define [[FNATTRS]] [[TYPE]] @
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn [[TYPE]]
// CHECK: ret [[TYPE]] %fmod.i
half test_fmod_half(half p0, half p1) { return fmod(p0, p1); }
+// DXCHECK: define [[FNATTRS]] <2 x [[TYPE]]> @
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x [[TYPE]]>
+// DXNATIVE_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.fabs.v2f16(<2 x [[TYPE]]>
+// DXNO_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.fabs.v2f32(<2 x [[TYPE]]>
+// DXNATIVE_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.dx.frac.v2f16(<2 x [[TYPE]]>
+// DXNO_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.dx.frac.v2f32(<2 x [[TYPE]]>
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1>
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
+// DXCHECK: ret <2 x [[TYPE]]> %mul.i
// CHECK: define [[FNATTRS]] <2 x [[TYPE]]> @
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
// CHECK: ret <2 x [[TYPE]]> %fmod.i
half2 test_fmod_half2(half2 p0, half2 p1) { return fmod(p0, p1); }
+// DXCHECK: define [[FNATTRS]] <3 x [[TYPE]]> @
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x [[TYPE]]>
+// DXNATIVE_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.fabs.v3f16(<3 x [[TYPE]]>
+// DXNO_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.fabs.v3f32(<3 x [[TYPE]]>
+// DXNATIVE_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.dx.frac.v3f16(<3 x [[TYPE]]>
+// DXNO_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.dx.frac.v3f32(<3 x [[TYPE]]>
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1>
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
+// DXCHECK: ret <3 x [[TYPE]]> %mul.i
// CHECK: define [[FNATTRS]] <3 x [[TYPE]]> @
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
// CHECK: ret <3 x [[TYPE]]> %fmod.i
half3 test_fmod_half3(half3 p0, half3 p1) { return fmod(p0, p1); }
+// DXCHECK: define [[FNATTRS]] <4 x [[TYPE]]> @
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x [[TYPE]]>
+// DXNATIVE_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.fabs.v4f16(<4 x [[TYPE]]>
+// DXNO_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.fabs.v4f32(<4 x [[TYPE]]>
+// DXNATIVE_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.dx.frac.v4f16(<4 x [[TYPE]]>
+// DXNO_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.dx.frac.v4f32(<4 x [[TYPE]]>
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1>
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
+// DXCHECK: ret <4 x [[TYPE]]> %mul.i
// CHECK: define [[FNATTRS]] <4 x [[TYPE]]> @
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
// CHECK: ret <4 x [[TYPE]]> %fmod.i
half4 test_fmod_half4(half4 p0, half4 p1) { return fmod(p0, p1); }
+// DXCHECK: define [[FNATTRS]] float @
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn float
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn float
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge float
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float
+// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn float @llvm.dx.frac.f32(float
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn float
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float
+// DXCHECK: ret float %mul.i
// CHECK: define [[FNATTRS]] float @
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn float
// CHECK: ret float %fmod.i
float test_fmod_float(float p0, float p1) { return fmod(p0, p1); }
+// DXCHECK: define [[FNATTRS]] <2 x float> @
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x float>
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x float>
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x float>
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.fabs.v2f32(<2 x float>
+// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.dx.frac.v2f32(<2 x float>
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <2 x float>
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1>
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x float>
+// DXCHECK: ret <2 x float> %mul.i
// CHECK: define [[FNATTRS]] <2 x float> @
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x float>
// CHECK: ret <2 x float> %fmod.i
float2 test_fmod_float2(float2 p0, float2 p1) { return fmod(p0, p1); }
+// DXCHECK: define [[FNATTRS]] <3 x float> @
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x float>
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x float>
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x float>
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.fabs.v3f32(<3 x float>
+// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.dx.frac.v3f32(<3 x float>
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <3 x float>
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1>
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x float>
+// DXCHECK: ret <3 x float> %mul.i
// CHECK: define [[FNATTRS]] <3 x float> @
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x float>
// CHECK: ret <3 x float> %fmod.i
float3 test_fmod_float3(float3 p0, float3 p1) { return fmod(p0, p1); }
+// DXCHECK: define [[FNATTRS]] <4 x float> @
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x float>
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x float>
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x float>
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f32(<4 x float>
+// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.frac.v4f32(<4 x float>
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <4 x float>
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1>
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x float>
+// DXCHECK: ret <4 x float> %mul.i
// CHECK: define [[FNATTRS]] <4 x float> @
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x float>
// CHECK: ret <4 x float> %fmod.i
>From 14f8be17a83363e2272bcd8e4c04c14bd4285d41 Mon Sep 17 00:00:00 2001
From: kmpeng <kaitlinpeng at microsoft.com>
Date: Fri, 7 Mar 2025 15:16:25 -0800
Subject: [PATCH 08/11] Added SPVCHECK prefix & changed function definition
checks in fmod.hlsl tests, formatted files with clang-format
---
clang/lib/Headers/hlsl/hlsl_detail.h | 6 +-
clang/lib/Headers/hlsl/hlsl_intrinsics.h | 8 +--
clang/test/CodeGenHLSL/builtins/fmod.hlsl | 68 ++++++++++-------------
3 files changed, 35 insertions(+), 47 deletions(-)
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h b/clang/lib/Headers/hlsl/hlsl_detail.h
index 1d61abb5dff88..38012fd9ea14d 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -50,7 +50,7 @@ constexpr enable_if_t<is_same<float, T>::value || is_same<half, T>::value, T>
fmod_impl(T X, T Y) {
#if !defined(__DIRECTX__)
return __builtin_elementwise_fmod(X, Y);
-#else
+#else
T div = X / Y;
bool ge = div >= -div;
T frc = frac(abs(div));
@@ -62,10 +62,10 @@ template <typename T, int N>
constexpr vector<T, N> fmod_vec_impl(vector<T, N> X, vector<T, N> Y) {
#if !defined(__DIRECTX__)
return __builtin_elementwise_fmod(X, Y);
-#else
+#else
vector<T, N> div = X / Y;
vector<bool, N> ge = div >= -div;
- vector<T, N> frc = frac(abs(div));
+ vector<T, N> frc = frac(abs(div));
return select<T>(ge, frc, -frc) * Y;
#endif
}
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index e625aa8a654e8..ce37e1e204020 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -122,13 +122,9 @@ const inline float distance(vector<float, N> X, vector<float, N> Y) {
/// parameter.
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
-const inline half fmod(half X, half Y) {
- return __detail::fmod_impl(X, Y);
-}
+const inline half fmod(half X, half Y) { return __detail::fmod_impl(X, Y); }
-const inline float fmod(float X, float Y) {
- return __detail::fmod_impl(X, Y);
-}
+const inline float fmod(float X, float Y) { return __detail::fmod_impl(X, Y); }
template <int N>
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
diff --git a/clang/test/CodeGenHLSL/builtins/fmod.hlsl b/clang/test/CodeGenHLSL/builtins/fmod.hlsl
index 359463b914c98..a0f5b481b00ee 100644
--- a/clang/test/CodeGenHLSL/builtins/fmod.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/fmod.hlsl
@@ -4,16 +4,16 @@
//
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
-// RUN: -emit-llvm -o - | FileCheck %s -DFNATTRS="noundef nofpclass(nan inf)" \
-// RUN: -DTYPE=half --check-prefixes=DXCHECK,DXNATIVE_HALF
+// RUN: -emit-llvm -o - | FileCheck %s \
+// RUN: -DTYPE=half --check-prefixes=CHECK,DXCHECK,DXNATIVE_HALF
//
// ---------- No Native Half support test -----------
//
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm \
-// RUN: -o - | FileCheck %s -DFNATTRS="noundef nofpclass(nan inf)" \
-// RUN: -DTYPE=float --check-prefixes=DXCHECK,DXNO_HALF
+// RUN: -o - | FileCheck %s \
+// RUN: -DTYPE=float --check-prefixes=CHECK,DXCHECK,DXNO_HALF
// Spirv target:
@@ -23,7 +23,7 @@
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \
// RUN: -emit-llvm -o - | FileCheck %s \
-// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTYPE=half
+// RUN: -DTYPE=half --check-prefixes=CHECK,SPVCHECK
//
// ---------- No Native Half support test -----------
@@ -31,11 +31,11 @@
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: spirv-unknown-vulkan-compute %s -emit-llvm \
// RUN: -o - | FileCheck %s \
-// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTYPE=float
+// RUN: -DTYPE=float --check-prefixes=CHECK,SPVCHECK
-// DXCHECK: define [[FNATTRS]] [[TYPE]] @
+// CHECK-LABEL: test_fmod_half
// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn [[TYPE]]
// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn [[TYPE]]
// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge [[TYPE]]
@@ -47,12 +47,11 @@
// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1
// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn [[TYPE]]
// DXCHECK: ret [[TYPE]] %mul.i
-// CHECK: define [[FNATTRS]] [[TYPE]] @
-// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn [[TYPE]]
-// CHECK: ret [[TYPE]] %fmod.i
+// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn [[TYPE]]
+// SPVCHECK: ret [[TYPE]] %fmod.i
half test_fmod_half(half p0, half p1) { return fmod(p0, p1); }
-// DXCHECK: define [[FNATTRS]] <2 x [[TYPE]]> @
+// CHECK-LABEL: test_fmod_half2
// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x [[TYPE]]>
@@ -64,12 +63,11 @@ half test_fmod_half(half p0, half p1) { return fmod(p0, p1); }
// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1>
// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
// DXCHECK: ret <2 x [[TYPE]]> %mul.i
-// CHECK: define [[FNATTRS]] <2 x [[TYPE]]> @
-// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
-// CHECK: ret <2 x [[TYPE]]> %fmod.i
+// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
+// SPVCHECK: ret <2 x [[TYPE]]> %fmod.i
half2 test_fmod_half2(half2 p0, half2 p1) { return fmod(p0, p1); }
-// DXCHECK: define [[FNATTRS]] <3 x [[TYPE]]> @
+// CHECK-LABEL: test_fmod_half3
// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x [[TYPE]]>
@@ -81,12 +79,11 @@ half2 test_fmod_half2(half2 p0, half2 p1) { return fmod(p0, p1); }
// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1>
// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
// DXCHECK: ret <3 x [[TYPE]]> %mul.i
-// CHECK: define [[FNATTRS]] <3 x [[TYPE]]> @
-// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
-// CHECK: ret <3 x [[TYPE]]> %fmod.i
+// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
+// SPVCHECK: ret <3 x [[TYPE]]> %fmod.i
half3 test_fmod_half3(half3 p0, half3 p1) { return fmod(p0, p1); }
-// DXCHECK: define [[FNATTRS]] <4 x [[TYPE]]> @
+// CHECK-LABEL: test_fmod_half4
// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x [[TYPE]]>
@@ -98,12 +95,11 @@ half3 test_fmod_half3(half3 p0, half3 p1) { return fmod(p0, p1); }
// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1>
// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
// DXCHECK: ret <4 x [[TYPE]]> %mul.i
-// CHECK: define [[FNATTRS]] <4 x [[TYPE]]> @
-// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
-// CHECK: ret <4 x [[TYPE]]> %fmod.i
+// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
+// SPVCHECK: ret <4 x [[TYPE]]> %fmod.i
half4 test_fmod_half4(half4 p0, half4 p1) { return fmod(p0, p1); }
-// DXCHECK: define [[FNATTRS]] float @
+// CHECK-LABEL: test_fmod_float
// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn float
// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn float
// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge float
@@ -113,12 +109,11 @@ half4 test_fmod_half4(half4 p0, half4 p1) { return fmod(p0, p1); }
// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1
// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float
// DXCHECK: ret float %mul.i
-// CHECK: define [[FNATTRS]] float @
-// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn float
-// CHECK: ret float %fmod.i
+// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn float
+// SPVCHECK: ret float %fmod.i
float test_fmod_float(float p0, float p1) { return fmod(p0, p1); }
-// DXCHECK: define [[FNATTRS]] <2 x float> @
+// CHECK-LABEL: test_fmod_float2
// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x float>
// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x float>
// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x float>
@@ -128,12 +123,11 @@ float test_fmod_float(float p0, float p1) { return fmod(p0, p1); }
// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1>
// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x float>
// DXCHECK: ret <2 x float> %mul.i
-// CHECK: define [[FNATTRS]] <2 x float> @
-// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x float>
-// CHECK: ret <2 x float> %fmod.i
+// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x float>
+// SPVCHECK: ret <2 x float> %fmod.i
float2 test_fmod_float2(float2 p0, float2 p1) { return fmod(p0, p1); }
-// DXCHECK: define [[FNATTRS]] <3 x float> @
+// CHECK-LABEL: test_fmod_float3
// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x float>
// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x float>
// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x float>
@@ -143,12 +137,11 @@ float2 test_fmod_float2(float2 p0, float2 p1) { return fmod(p0, p1); }
// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1>
// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x float>
// DXCHECK: ret <3 x float> %mul.i
-// CHECK: define [[FNATTRS]] <3 x float> @
-// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x float>
-// CHECK: ret <3 x float> %fmod.i
+// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x float>
+// SPVCHECK: ret <3 x float> %fmod.i
float3 test_fmod_float3(float3 p0, float3 p1) { return fmod(p0, p1); }
-// DXCHECK: define [[FNATTRS]] <4 x float> @
+// CHECK-LABEL: test_fmod_float4
// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x float>
// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x float>
// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x float>
@@ -158,8 +151,7 @@ float3 test_fmod_float3(float3 p0, float3 p1) { return fmod(p0, p1); }
// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1>
// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x float>
// DXCHECK: ret <4 x float> %mul.i
-// CHECK: define [[FNATTRS]] <4 x float> @
-// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x float>
-// CHECK: ret <4 x float> %fmod.i
+// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x float>
+// SPVCHECK: ret <4 x float> %fmod.i
float4 test_fmod_float4(float4 p0, float4 p1) { return fmod(p0, p1); }
>From d4b909598a7a43a83dc8fe8b1c478d4d518b872f Mon Sep 17 00:00:00 2001
From: kmpeng <kaitlinpeng at microsoft.com>
Date: Fri, 7 Mar 2025 16:54:15 -0800
Subject: [PATCH 09/11] Modify fmod.hlsl tests to include operands of each
instruction
---
clang/test/CodeGenHLSL/builtins/fmod.hlsl | 160 +++++++++++-----------
1 file changed, 80 insertions(+), 80 deletions(-)
diff --git a/clang/test/CodeGenHLSL/builtins/fmod.hlsl b/clang/test/CodeGenHLSL/builtins/fmod.hlsl
index a0f5b481b00ee..9e128bc9329cf 100644
--- a/clang/test/CodeGenHLSL/builtins/fmod.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/fmod.hlsl
@@ -36,122 +36,122 @@
// CHECK-LABEL: test_fmod_half
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn [[TYPE]]
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn [[TYPE]]
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge [[TYPE]]
-// DXNATIVE_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.fabs.f16([[TYPE]]
-// DXNO_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.fabs.f32([[TYPE]]
-// DXNATIVE_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.dx.frac.f16([[TYPE]]
-// DXNO_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.dx.frac.f32([[TYPE]]
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn [[TYPE]]
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn [[TYPE]]
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn [[TYPE]] [[X:%.*]], [[Y:%.*]]
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn [[TYPE]] [[DIV1_I:%.*]]
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge [[TYPE]] [[DIV1_I_2:%.*]], %fneg.i
+// DXNATIVE_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.fabs.f16([[TYPE]] [[DIV1_I_3:%.*]])
+// DXNO_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.fabs.f32([[TYPE]] [[DIV1_I_3:%.*]])
+// DXNATIVE_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.dx.frac.f16([[TYPE]] %elt.abs.i)
+// DXNO_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.dx.frac.f32([[TYPE]] %elt.abs.i)
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn [[TYPE]] [[HLSL_FRAC_I:%.*]]
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 [[CMP_I:%.*]], [[TYPE]] [[HLSL_FRAC_I_2:%.*]], [[TYPE]] %fneg2.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn [[TYPE]] %hlsl.select.i, [[Y_2:%.*]]
// DXCHECK: ret [[TYPE]] %mul.i
-// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn [[TYPE]]
+// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn [[TYPE]] [[X:%.*]], [[Y:%.*]]
// SPVCHECK: ret [[TYPE]] %fmod.i
half test_fmod_half(half p0, half p1) { return fmod(p0, p1); }
// CHECK-LABEL: test_fmod_half2
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x [[TYPE]]>
-// DXNATIVE_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.fabs.v2f16(<2 x [[TYPE]]>
-// DXNO_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.fabs.v2f32(<2 x [[TYPE]]>
-// DXNATIVE_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.dx.frac.v2f16(<2 x [[TYPE]]>
-// DXNO_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.dx.frac.v2f32(<2 x [[TYPE]]>
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1>
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> [[X:%.*]], [[Y:%.*]]
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> [[DIV1_I:%.*]]
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x [[TYPE]]> [[DIV1_I_2:%.*]], %fneg.i
+// DXNATIVE_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.fabs.v2f16(<2 x [[TYPE]]> [[DIV1_I_3:%.*]])
+// DXNO_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.fabs.v2f32(<2 x [[TYPE]]> [[DIV1_I_3:%.*]])
+// DXNATIVE_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.dx.frac.v2f16(<2 x [[TYPE]]> %elt.abs.i)
+// DXNO_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.dx.frac.v2f32(<2 x [[TYPE]]> %elt.abs.i)
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> [[HLSL_FRAC_I:%.*]]
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1> [[CMP_I:%.*]], <2 x [[TYPE]]> [[HLSL_FRAC_I_2:%.*]], <2 x [[TYPE]]> %fneg2.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> %hlsl.select.i, [[Y_2:%.*]]
// DXCHECK: ret <2 x [[TYPE]]> %mul.i
-// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
+// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> [[X:%.*]], [[Y:%.*]]
// SPVCHECK: ret <2 x [[TYPE]]> %fmod.i
half2 test_fmod_half2(half2 p0, half2 p1) { return fmod(p0, p1); }
// CHECK-LABEL: test_fmod_half3
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x [[TYPE]]>
-// DXNATIVE_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.fabs.v3f16(<3 x [[TYPE]]>
-// DXNO_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.fabs.v3f32(<3 x [[TYPE]]>
-// DXNATIVE_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.dx.frac.v3f16(<3 x [[TYPE]]>
-// DXNO_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.dx.frac.v3f32(<3 x [[TYPE]]>
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1>
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> [[X:%.*]], [[Y:%.*]]
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> [[DIV1_I:%.*]]
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x [[TYPE]]> [[DIV1_I_2:%.*]], %fneg.i
+// DXNATIVE_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.fabs.v3f16(<3 x [[TYPE]]> [[DIV1_I_3:%.*]])
+// DXNO_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.fabs.v3f32(<3 x [[TYPE]]> [[DIV1_I_3:%.*]])
+// DXNATIVE_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.dx.frac.v3f16(<3 x [[TYPE]]> %elt.abs.i)
+// DXNO_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.dx.frac.v3f32(<3 x [[TYPE]]> %elt.abs.i)
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> [[HLSL_FRAC_I:%.*]]
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1> [[CMP_I:%.*]], <3 x [[TYPE]]> [[HLSL_FRAC_I_2:%.*]], <3 x [[TYPE]]> %fneg2.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> %hlsl.select.i, [[Y_2:%.*]]
// DXCHECK: ret <3 x [[TYPE]]> %mul.i
-// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
+// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> [[X:%.*]], [[Y:%.*]]
// SPVCHECK: ret <3 x [[TYPE]]> %fmod.i
half3 test_fmod_half3(half3 p0, half3 p1) { return fmod(p0, p1); }
// CHECK-LABEL: test_fmod_half4
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x [[TYPE]]>
-// DXNATIVE_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.fabs.v4f16(<4 x [[TYPE]]>
-// DXNO_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.fabs.v4f32(<4 x [[TYPE]]>
-// DXNATIVE_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.dx.frac.v4f16(<4 x [[TYPE]]>
-// DXNO_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.dx.frac.v4f32(<4 x [[TYPE]]>
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1>
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> [[X:%.*]], [[Y:%.*]]
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> [[DIV1_I:%.*]]
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x [[TYPE]]> [[DIV1_I_2:%.*]], %fneg.i
+// DXNATIVE_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.fabs.v4f16(<4 x [[TYPE]]> [[DIV1_I_3:%.*]])
+// DXNO_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.fabs.v4f32(<4 x [[TYPE]]> [[DIV1_I_3:%.*]])
+// DXNATIVE_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.dx.frac.v4f16(<4 x [[TYPE]]> %elt.abs.i)
+// DXNO_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.dx.frac.v4f32(<4 x [[TYPE]]> %elt.abs.i)
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> [[HLSL_FRAC_I:%.*]]
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1> [[CMP_I:%.*]], <4 x [[TYPE]]> [[HLSL_FRAC_I_2:%.*]], <4 x [[TYPE]]> %fneg2.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> %hlsl.select.i, [[Y_2:%.*]]
// DXCHECK: ret <4 x [[TYPE]]> %mul.i
-// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
+// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> [[X:%.*]], [[Y:%.*]]
// SPVCHECK: ret <4 x [[TYPE]]> %fmod.i
half4 test_fmod_half4(half4 p0, half4 p1) { return fmod(p0, p1); }
// CHECK-LABEL: test_fmod_float
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn float
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn float
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge float
-// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float
-// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn float @llvm.dx.frac.f32(float
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn float
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn float [[X:%.*]], [[Y:%.*]]
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn float [[DIV1_I:%.*]]
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge float [[DIV1_I_2:%.*]], %fneg.i
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float [[DIV1_I_3:%.*]])
+// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn float @llvm.dx.frac.f32(float %elt.abs.i)
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn float [[HLSL_FRAC_I:%.*]]
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 [[CMP_I:%.*]], float [[HLSL_FRAC_I_2:%.*]], float %fneg2.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %hlsl.select.i, [[Y_2:%.*]]
// DXCHECK: ret float %mul.i
-// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn float
+// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn float [[X:%.*]], [[Y:%.*]]
// SPVCHECK: ret float %fmod.i
float test_fmod_float(float p0, float p1) { return fmod(p0, p1); }
// CHECK-LABEL: test_fmod_float2
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x float>
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x float>
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x float>
-// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.fabs.v2f32(<2 x float>
-// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.dx.frac.v2f32(<2 x float>
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <2 x float>
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1>
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x float>
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x float> [[X:%.*]], [[Y:%.*]]
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x float> [[DIV1_I:%.*]]
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x float> [[DIV1_I_2:%.*]], %fneg.i
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[DIV1_I_3:%.*]])
+// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.dx.frac.v2f32(<2 x float> %elt.abs.i)
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <2 x float> [[HLSL_FRAC_I:%.*]]
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1> [[CMP_I:%.*]], <2 x float> [[HLSL_FRAC_I_2:%.*]], <2 x float> %fneg2.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x float> %hlsl.select.i, [[Y_2:%.*]]
// DXCHECK: ret <2 x float> %mul.i
-// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x float>
+// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x float> [[X:%.*]], [[Y:%.*]]
// SPVCHECK: ret <2 x float> %fmod.i
float2 test_fmod_float2(float2 p0, float2 p1) { return fmod(p0, p1); }
// CHECK-LABEL: test_fmod_float3
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x float>
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x float>
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x float>
-// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.fabs.v3f32(<3 x float>
-// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.dx.frac.v3f32(<3 x float>
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <3 x float>
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1>
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x float>
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x float> [[X:%.*]], [[Y:%.*]]
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x float> [[DIV1_I:%.*]]
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x float> [[DIV1_I_2:%.*]], %fneg.i
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.fabs.v3f32(<3 x float> [[DIV1_I_3:%.*]])
+// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.dx.frac.v3f32(<3 x float> %elt.abs.i)
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <3 x float> [[HLSL_FRAC_I:%.*]]
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1> [[CMP_I:%.*]], <3 x float> [[HLSL_FRAC_I_2:%.*]], <3 x float> %fneg2.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x float> %hlsl.select.i, [[Y_2:%.*]]
// DXCHECK: ret <3 x float> %mul.i
-// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x float>
+// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x float> [[X:%.*]], [[Y:%.*]]
// SPVCHECK: ret <3 x float> %fmod.i
float3 test_fmod_float3(float3 p0, float3 p1) { return fmod(p0, p1); }
// CHECK-LABEL: test_fmod_float4
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x float>
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x float>
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x float>
-// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f32(<4 x float>
-// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.frac.v4f32(<4 x float>
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <4 x float>
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1>
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x float>
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x float> [[X:%.*]], [[Y:%.*]]
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x float> [[DIV1_I:%.*]]
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x float> [[DIV1_I_2:%.*]], %fneg.i
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f32(<4 x float> [[DIV1_I_3:%.*]])
+// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.frac.v4f32(<4 x float> %elt.abs.i)
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <4 x float> [[HLSL_FRAC_I:%.*]]
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1> [[CMP_I:%.*]], <4 x float> [[HLSL_FRAC_I_2:%.*]], <4 x float> %fneg2.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x float> %hlsl.select.i, [[Y_2:%.*]]
// DXCHECK: ret <4 x float> %mul.i
-// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x float>
+// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x float> [[X:%.*]], [[Y:%.*]]
// SPVCHECK: ret <4 x float> %fmod.i
float4 test_fmod_float4(float4 p0, float4 p1) { return fmod(p0, p1); }
>From 93d2c742d5a59b86cb38acbace81e09730573947 Mon Sep 17 00:00:00 2001
From: kmpeng <kaitlinpeng at microsoft.com>
Date: Mon, 10 Mar 2025 13:53:10 -0700
Subject: [PATCH 10/11] updated fmod.hlsl test cases following feedback, move
fmod hlsl_detail.h changes to hlsl_intrinsic_helpers.h
---
clang/lib/Headers/hlsl/hlsl_detail.h | 25 ---
.../lib/Headers/hlsl/hlsl_intrinsic_helpers.h | 26 +++
clang/test/CodeGenHLSL/builtins/fmod.hlsl | 196 +++++++++---------
3 files changed, 124 insertions(+), 123 deletions(-)
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h b/clang/lib/Headers/hlsl/hlsl_detail.h
index 38012fd9ea14d..c691d85283de4 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -45,31 +45,6 @@ template <typename T> struct is_arithmetic {
static const bool Value = __is_arithmetic(T);
};
-template <typename T>
-constexpr enable_if_t<is_same<float, T>::value || is_same<half, T>::value, T>
-fmod_impl(T X, T Y) {
-#if !defined(__DIRECTX__)
- return __builtin_elementwise_fmod(X, Y);
-#else
- T div = X / Y;
- bool ge = div >= -div;
- T frc = frac(abs(div));
- return select<T>(ge, frc, -frc) * Y;
-#endif
-}
-
-template <typename T, int N>
-constexpr vector<T, N> fmod_vec_impl(vector<T, N> X, vector<T, N> Y) {
-#if !defined(__DIRECTX__)
- return __builtin_elementwise_fmod(X, Y);
-#else
- vector<T, N> div = X / Y;
- vector<bool, N> ge = div >= -div;
- vector<T, N> frc = frac(abs(div));
- return select<T>(ge, frc, -frc) * Y;
-#endif
-}
-
} // namespace __detail
} // namespace hlsl
#endif //_HLSL_HLSL_DETAILS_H_
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
index 6783e23f6346d..de1eefc490bb4 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
@@ -65,6 +65,32 @@ constexpr vector<T, L> reflect_vec_impl(vector<T, L> I, vector<T, L> N) {
return I - 2 * N * dot(I, N);
#endif
}
+
+template <typename T>
+constexpr enable_if_t<is_same<float, T>::value || is_same<half, T>::value, T>
+fmod_impl(T X, T Y) {
+#if !defined(__DIRECTX__)
+ return __builtin_elementwise_fmod(X, Y);
+#else
+ T div = X / Y;
+ bool ge = div >= -div;
+ T frc = frac(abs(div));
+ return select<T>(ge, frc, -frc) * Y;
+#endif
+}
+
+template <typename T, int N>
+constexpr vector<T, N> fmod_vec_impl(vector<T, N> X, vector<T, N> Y) {
+#if !defined(__DIRECTX__)
+ return __builtin_elementwise_fmod(X, Y);
+#else
+ vector<T, N> div = X / Y;
+ vector<bool, N> ge = div >= -div;
+ vector<T, N> frc = frac(abs(div));
+ return select<T>(ge, frc, -frc) * Y;
+#endif
+}
+
} // namespace __detail
} // namespace hlsl
diff --git a/clang/test/CodeGenHLSL/builtins/fmod.hlsl b/clang/test/CodeGenHLSL/builtins/fmod.hlsl
index 9e128bc9329cf..f18a852000c57 100644
--- a/clang/test/CodeGenHLSL/builtins/fmod.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/fmod.hlsl
@@ -4,16 +4,16 @@
//
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
-// RUN: -emit-llvm -o - | FileCheck %s \
-// RUN: -DTYPE=half --check-prefixes=CHECK,DXCHECK,DXNATIVE_HALF
+// RUN: -emit-llvm -o - | FileCheck %s -DFNATTRS="noundef nofpclass(nan inf)" \
+// RUN: -DTYPE=half -DINT_TYPE=f16 --check-prefixes=DXCHECK
//
// ---------- No Native Half support test -----------
//
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm \
-// RUN: -o - | FileCheck %s \
-// RUN: -DTYPE=float --check-prefixes=CHECK,DXCHECK,DXNO_HALF
+// RUN: -o - | FileCheck %s -DFNATTRS="noundef nofpclass(nan inf)" \
+// RUN: -DTYPE=float -DINT_TYPE=f32 --check-prefixes=DXCHECK
// Spirv target:
@@ -23,7 +23,7 @@
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \
// RUN: -emit-llvm -o - | FileCheck %s \
-// RUN: -DTYPE=half --check-prefixes=CHECK,SPVCHECK
+// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTYPE=half
//
// ---------- No Native Half support test -----------
@@ -31,127 +31,127 @@
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: spirv-unknown-vulkan-compute %s -emit-llvm \
// RUN: -o - | FileCheck %s \
-// RUN: -DTYPE=float --check-prefixes=CHECK,SPVCHECK
+// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTYPE=float
-// CHECK-LABEL: test_fmod_half
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn [[TYPE]] [[X:%.*]], [[Y:%.*]]
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn [[TYPE]] [[DIV1_I:%.*]]
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge [[TYPE]] [[DIV1_I_2:%.*]], %fneg.i
-// DXNATIVE_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.fabs.f16([[TYPE]] [[DIV1_I_3:%.*]])
-// DXNO_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.fabs.f32([[TYPE]] [[DIV1_I_3:%.*]])
-// DXNATIVE_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.dx.frac.f16([[TYPE]] %elt.abs.i)
-// DXNO_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.dx.frac.f32([[TYPE]] %elt.abs.i)
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn [[TYPE]] [[HLSL_FRAC_I:%.*]]
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 [[CMP_I:%.*]], [[TYPE]] [[HLSL_FRAC_I_2:%.*]], [[TYPE]] %fneg2.i
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn [[TYPE]] %hlsl.select.i, [[Y_2:%.*]]
+// DXCHECK: define [[FNATTRS]] [[TYPE]] @
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn [[TYPE]] %4, %5
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn [[TYPE]] %7
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge [[TYPE]] %6, %fneg.i
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.fabs.[[INT_TYPE]]([[TYPE]] %8)
+// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.dx.frac.[[INT_TYPE]]([[TYPE]] %elt.abs.i)
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn [[TYPE]] %11
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %loadedv.i, [[TYPE]] %10, [[TYPE]] %fneg2.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn [[TYPE]] %hlsl.select.i, %12
// DXCHECK: ret [[TYPE]] %mul.i
-// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn [[TYPE]] [[X:%.*]], [[Y:%.*]]
-// SPVCHECK: ret [[TYPE]] %fmod.i
+// CHECK: define [[FNATTRS]] [[TYPE]] @
+// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn [[TYPE]]
+// CHECK: ret [[TYPE]] %fmod.i
half test_fmod_half(half p0, half p1) { return fmod(p0, p1); }
-// CHECK-LABEL: test_fmod_half2
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> [[X:%.*]], [[Y:%.*]]
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> [[DIV1_I:%.*]]
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x [[TYPE]]> [[DIV1_I_2:%.*]], %fneg.i
-// DXNATIVE_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.fabs.v2f16(<2 x [[TYPE]]> [[DIV1_I_3:%.*]])
-// DXNO_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.fabs.v2f32(<2 x [[TYPE]]> [[DIV1_I_3:%.*]])
-// DXNATIVE_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.dx.frac.v2f16(<2 x [[TYPE]]> %elt.abs.i)
-// DXNO_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.dx.frac.v2f32(<2 x [[TYPE]]> %elt.abs.i)
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> [[HLSL_FRAC_I:%.*]]
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1> [[CMP_I:%.*]], <2 x [[TYPE]]> [[HLSL_FRAC_I_2:%.*]], <2 x [[TYPE]]> %fneg2.i
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> %hlsl.select.i, [[Y_2:%.*]]
+// DXCHECK: define [[FNATTRS]] <2 x [[TYPE]]> @
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> %4, %5
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> %7
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x [[TYPE]]> %6, %fneg.i
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.fabs.v2[[INT_TYPE]](<2 x [[TYPE]]> %9)
+// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.dx.frac.v2[[INT_TYPE]](<2 x [[TYPE]]> %elt.abs.i)
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> %12
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1> %extractvec.i, <2 x [[TYPE]]> %11, <2 x [[TYPE]]> %fneg2.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> %hlsl.select.i, %13
// DXCHECK: ret <2 x [[TYPE]]> %mul.i
-// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> [[X:%.*]], [[Y:%.*]]
-// SPVCHECK: ret <2 x [[TYPE]]> %fmod.i
+// CHECK: define [[FNATTRS]] <2 x [[TYPE]]> @
+// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
+// CHECK: ret <2 x [[TYPE]]> %fmod.i
half2 test_fmod_half2(half2 p0, half2 p1) { return fmod(p0, p1); }
-// CHECK-LABEL: test_fmod_half3
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> [[X:%.*]], [[Y:%.*]]
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> [[DIV1_I:%.*]]
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x [[TYPE]]> [[DIV1_I_2:%.*]], %fneg.i
-// DXNATIVE_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.fabs.v3f16(<3 x [[TYPE]]> [[DIV1_I_3:%.*]])
-// DXNO_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.fabs.v3f32(<3 x [[TYPE]]> [[DIV1_I_3:%.*]])
-// DXNATIVE_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.dx.frac.v3f16(<3 x [[TYPE]]> %elt.abs.i)
-// DXNO_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.dx.frac.v3f32(<3 x [[TYPE]]> %elt.abs.i)
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> [[HLSL_FRAC_I:%.*]]
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1> [[CMP_I:%.*]], <3 x [[TYPE]]> [[HLSL_FRAC_I_2:%.*]], <3 x [[TYPE]]> %fneg2.i
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> %hlsl.select.i, [[Y_2:%.*]]
+// DXCHECK: define [[FNATTRS]] <3 x [[TYPE]]> @
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> %4, %5
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> %7
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x [[TYPE]]> %6, %fneg.i
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.fabs.v3[[INT_TYPE]](<3 x [[TYPE]]> %9)
+// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.dx.frac.v3[[INT_TYPE]](<3 x [[TYPE]]> %elt.abs.i)
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> %12
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1> %extractvec.i, <3 x [[TYPE]]> %11, <3 x [[TYPE]]> %fneg2.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> %hlsl.select.i, %13
// DXCHECK: ret <3 x [[TYPE]]> %mul.i
-// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> [[X:%.*]], [[Y:%.*]]
-// SPVCHECK: ret <3 x [[TYPE]]> %fmod.i
+// CHECK: define [[FNATTRS]] <3 x [[TYPE]]> @
+// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
+// CHECK: ret <3 x [[TYPE]]> %fmod.i
half3 test_fmod_half3(half3 p0, half3 p1) { return fmod(p0, p1); }
-// CHECK-LABEL: test_fmod_half4
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> [[X:%.*]], [[Y:%.*]]
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> [[DIV1_I:%.*]]
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x [[TYPE]]> [[DIV1_I_2:%.*]], %fneg.i
-// DXNATIVE_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.fabs.v4f16(<4 x [[TYPE]]> [[DIV1_I_3:%.*]])
-// DXNO_HALF: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.fabs.v4f32(<4 x [[TYPE]]> [[DIV1_I_3:%.*]])
-// DXNATIVE_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.dx.frac.v4f16(<4 x [[TYPE]]> %elt.abs.i)
-// DXNO_HALF: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.dx.frac.v4f32(<4 x [[TYPE]]> %elt.abs.i)
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> [[HLSL_FRAC_I:%.*]]
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1> [[CMP_I:%.*]], <4 x [[TYPE]]> [[HLSL_FRAC_I_2:%.*]], <4 x [[TYPE]]> %fneg2.i
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> %hlsl.select.i, [[Y_2:%.*]]
+// DXCHECK: define [[FNATTRS]] <4 x [[TYPE]]> @
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> %4, %5
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> %7
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x [[TYPE]]> %6, %fneg.i
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.fabs.v4[[INT_TYPE]](<4 x [[TYPE]]> %9)
+// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.dx.frac.v4[[INT_TYPE]](<4 x [[TYPE]]> %elt.abs.i)
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> %12
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1> %extractvec.i, <4 x [[TYPE]]> %11, <4 x [[TYPE]]> %fneg2.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> %hlsl.select.i, %13
// DXCHECK: ret <4 x [[TYPE]]> %mul.i
-// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> [[X:%.*]], [[Y:%.*]]
-// SPVCHECK: ret <4 x [[TYPE]]> %fmod.i
+// CHECK: define [[FNATTRS]] <4 x [[TYPE]]> @
+// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
+// CHECK: ret <4 x [[TYPE]]> %fmod.i
half4 test_fmod_half4(half4 p0, half4 p1) { return fmod(p0, p1); }
-// CHECK-LABEL: test_fmod_float
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn float [[X:%.*]], [[Y:%.*]]
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn float [[DIV1_I:%.*]]
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge float [[DIV1_I_2:%.*]], %fneg.i
-// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float [[DIV1_I_3:%.*]])
+// DXCHECK: define [[FNATTRS]] float @
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn float %4, %5
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn float %7
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge float %6, %fneg.i
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float %8)
// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn float @llvm.dx.frac.f32(float %elt.abs.i)
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn float [[HLSL_FRAC_I:%.*]]
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 [[CMP_I:%.*]], float [[HLSL_FRAC_I_2:%.*]], float %fneg2.i
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %hlsl.select.i, [[Y_2:%.*]]
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn float %11
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %loadedv.i, float %10, float %fneg2.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %hlsl.select.i, %12
// DXCHECK: ret float %mul.i
-// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn float [[X:%.*]], [[Y:%.*]]
-// SPVCHECK: ret float %fmod.i
+// CHECK: define [[FNATTRS]] float @
+// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn float
+// CHECK: ret float %fmod.i
float test_fmod_float(float p0, float p1) { return fmod(p0, p1); }
-// CHECK-LABEL: test_fmod_float2
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x float> [[X:%.*]], [[Y:%.*]]
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x float> [[DIV1_I:%.*]]
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x float> [[DIV1_I_2:%.*]], %fneg.i
-// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.fabs.v2f32(<2 x float> [[DIV1_I_3:%.*]])
+// DXCHECK: define [[FNATTRS]] <2 x float> @
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x float> %4, %5
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x float> %7
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x float> %6, %fneg.i
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.fabs.v2f32(<2 x float> %9)
// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.dx.frac.v2f32(<2 x float> %elt.abs.i)
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <2 x float> [[HLSL_FRAC_I:%.*]]
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1> [[CMP_I:%.*]], <2 x float> [[HLSL_FRAC_I_2:%.*]], <2 x float> %fneg2.i
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x float> %hlsl.select.i, [[Y_2:%.*]]
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <2 x float> %12
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1> %extractvec.i, <2 x float> %11, <2 x float> %fneg2.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x float> %hlsl.select.i, %13
// DXCHECK: ret <2 x float> %mul.i
-// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x float> [[X:%.*]], [[Y:%.*]]
-// SPVCHECK: ret <2 x float> %fmod.i
+// CHECK: define [[FNATTRS]] <2 x float> @
+// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x float>
+// CHECK: ret <2 x float> %fmod.i
float2 test_fmod_float2(float2 p0, float2 p1) { return fmod(p0, p1); }
-// CHECK-LABEL: test_fmod_float3
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x float> [[X:%.*]], [[Y:%.*]]
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x float> [[DIV1_I:%.*]]
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x float> [[DIV1_I_2:%.*]], %fneg.i
-// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.fabs.v3f32(<3 x float> [[DIV1_I_3:%.*]])
+// DXCHECK: define [[FNATTRS]] <3 x float> @
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x float> %4, %5
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x float> %7
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x float> %6, %fneg.i
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.fabs.v3f32(<3 x float> %9)
// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.dx.frac.v3f32(<3 x float> %elt.abs.i)
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <3 x float> [[HLSL_FRAC_I:%.*]]
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1> [[CMP_I:%.*]], <3 x float> [[HLSL_FRAC_I_2:%.*]], <3 x float> %fneg2.i
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x float> %hlsl.select.i, [[Y_2:%.*]]
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <3 x float> %12
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1> %extractvec.i, <3 x float> %11, <3 x float> %fneg2.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x float> %hlsl.select.i, %13
// DXCHECK: ret <3 x float> %mul.i
-// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x float> [[X:%.*]], [[Y:%.*]]
-// SPVCHECK: ret <3 x float> %fmod.i
+// CHECK: define [[FNATTRS]] <3 x float> @
+// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x float>
+// CHECK: ret <3 x float> %fmod.i
float3 test_fmod_float3(float3 p0, float3 p1) { return fmod(p0, p1); }
-// CHECK-LABEL: test_fmod_float4
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x float> [[X:%.*]], [[Y:%.*]]
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x float> [[DIV1_I:%.*]]
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x float> [[DIV1_I_2:%.*]], %fneg.i
-// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f32(<4 x float> [[DIV1_I_3:%.*]])
+// DXCHECK: define [[FNATTRS]] <4 x float> @
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x float> %4, %5
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x float> %7
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x float> %6, %fneg.i
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f32(<4 x float> %9)
// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.frac.v4f32(<4 x float> %elt.abs.i)
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <4 x float> [[HLSL_FRAC_I:%.*]]
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1> [[CMP_I:%.*]], <4 x float> [[HLSL_FRAC_I_2:%.*]], <4 x float> %fneg2.i
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x float> %hlsl.select.i, [[Y_2:%.*]]
+// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <4 x float> %12
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1> %extractvec.i, <4 x float> %11, <4 x float> %fneg2.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x float> %hlsl.select.i, %13
// DXCHECK: ret <4 x float> %mul.i
-// SPVCHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x float> [[X:%.*]], [[Y:%.*]]
-// SPVCHECK: ret <4 x float> %fmod.i
+// CHECK: define [[FNATTRS]] <4 x float> @
+// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x float>
+// CHECK: ret <4 x float> %fmod.i
float4 test_fmod_float4(float4 p0, float4 p1) { return fmod(p0, p1); }
>From 4b621591c8f34b091a95f620ed7397562d13f713 Mon Sep 17 00:00:00 2001
From: kmpeng <kaitlinpeng at microsoft.com>
Date: Tue, 11 Mar 2025 10:01:51 -0700
Subject: [PATCH 11/11] wild card out ambiguous registers, simplify fmod
algorithm
---
.../lib/Headers/hlsl/hlsl_intrinsic_helpers.h | 4 +-
clang/test/CodeGenHLSL/builtins/fmod.hlsl | 104 ++++++++----------
2 files changed, 50 insertions(+), 58 deletions(-)
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
index de1eefc490bb4..5ae8b7fe7e45c 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
@@ -73,7 +73,7 @@ fmod_impl(T X, T Y) {
return __builtin_elementwise_fmod(X, Y);
#else
T div = X / Y;
- bool ge = div >= -div;
+ bool ge = div >= 0;
T frc = frac(abs(div));
return select<T>(ge, frc, -frc) * Y;
#endif
@@ -85,7 +85,7 @@ constexpr vector<T, N> fmod_vec_impl(vector<T, N> X, vector<T, N> Y) {
return __builtin_elementwise_fmod(X, Y);
#else
vector<T, N> div = X / Y;
- vector<bool, N> ge = div >= -div;
+ vector<bool, N> ge = div >= 0;
vector<T, N> frc = frac(abs(div));
return select<T>(ge, frc, -frc) * Y;
#endif
diff --git a/clang/test/CodeGenHLSL/builtins/fmod.hlsl b/clang/test/CodeGenHLSL/builtins/fmod.hlsl
index f18a852000c57..7ecc5854b3988 100644
--- a/clang/test/CodeGenHLSL/builtins/fmod.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/fmod.hlsl
@@ -36,14 +36,13 @@
// DXCHECK: define [[FNATTRS]] [[TYPE]] @
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn [[TYPE]] %4, %5
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn [[TYPE]] %7
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge [[TYPE]] %6, %fneg.i
-// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.fabs.[[INT_TYPE]]([[TYPE]] %8)
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn [[TYPE]] %{{.*}}, %{{.*}}
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge [[TYPE]] %{{.*}}, 0
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.fabs.[[INT_TYPE]]([[TYPE]] %{{.*}})
// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.dx.frac.[[INT_TYPE]]([[TYPE]] %elt.abs.i)
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn [[TYPE]] %11
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %loadedv.i, [[TYPE]] %10, [[TYPE]] %fneg2.i
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn [[TYPE]] %hlsl.select.i, %12
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn [[TYPE]] %{{.*}}
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, [[TYPE]] %{{.*}}, [[TYPE]] %fneg.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn [[TYPE]] %hlsl.select.i, %{{.*}}
// DXCHECK: ret [[TYPE]] %mul.i
// CHECK: define [[FNATTRS]] [[TYPE]] @
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn [[TYPE]]
@@ -51,14 +50,13 @@
half test_fmod_half(half p0, half p1) { return fmod(p0, p1); }
// DXCHECK: define [[FNATTRS]] <2 x [[TYPE]]> @
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> %4, %5
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> %7
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x [[TYPE]]> %6, %fneg.i
-// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.fabs.v2[[INT_TYPE]](<2 x [[TYPE]]> %9)
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> %{{.*}}, %{{.*}}
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x [[TYPE]]> %{{.*}}, zeroinitializer
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.fabs.v2[[INT_TYPE]](<2 x [[TYPE]]> %{{.*}})
// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.dx.frac.v2[[INT_TYPE]](<2 x [[TYPE]]> %elt.abs.i)
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> %12
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1> %extractvec.i, <2 x [[TYPE]]> %11, <2 x [[TYPE]]> %fneg2.i
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> %hlsl.select.i, %13
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> %{{.*}}
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1> %{{.*}}, <2 x [[TYPE]]> %{{.*}}, <2 x [[TYPE]]> %fneg.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> %hlsl.select.i, %{{.*}}
// DXCHECK: ret <2 x [[TYPE]]> %mul.i
// CHECK: define [[FNATTRS]] <2 x [[TYPE]]> @
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
@@ -66,14 +64,13 @@ half test_fmod_half(half p0, half p1) { return fmod(p0, p1); }
half2 test_fmod_half2(half2 p0, half2 p1) { return fmod(p0, p1); }
// DXCHECK: define [[FNATTRS]] <3 x [[TYPE]]> @
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> %4, %5
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> %7
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x [[TYPE]]> %6, %fneg.i
-// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.fabs.v3[[INT_TYPE]](<3 x [[TYPE]]> %9)
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> %{{.*}}, %{{.*}}
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x [[TYPE]]> %{{.*}}, zeroinitializer
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.fabs.v3[[INT_TYPE]](<3 x [[TYPE]]> %{{.*}})
// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.dx.frac.v3[[INT_TYPE]](<3 x [[TYPE]]> %elt.abs.i)
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> %12
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1> %extractvec.i, <3 x [[TYPE]]> %11, <3 x [[TYPE]]> %fneg2.i
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> %hlsl.select.i, %13
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> %{{.*}}
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1> %{{.*}}, <3 x [[TYPE]]> %{{.*}}, <3 x [[TYPE]]> %fneg.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> %hlsl.select.i, %{{.*}}
// DXCHECK: ret <3 x [[TYPE]]> %mul.i
// CHECK: define [[FNATTRS]] <3 x [[TYPE]]> @
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
@@ -81,14 +78,13 @@ half2 test_fmod_half2(half2 p0, half2 p1) { return fmod(p0, p1); }
half3 test_fmod_half3(half3 p0, half3 p1) { return fmod(p0, p1); }
// DXCHECK: define [[FNATTRS]] <4 x [[TYPE]]> @
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> %4, %5
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> %7
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x [[TYPE]]> %6, %fneg.i
-// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.fabs.v4[[INT_TYPE]](<4 x [[TYPE]]> %9)
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> %{{.*}}, %{{.*}}
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x [[TYPE]]> %{{.*}}, zeroinitializer
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.fabs.v4[[INT_TYPE]](<4 x [[TYPE]]> %{{.*}})
// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.dx.frac.v4[[INT_TYPE]](<4 x [[TYPE]]> %elt.abs.i)
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> %12
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1> %extractvec.i, <4 x [[TYPE]]> %11, <4 x [[TYPE]]> %fneg2.i
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> %hlsl.select.i, %13
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> %{{.*}}
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1> %{{.*}}, <4 x [[TYPE]]> %{{.*}}, <4 x [[TYPE]]> %fneg.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> %hlsl.select.i, %{{.*}}
// DXCHECK: ret <4 x [[TYPE]]> %mul.i
// CHECK: define [[FNATTRS]] <4 x [[TYPE]]> @
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
@@ -96,14 +92,13 @@ half3 test_fmod_half3(half3 p0, half3 p1) { return fmod(p0, p1); }
half4 test_fmod_half4(half4 p0, half4 p1) { return fmod(p0, p1); }
// DXCHECK: define [[FNATTRS]] float @
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn float %4, %5
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn float %7
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge float %6, %fneg.i
-// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float %8)
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn float %{{.*}}, %{{.*}}
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge float %{{.*}}, 0.000000e+00
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float %{{.*}})
// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn float @llvm.dx.frac.f32(float %elt.abs.i)
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn float %11
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %loadedv.i, float %10, float %fneg2.i
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %hlsl.select.i, %12
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn float %{{.*}}
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float %{{.*}}, float %fneg.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %hlsl.select.i, %{{.*}}
// DXCHECK: ret float %mul.i
// CHECK: define [[FNATTRS]] float @
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn float
@@ -111,14 +106,13 @@ half4 test_fmod_half4(half4 p0, half4 p1) { return fmod(p0, p1); }
float test_fmod_float(float p0, float p1) { return fmod(p0, p1); }
// DXCHECK: define [[FNATTRS]] <2 x float> @
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x float> %4, %5
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x float> %7
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x float> %6, %fneg.i
-// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.fabs.v2f32(<2 x float> %9)
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x float> %{{.*}}, %{{.*}}
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x float> %{{.*}}, zeroinitializer
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.fabs.v2f32(<2 x float> %{{.*}})
// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.dx.frac.v2f32(<2 x float> %elt.abs.i)
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <2 x float> %12
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1> %extractvec.i, <2 x float> %11, <2 x float> %fneg2.i
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x float> %hlsl.select.i, %13
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x float> %{{.*}}
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %fneg.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x float> %hlsl.select.i, %{{.*}}
// DXCHECK: ret <2 x float> %mul.i
// CHECK: define [[FNATTRS]] <2 x float> @
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x float>
@@ -126,14 +120,13 @@ float test_fmod_float(float p0, float p1) { return fmod(p0, p1); }
float2 test_fmod_float2(float2 p0, float2 p1) { return fmod(p0, p1); }
// DXCHECK: define [[FNATTRS]] <3 x float> @
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x float> %4, %5
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x float> %7
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x float> %6, %fneg.i
-// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.fabs.v3f32(<3 x float> %9)
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x float> %{{.*}}, %{{.*}}
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x float> %{{.*}}, zeroinitializer
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.fabs.v3f32(<3 x float> %{{.*}})
// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.dx.frac.v3f32(<3 x float> %elt.abs.i)
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <3 x float> %12
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1> %extractvec.i, <3 x float> %11, <3 x float> %fneg2.i
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x float> %hlsl.select.i, %13
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x float> %{{.*}}
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1> %{{.*}}, <3 x float> %{{.*}}, <3 x float> %fneg.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x float> %hlsl.select.i, %{{.*}}
// DXCHECK: ret <3 x float> %mul.i
// CHECK: define [[FNATTRS]] <3 x float> @
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x float>
@@ -141,14 +134,13 @@ float2 test_fmod_float2(float2 p0, float2 p1) { return fmod(p0, p1); }
float3 test_fmod_float3(float3 p0, float3 p1) { return fmod(p0, p1); }
// DXCHECK: define [[FNATTRS]] <4 x float> @
-// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x float> %4, %5
-// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x float> %7
-// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x float> %6, %fneg.i
-// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f32(<4 x float> %9)
+// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x float> %{{.*}}, %{{.*}}
+// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x float> %{{.*}}, zeroinitializer
+// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f32(<4 x float> %{{.*}})
// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.frac.v4f32(<4 x float> %elt.abs.i)
-// DXCHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <4 x float> %12
-// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1> %extractvec.i, <4 x float> %11, <4 x float> %fneg2.i
-// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x float> %hlsl.select.i, %13
+// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x float> %{{.*}}
+// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %fneg.i
+// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x float> %hlsl.select.i, %{{.*}}
// DXCHECK: ret <4 x float> %mul.i
// CHECK: define [[FNATTRS]] <4 x float> @
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x float>
More information about the cfe-commits
mailing list