Skip to content

Commit 6c454ba

Browse files
committed
Modified implementation after reorganization of instrinsics, finished fmod-directx.hlsl tests
1 parent 523da62 commit 6c454ba

File tree

4 files changed

+104
-59
lines changed

4 files changed

+104
-59
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_detail.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,25 +48,25 @@ template <typename T> struct is_arithmetic {
4848
template <typename T>
4949
constexpr enable_if_t<is_same<float, T>::value || is_same<half, T>::value, T>
5050
fmod_impl(T X, T Y) {
51-
#if !defined(__DirectX__)
51+
#if !defined(__DIRECTX__)
5252
return __builtin_elementwise_fmod(X, Y);
5353
#else
5454
T div = X / Y;
5555
bool ge = div >= -div;
56-
T frc = __builtin_hlsl_elementwise_frac(__builtin_elementwise_abs(div));
57-
return __builtin_hlsl_select(ge, frc, -frc) * Y;
56+
T frc = frac(abs(div));
57+
return select<T>(ge, frc, -frc) * Y;
5858
#endif
5959
}
6060

6161
template <typename T, int N>
6262
constexpr vector<T, N> fmod_vec_impl(vector<T, N> X, vector<T, N> Y) {
63-
#if !defined(__DirectX__)
63+
#if !defined(__DIRECTX__)
6464
return __builtin_elementwise_fmod(X, Y);
6565
#else
6666
vector<T, N> div = X / Y;
6767
vector<bool, N> ge = div >= -div;
68-
vector<T, N> frc = __builtin_hlsl_elementwise_frac(__builtin_elementwise_abs(div));
69-
return __builtin_hlsl_select(ge, frc, -frc) * Y;
68+
vector<T, N> frc = frac(abs(div));
69+
return select<T>(ge, frc, -frc) * Y;
7070
#endif
7171
}
7272

clang/lib/Headers/hlsl/hlsl_intrinsics.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,38 @@ const inline float distance(vector<float, N> X, vector<float, N> Y) {
109109
return __detail::distance_vec_impl(X, Y);
110110
}
111111

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

clang/test/CodeGenHLSL/builtins/fmod-directx.hlsl

Lines changed: 66 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,56 +4,103 @@
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 -O1 -o - | FileCheck %s \
7+
// RUN: -emit-llvm -O1 -o - | FileCheck %s \
88
// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTYPE=half
9-
109
//
1110
// ---------- No Native Half support test -----------
1211
//
1312
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
14-
// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
13+
// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm \
1514
// RUN: -O1 -o - | FileCheck %s \
1615
// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTYPE=float
1716

1817

1918

2019
// CHECK: define [[FNATTRS]] [[TYPE]] @
21-
// CHECK: call nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}([[TYPE]] noundef nofpclass(nan inf) %{{.*}}, [[TYPE]] noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
22-
// CHECK: ret [[TYPE]] %call
20+
// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn [[TYPE]]
21+
// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge [[TYPE]]
22+
// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.fabs.f
23+
// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn [[TYPE]] @llvm.dx.frac.f
24+
// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn [[TYPE]]
25+
// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1
26+
// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn [[TYPE]]
27+
// CHECK: ret [[TYPE]] %mul.i
2328
half test_fmod_half(half p0, half p1) { return fmod(p0, p1); }
2429

2530
// CHECK: define [[FNATTRS]] <2 x [[TYPE]]> @
26-
// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}(<2 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}, <2 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
27-
// CHECK: ret <2 x [[TYPE]]> %splat.splat
31+
// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
32+
// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x [[TYPE]]>
33+
// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.fabs.v2f
34+
// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]> @llvm.dx.frac.v2f
35+
// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
36+
// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1>
37+
// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x [[TYPE]]>
38+
// CHECK: ret <2 x [[TYPE]]> %mul.i
2839
half2 test_fmod_half2(half2 p0, half2 p1) { return fmod(p0, p1); }
2940

3041
// CHECK: define [[FNATTRS]] <3 x [[TYPE]]> @
31-
// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}(<3 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}, <3 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}} #{{.*}}
32-
// CHECK: ret <3 x [[TYPE]]> %splat.splat
42+
// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
43+
// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x [[TYPE]]>
44+
// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.fabs.v3f
45+
// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]> @llvm.dx.frac.v3f
46+
// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
47+
// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1>
48+
// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x [[TYPE]]>
49+
// CHECK: ret <3 x [[TYPE]]> %mul.i
3350
half3 test_fmod_half3(half3 p0, half3 p1) { return fmod(p0, p1); }
3451

3552
// CHECK: define [[FNATTRS]] <4 x [[TYPE]]> @
36-
// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] [[TYPE]] @{{.*}}(<4 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}, <4 x [[TYPE]]> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
37-
// CHECK: ret <4 x [[TYPE]]> %splat.splat
53+
// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
54+
// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x [[TYPE]]>
55+
// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.fabs.v4f
56+
// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]> @llvm.dx.frac.v4f
57+
// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
58+
// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1>
59+
// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x [[TYPE]]>
60+
// CHECK: ret <4 x [[TYPE]]> %mul.i
3861
half4 test_fmod_half4(half4 p0, half4 p1) { return fmod(p0, p1); }
3962

4063
// CHECK: define [[FNATTRS]] float @
41-
// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(float noundef nofpclass(nan inf) %{{.*}}, float noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
42-
// CHECK: ret float %call
64+
// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn float
65+
// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge float
66+
// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f
67+
// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn float @llvm.dx.frac.f
68+
// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn float
69+
// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1
70+
// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float
71+
// CHECK: ret float %mul.i
4372
float test_fmod_float(float p0, float p1) { return fmod(p0, p1); }
4473

4574
// CHECK: define [[FNATTRS]] <2 x float> @
46-
// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(<2 x float> noundef nofpclass(nan inf) %{{.*}}, <2 x float> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
47-
// CHECK: ret <2 x float> %splat.splat
75+
// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <2 x float>
76+
// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <2 x float>
77+
// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.fabs.v2f
78+
// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.dx.frac.v2f
79+
// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <2 x float>
80+
// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <2 x i1>
81+
// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <2 x float>
82+
// CHECK: ret <2 x float> %mul.i
4883
float2 test_fmod_float2(float2 p0, float2 p1) { return fmod(p0, p1); }
4984

5085
// CHECK: define [[FNATTRS]] <3 x float> @
51-
// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(<3 x float> noundef nofpclass(nan inf) %{{.*}}, <3 x float> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
52-
// CHECK: ret <3 x float> %splat.splat
86+
// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <3 x float>
87+
// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <3 x float>
88+
// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.fabs.v3f
89+
// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.dx.frac.v3f
90+
// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <3 x float>
91+
// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <3 x i1>
92+
// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <3 x float>
93+
// CHECK: ret <3 x float> %mul.i
5394
float3 test_fmod_float3(float3 p0, float3 p1) { return fmod(p0, p1); }
5495

5596
// CHECK: define [[FNATTRS]] <4 x float> @
56-
// CHECK: call reassoc nnan ninf nsz arcp afn [[FNATTRS]] float @{{.*}}(<4 x float> noundef nofpclass(nan inf) %{{.*}}, <4 x float> noundef nofpclass(nan inf) %{{.*}}) #{{.*}}
57-
// CHECK: ret <4 x float> %splat.splat
97+
// CHECK: %div1.i = fdiv reassoc nnan ninf nsz arcp afn <4 x float>
98+
// CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn oge <4 x float>
99+
// CHECK: %elt.abs.i = tail call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f
100+
// CHECK: %hlsl.frac.i = tail call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.frac.v4f
101+
// CHECK: %fneg2.i = fneg reassoc nnan ninf nsz arcp afn <4 x float>
102+
// CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn <4 x i1>
103+
// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x float>
104+
// CHECK: ret <4 x float> %mul.i
58105
float4 test_fmod_float4(float4 p0, float4 p1) { return fmod(p0, p1); }
59106

0 commit comments

Comments
 (0)