Skip to content

Commit d529f8d

Browse files
kmpengfrederik-h
authored andcommitted
Implement the fmod intrinsic (llvm#130320)
Replaced the current `fmod` definition with a templatized version, implemented `fmod` algorithm for DirectX targets that matches the DXC implementation, added corresponding tests in `clang/test/CodeGenHLSL/builtins/fmod.hlsl` and `clang/test/SemaHLSL/BuiltIns/fmod-errors.hlsl`. Closes llvm#99118.
1 parent d06a9a4 commit d529f8d

File tree

5 files changed

+182
-57
lines changed

5 files changed

+182
-57
lines changed

clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,40 +1237,6 @@ float3 floor(float3);
12371237
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_floor)
12381238
float4 floor(float4);
12391239

1240-
//===----------------------------------------------------------------------===//
1241-
// fmod builtins
1242-
//===----------------------------------------------------------------------===//
1243-
1244-
/// \fn T fmod(T x, T y)
1245-
/// \brief Returns the linear interpolation of x to y.
1246-
/// \param x [in] The dividend.
1247-
/// \param y [in] The divisor.
1248-
///
1249-
/// Return the floating-point remainder of the x parameter divided by the y
1250-
/// parameter.
1251-
1252-
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
1253-
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_fmod)
1254-
half fmod(half, half);
1255-
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
1256-
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_fmod)
1257-
half2 fmod(half2, half2);
1258-
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
1259-
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_fmod)
1260-
half3 fmod(half3, half3);
1261-
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
1262-
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_fmod)
1263-
half4 fmod(half4, half4);
1264-
1265-
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_fmod)
1266-
float fmod(float, float);
1267-
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_fmod)
1268-
float2 fmod(float2, float2);
1269-
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_fmod)
1270-
float3 fmod(float3, float3);
1271-
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_fmod)
1272-
float4 fmod(float4, float4);
1273-
12741240
//===----------------------------------------------------------------------===//
12751241
// frac builtins
12761242
//===----------------------------------------------------------------------===//

clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,32 @@ constexpr vector<T, L> reflect_vec_impl(vector<T, L> I, vector<T, L> N) {
5757
return I - 2 * N * dot(I, N);
5858
#endif
5959
}
60+
61+
template <typename T>
62+
constexpr enable_if_t<is_same<float, T>::value || is_same<half, T>::value, T>
63+
fmod_impl(T X, T Y) {
64+
#if !defined(__DIRECTX__)
65+
return __builtin_elementwise_fmod(X, Y);
66+
#else
67+
T div = X / Y;
68+
bool ge = div >= 0;
69+
T frc = frac(abs(div));
70+
return select<T>(ge, frc, -frc) * Y;
71+
#endif
72+
}
73+
74+
template <typename T, int N>
75+
constexpr vector<T, N> fmod_vec_impl(vector<T, N> X, vector<T, N> Y) {
76+
#if !defined(__DIRECTX__)
77+
return __builtin_elementwise_fmod(X, Y);
78+
#else
79+
vector<T, N> div = X / Y;
80+
vector<bool, N> ge = div >= 0;
81+
vector<T, N> frc = frac(abs(div));
82+
return select<T>(ge, frc, -frc) * Y;
83+
#endif
84+
}
85+
6086
} // namespace __detail
6187
} // namespace hlsl
6288

clang/lib/Headers/hlsl/hlsl_intrinsics.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,34 @@ const inline float distance(__detail::HLSL_FIXED_VECTOR<float, N> X,
117117
return __detail::distance_vec_impl(X, Y);
118118
}
119119

120+
//===----------------------------------------------------------------------===//
121+
// fmod builtins
122+
//===----------------------------------------------------------------------===//
123+
124+
/// \fn T fmod(T x, T y)
125+
/// \brief Returns the linear interpolation of x to y.
126+
/// \param x [in] The dividend.
127+
/// \param y [in] The divisor.
128+
///
129+
/// Return the floating-point remainder of the x parameter divided by the y
130+
/// parameter.
131+
132+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
133+
const inline half fmod(half X, half Y) { return __detail::fmod_impl(X, Y); }
134+
135+
const inline float fmod(float X, float Y) { return __detail::fmod_impl(X, Y); }
136+
137+
template <int N>
138+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
139+
const inline vector<half, N> fmod(vector<half, N> X, vector<half, N> Y) {
140+
return __detail::fmod_vec_impl(X, Y);
141+
}
142+
143+
template <int N>
144+
const inline vector<float, N> fmod(vector<float, N> X, vector<float, N> Y) {
145+
return __detail::fmod_vec_impl(X, Y);
146+
}
147+
120148
//===----------------------------------------------------------------------===//
121149
// length builtins
122150
//===----------------------------------------------------------------------===//

clang/test/CodeGenHLSL/builtins/fmod.hlsl

Lines changed: 95 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44
//
55
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
66
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
7-
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
8-
// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTYPE=half
7+
// RUN: -emit-llvm -o - | FileCheck %s -DFNATTRS="noundef nofpclass(nan inf)" \
8+
// RUN: -DTYPE=half -DINT_TYPE=f16 --check-prefixes=DXCHECK
99

1010
//
1111
// ---------- No Native Half support test -----------
1212
//
1313
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
14-
// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
15-
// RUN: -o - | FileCheck %s \
16-
// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTYPE=float
14+
// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm \
15+
// RUN: -o - | FileCheck %s -DFNATTRS="noundef nofpclass(nan inf)" \
16+
// RUN: -DTYPE=float -DINT_TYPE=f32 --check-prefixes=DXCHECK
1717

1818

1919
// Spirv target:
@@ -22,56 +22,128 @@
2222
//
2323
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
2424
// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \
25-
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
25+
// RUN: -emit-llvm -o - | FileCheck %s \
2626
// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTYPE=half
2727

2828
//
2929
// ---------- No Native Half support test -----------
3030
//
3131
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
32-
// RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \
32+
// RUN: spirv-unknown-vulkan-compute %s -emit-llvm \
3333
// RUN: -o - | FileCheck %s \
3434
// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTYPE=float
3535

3636

3737

38+
// DXCHECK: define [[FNATTRS]] [[TYPE]] @
39+
// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn [[TYPE]] %{{.*}}, %{{.*}}
40+
// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge [[TYPE]] %{{.*}}, 0
41+
// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.fabs.[[INT_TYPE]]([[TYPE]] %{{.*}})
42+
// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.dx.frac.[[INT_TYPE]]([[TYPE]] %elt.abs.i)
43+
// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn [[TYPE]] %{{.*}}
44+
// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, [[TYPE]] %{{.*}}, [[TYPE]] %fneg.i
45+
// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn [[TYPE]] %hlsl.select.i, %{{.*}}
46+
// DXCHECK: ret [[TYPE]] %mul.i
3847
// CHECK: define [[FNATTRS]] [[TYPE]] @
39-
// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn [[TYPE]]
40-
// CHECK: ret [[TYPE]] %fmod
48+
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn [[TYPE]]
49+
// CHECK: ret [[TYPE]] %fmod.i
4150
half test_fmod_half(half p0, half p1) { return fmod(p0, p1); }
4251

52+
// DXCHECK: define [[FNATTRS]] <2 x [[TYPE]]> @
53+
// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> %{{.*}}, %{{.*}}
54+
// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x [[TYPE]]> %{{.*}}, zeroinitializer
55+
// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.fabs.v2[[INT_TYPE]](<2 x [[TYPE]]> %{{.*}})
56+
// 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)
57+
// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> %{{.*}}
58+
// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1> %{{.*}}, <2 x [[TYPE]]> %{{.*}}, <2 x [[TYPE]]> %fneg.i
59+
// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> %hlsl.select.i, %{{.*}}
60+
// DXCHECK: ret <2 x [[TYPE]]> %mul.i
4361
// CHECK: define [[FNATTRS]] <2 x [[TYPE]]> @
44-
// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
45-
// CHECK: ret <2 x [[TYPE]]> %fmod
62+
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
63+
// CHECK: ret <2 x [[TYPE]]> %fmod.i
4664
half2 test_fmod_half2(half2 p0, half2 p1) { return fmod(p0, p1); }
4765

66+
// DXCHECK: define [[FNATTRS]] <3 x [[TYPE]]> @
67+
// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> %{{.*}}, %{{.*}}
68+
// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x [[TYPE]]> %{{.*}}, zeroinitializer
69+
// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.fabs.v3[[INT_TYPE]](<3 x [[TYPE]]> %{{.*}})
70+
// 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)
71+
// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> %{{.*}}
72+
// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1> %{{.*}}, <3 x [[TYPE]]> %{{.*}}, <3 x [[TYPE]]> %fneg.i
73+
// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> %hlsl.select.i, %{{.*}}
74+
// DXCHECK: ret <3 x [[TYPE]]> %mul.i
4875
// CHECK: define [[FNATTRS]] <3 x [[TYPE]]> @
49-
// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
50-
// CHECK: ret <3 x [[TYPE]]> %fmod
76+
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
77+
// CHECK: ret <3 x [[TYPE]]> %fmod.i
5178
half3 test_fmod_half3(half3 p0, half3 p1) { return fmod(p0, p1); }
5279

80+
// DXCHECK: define [[FNATTRS]] <4 x [[TYPE]]> @
81+
// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> %{{.*}}, %{{.*}}
82+
// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x [[TYPE]]> %{{.*}}, zeroinitializer
83+
// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.fabs.v4[[INT_TYPE]](<4 x [[TYPE]]> %{{.*}})
84+
// 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)
85+
// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> %{{.*}}
86+
// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1> %{{.*}}, <4 x [[TYPE]]> %{{.*}}, <4 x [[TYPE]]> %fneg.i
87+
// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> %hlsl.select.i, %{{.*}}
88+
// DXCHECK: ret <4 x [[TYPE]]> %mul.i
5389
// CHECK: define [[FNATTRS]] <4 x [[TYPE]]> @
54-
// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
55-
// CHECK: ret <4 x [[TYPE]]> %fmod
90+
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
91+
// CHECK: ret <4 x [[TYPE]]> %fmod.i
5692
half4 test_fmod_half4(half4 p0, half4 p1) { return fmod(p0, p1); }
5793

94+
// DXCHECK: define [[FNATTRS]] float @
95+
// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn float %{{.*}}, %{{.*}}
96+
// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge float %{{.*}}, 0.000000e+00
97+
// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float %{{.*}})
98+
// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn float @llvm.dx.frac.f32(float %elt.abs.i)
99+
// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn float %{{.*}}
100+
// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float %{{.*}}, float %fneg.i
101+
// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %hlsl.select.i, %{{.*}}
102+
// DXCHECK: ret float %mul.i
58103
// CHECK: define [[FNATTRS]] float @
59-
// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn float
60-
// CHECK: ret float %fmod
104+
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn float
105+
// CHECK: ret float %fmod.i
61106
float test_fmod_float(float p0, float p1) { return fmod(p0, p1); }
62107

108+
// DXCHECK: define [[FNATTRS]] <2 x float> @
109+
// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x float> %{{.*}}, %{{.*}}
110+
// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x float> %{{.*}}, zeroinitializer
111+
// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.fabs.v2f32(<2 x float> %{{.*}})
112+
// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.dx.frac.v2f32(<2 x float> %elt.abs.i)
113+
// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x float> %{{.*}}
114+
// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %fneg.i
115+
// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x float> %hlsl.select.i, %{{.*}}
116+
// DXCHECK: ret <2 x float> %mul.i
63117
// CHECK: define [[FNATTRS]] <2 x float> @
64-
// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <2 x float>
65-
// CHECK: ret <2 x float> %fmod
118+
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <2 x float>
119+
// CHECK: ret <2 x float> %fmod.i
66120
float2 test_fmod_float2(float2 p0, float2 p1) { return fmod(p0, p1); }
67121

122+
// DXCHECK: define [[FNATTRS]] <3 x float> @
123+
// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x float> %{{.*}}, %{{.*}}
124+
// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x float> %{{.*}}, zeroinitializer
125+
// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.fabs.v3f32(<3 x float> %{{.*}})
126+
// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.dx.frac.v3f32(<3 x float> %elt.abs.i)
127+
// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x float> %{{.*}}
128+
// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1> %{{.*}}, <3 x float> %{{.*}}, <3 x float> %fneg.i
129+
// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x float> %hlsl.select.i, %{{.*}}
130+
// DXCHECK: ret <3 x float> %mul.i
68131
// CHECK: define [[FNATTRS]] <3 x float> @
69-
// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <3 x float>
70-
// CHECK: ret <3 x float> %fmod
132+
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <3 x float>
133+
// CHECK: ret <3 x float> %fmod.i
71134
float3 test_fmod_float3(float3 p0, float3 p1) { return fmod(p0, p1); }
72135

136+
// DXCHECK: define [[FNATTRS]] <4 x float> @
137+
// DXCHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x float> %{{.*}}, %{{.*}}
138+
// DXCHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x float> %{{.*}}, zeroinitializer
139+
// DXCHECK: %elt.abs.i = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f32(<4 x float> %{{.*}})
140+
// DXCHECK: %hlsl.frac.i = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.frac.v4f32(<4 x float> %elt.abs.i)
141+
// DXCHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x float> %{{.*}}
142+
// DXCHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %fneg.i
143+
// DXCHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x float> %hlsl.select.i, %{{.*}}
144+
// DXCHECK: ret <4 x float> %mul.i
73145
// CHECK: define [[FNATTRS]] <4 x float> @
74-
// CHECK: %fmod = frem reassoc nnan ninf nsz arcp afn <4 x float>
75-
// CHECK: ret <4 x float> %fmod
146+
// CHECK: %fmod.i = frem reassoc nnan ninf nsz arcp afn <4 x float>
147+
// CHECK: ret <4 x float> %fmod.i
76148
float4 test_fmod_float4(float4 p0, float4 p1) { return fmod(p0, p1); }
77149

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// 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
2+
3+
float test_no_second_arg(float2 p0) {
4+
return fmod(p0);
5+
// expected-error@-1 {{no matching function for call to 'fmod'}}
6+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 1 was provided}}
7+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 1 was provided}}
8+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 1 was provided}}
9+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 1 was provided}}
10+
}
11+
12+
float test_too_many_arg(float2 p0) {
13+
return fmod(p0, p0, p0);
14+
// expected-error@-1 {{no matching function for call to 'fmod'}}
15+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 3 were provided}}
16+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 3 were provided}}
17+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 3 were provided}}
18+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 3 were provided}}
19+
}
20+
21+
float test_double_inputs(double p0, double p1) {
22+
return fmod(p0, p1);
23+
// expected-error@-1 {{call to 'fmod' is ambiguous}}
24+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
25+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
26+
}
27+
28+
float test_int_inputs(int p0, int p1) {
29+
return fmod(p0, p1);
30+
// expected-error@-1 {{call to 'fmod' is ambiguous}}
31+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
32+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
33+
}

0 commit comments

Comments
 (0)