From 73ec3fa063970bf9b0c8c9a6ef22666db16fb80a Mon Sep 17 00:00:00 2001 From: kmpeng 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 80c4900121dfb..025c02bb24762 100644 --- a/clang/lib/Headers/hlsl/hlsl_detail.h +++ b/clang/lib/Headers/hlsl/hlsl_detail.h @@ -45,6 +45,20 @@ template struct is_arithmetic { static const bool Value = __is_arithmetic(T); }; +template +constexpr enable_if_t::value || is_same::value, T> +fmod_vec_impl(vector X, vector Y) { +#if !defined(__DirectX__) + return __builtin_elementwise_fmod(X, Y); +#else + vector div = X / Y; + vector result = __builtin_hlsl_elementwise_frac(__builtin_elementwise_abs(div)) * Y; + vector condition = (div >= -div); + vector realResult = __builtin_hlsl_select(condition, result, -result); + return realResult; +#endif +} + template using HLSL_FIXED_VECTOR = vector<__detail::enable_if_t<(N > 1 && N <= 4), T>, N>; From f7cee38112414e5089661374d01cc662311c87a8 Mon Sep 17 00:00:00 2001 From: kmpeng 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 025c02bb24762..9cf874fb10e18 100644 --- a/clang/lib/Headers/hlsl/hlsl_detail.h +++ b/clang/lib/Headers/hlsl/hlsl_detail.h @@ -45,6 +45,12 @@ template struct is_arithmetic { static const bool Value = __is_arithmetic(T); }; +template +constexpr enable_if_t::value || is_same::value, T> +fmod_impl(T X, T Y) { + return __builtin_elementwise_fmod(X, Y); +} + template constexpr enable_if_t::value || is_same::value, T> fmod_vec_impl(vector X, vector Y) { @@ -52,10 +58,10 @@ fmod_vec_impl(vector X, vector Y) { return __builtin_elementwise_fmod(X, Y); #else vector div = X / Y; - vector result = __builtin_hlsl_elementwise_frac(__builtin_elementwise_abs(div)) * Y; - vector condition = (div >= -div); - vector realResult = __builtin_hlsl_select(condition, result, -result); - return realResult; + vector ge = div >= -div; + vector frc = __builtin_hlsl_elementwise_frac(__builtin_elementwise_abs(div)); + vector 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 67cdd8c2977e1e763690a9711995b270f96f7201 Mon Sep 17 00:00:00 2001 From: kmpeng 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 9cf874fb10e18..91a9b0fdfb1d7 100644 --- a/clang/lib/Headers/hlsl/hlsl_detail.h +++ b/clang/lib/Headers/hlsl/hlsl_detail.h @@ -48,20 +48,25 @@ template struct is_arithmetic { template constexpr enable_if_t::value || is_same::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 -constexpr enable_if_t::value || is_same::value, T> -fmod_vec_impl(vector X, vector Y) { +constexpr vector fmod_vec_impl(vector X, vector Y) { #if !defined(__DirectX__) return __builtin_elementwise_fmod(X, Y); #else vector div = X / Y; vector ge = div >= -div; vector frc = __builtin_hlsl_elementwise_frac(__builtin_elementwise_abs(div)); - vector 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 c1b03d720b7c03431e94728e02ab452d54d945aa Mon Sep 17 00:00:00 2001 From: kmpeng 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 8b1b2a4b09e8f764623307871da772ee307b0a0c Mon Sep 17 00:00:00 2001 From: kmpeng 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 91a9b0fdfb1d7..089cb0cff2266 100644 --- a/clang/lib/Headers/hlsl/hlsl_detail.h +++ b/clang/lib/Headers/hlsl/hlsl_detail.h @@ -48,25 +48,25 @@ template struct is_arithmetic { template constexpr enable_if_t::value || is_same::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(ge, frc, -frc) * Y; #endif } template constexpr vector fmod_vec_impl(vector X, vector Y) { -#if !defined(__DirectX__) +#if !defined(__DIRECTX__) return __builtin_elementwise_fmod(X, Y); #else vector div = X / Y; vector ge = div >= -div; - vector frc = __builtin_hlsl_elementwise_frac(__builtin_elementwise_abs(div)); - return __builtin_hlsl_select(ge, frc, -frc) * Y; + vector frc = frac(abs(div)); + return select(ge, frc, -frc) * Y; #endif } diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 47a7066b2b3e1..5f5201ff64e39 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -117,6 +117,38 @@ const inline float distance(__detail::HLSL_FIXED_VECTOR X, 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 +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +const inline vector fmod(vector X, vector Y) { + return __detail::fmod_vec_impl(X, Y); +} + +template +const inline vector fmod(vector X, vector 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 5a131aecbc1bad2a0a4f8cb27ac37f9542262be6 Mon Sep 17 00:00:00 2001 From: kmpeng 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@-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 1d7143741fc42a51838b0aa49c0a076168245091 Mon Sep 17 00:00:00 2001 From: kmpeng 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 fc0d9f0bced11cccb3517c811d628bc1f0cd3317 Mon Sep 17 00:00:00 2001 From: kmpeng 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 089cb0cff2266..ca517239a2b4e 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::value || is_same::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 constexpr vector fmod_vec_impl(vector X, vector Y) { #if !defined(__DIRECTX__) return __builtin_elementwise_fmod(X, Y); -#else +#else vector div = X / Y; vector ge = div >= -div; - vector frc = frac(abs(div)); + vector frc = frac(abs(div)); return select(ge, frc, -frc) * Y; #endif } diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 5f5201ff64e39..5459cbeb34fd0 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -130,13 +130,9 @@ const inline float distance(__detail::HLSL_FIXED_VECTOR X, /// 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 _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 567d8bb90c59cc3f6f42489fb93c2fddd0cbfd62 Mon Sep 17 00:00:00 2001 From: kmpeng 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 f31cae5ab8e34b9f2483eaf783a425d11eaad422 Mon Sep 17 00:00:00 2001 From: kmpeng 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 ca517239a2b4e..80c4900121dfb 100644 --- a/clang/lib/Headers/hlsl/hlsl_detail.h +++ b/clang/lib/Headers/hlsl/hlsl_detail.h @@ -45,31 +45,6 @@ template struct is_arithmetic { static const bool Value = __is_arithmetic(T); }; -template -constexpr enable_if_t::value || is_same::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(ge, frc, -frc) * Y; -#endif -} - -template -constexpr vector fmod_vec_impl(vector X, vector Y) { -#if !defined(__DIRECTX__) - return __builtin_elementwise_fmod(X, Y); -#else - vector div = X / Y; - vector ge = div >= -div; - vector frc = frac(abs(div)); - return select(ge, frc, -frc) * Y; -#endif -} - template using HLSL_FIXED_VECTOR = vector<__detail::enable_if_t<(N > 1 && N <= 4), T>, N>; diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h index 87b52792447f6..22a89bf3f5b14 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h @@ -57,6 +57,32 @@ constexpr vector reflect_vec_impl(vector I, vector N) { return I - 2 * N * dot(I, N); #endif } + +template +constexpr enable_if_t::value || is_same::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(ge, frc, -frc) * Y; +#endif +} + +template +constexpr vector fmod_vec_impl(vector X, vector Y) { +#if !defined(__DIRECTX__) + return __builtin_elementwise_fmod(X, Y); +#else + vector div = X / Y; + vector ge = div >= -div; + vector frc = frac(abs(div)); + return select(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 8aeb5bd9895f5d14118a5e783808cda783142bd2 Mon Sep 17 00:00:00 2001 From: kmpeng 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 22a89bf3f5b14..5f7c047dbf340 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h @@ -65,7 +65,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(ge, frc, -frc) * Y; #endif @@ -77,7 +77,7 @@ constexpr vector fmod_vec_impl(vector X, vector Y) { return __builtin_elementwise_fmod(X, Y); #else vector div = X / Y; - vector ge = div >= -div; + vector ge = div >= 0; vector frc = frac(abs(div)); return select(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>