https://github.com/kmpeng created https://github.com/llvm/llvm-project/pull/130320
Replaced the current `fmod` definition with a templatized version, implemented `fmod` algorithm for DirectX targets that matches the DXC implementation, added corresponding tests in `clang/test/CodeGenHLSL/builtins/fmod.hlsl` and `clang/test/SemaHLSL/BuiltIns/fmod-errors.hlsl`. >From bdb66b5a68090e304647ddbbeb403ac408fcea65 Mon Sep 17 00:00:00 2001 From: kmpeng <hi.kait...@gmail.com> Date: Tue, 25 Feb 2025 14:50:09 -0800 Subject: [PATCH 1/7] 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 39254a3cc3a0a..e7e910e30957e 100644 --- a/clang/lib/Headers/hlsl/hlsl_detail.h +++ b/clang/lib/Headers/hlsl/hlsl_detail.h @@ -97,6 +97,20 @@ constexpr vector<T, L> reflect_vec_impl(vector<T, L> I, vector<T, L> N) { #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) { +#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 fe73beac17b99b0f7836ffdb7050e04595d96dba Mon Sep 17 00:00:00 2001 From: kmpeng <hi.kait...@gmail.com> Date: Wed, 26 Feb 2025 15:57:59 -0800 Subject: [PATCH 2/7] 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 e7e910e30957e..bc2dd463e0404 100644 --- a/clang/lib/Headers/hlsl/hlsl_detail.h +++ b/clang/lib/Headers/hlsl/hlsl_detail.h @@ -97,6 +97,12 @@ constexpr vector<T, L> reflect_vec_impl(vector<T, L> I, vector<T, L> 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) { + 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) { @@ -104,10 +110,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 9edf0623d7631d2d82826d9c45ae812ceea5fbbf Mon Sep 17 00:00:00 2001 From: kmpeng <hi.kait...@gmail.com> Date: Thu, 27 Feb 2025 13:40:52 -0800 Subject: [PATCH 3/7] 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 bc2dd463e0404..ab72301070d48 100644 --- a/clang/lib/Headers/hlsl/hlsl_detail.h +++ b/clang/lib/Headers/hlsl/hlsl_detail.h @@ -100,20 +100,25 @@ constexpr vector<T, L> reflect_vec_impl(vector<T, L> I, vector<T, L> N) { 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 e3e0495ff6076dbb31e4be6a524b9786e9699d23 Mon Sep 17 00:00:00 2001 From: kmpeng <hi.kait...@gmail.com> Date: Thu, 27 Feb 2025 16:30:12 -0800 Subject: [PATCH 4/7] 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 2e1ccbaec5b139866ab1a0202e086d9b03a67210 Mon Sep 17 00:00:00 2001 From: kmpeng <kaitlinp...@microsoft.com> Date: Wed, 5 Mar 2025 15:21:06 -0800 Subject: [PATCH 5/7] 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 7573f6e024167..cd59fef82d9f9 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 ab72301070d48..470cc4db24cd2 100644 --- a/clang/lib/Headers/hlsl/hlsl_detail.h +++ b/clang/lib/Headers/hlsl/hlsl_detail.h @@ -100,25 +100,25 @@ constexpr vector<T, L> reflect_vec_impl(vector<T, L> I, vector<T, L> N) { 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 fe9441080433d..3393c955e9a4b 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 2f8936e7cc0851600a9c6d9af8355060226f5c43 Mon Sep 17 00:00:00 2001 From: kmpeng <kaitlinp...@microsoft.com> Date: Wed, 5 Mar 2025 15:45:01 -0800 Subject: [PATCH 6/7] 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@-1 {{no matching function for call to 'fmod'}} + // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 1 was provided}} + // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 1 was provided}} + // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 1 was provided}} + // expected-note@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@-1 {{no matching function for call to 'fmod'}} + // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 3 were provided}} + // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 3 were provided}} + // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 3 were provided}} + // expected-note@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@-1 {{call to 'fmod' is ambiguous}} + // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}} + // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}} +} + +float test_int_inputs(int p0, int p1) { + return fmod(p0, p1); + // expected-error@-1 {{call to 'fmod' is ambiguous}} + // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}} + // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}} +} >From 00b3e767b0fe222f6b0bfa9fe49633df2984a641 Mon Sep 17 00:00:00 2001 From: kmpeng <kaitlinp...@microsoft.com> Date: Thu, 6 Mar 2025 14:42:13 -0800 Subject: [PATCH 7/7] 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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits