Skip to content

Commit 2807ea6

Browse files
authored
[HLSL] implement the any intrinsic (llvm#83903)
This PR implements the frontend for llvm#70076 This PR is part 1 of 2. Part 2 requires an intrinsic to instructions lowering. - `Builtins.td` - add an `any` builtin - `CGBuiltin.cpp` add the builtin to intrinsic lowering - `hlsl_basic_types.h` -add the `bool` vectors since that is an input for any - `hlsl_intrinsics.h` - add the `any` api - `SemaChecking.cpp` - addy `any` builtin checking - `IntrinsicsDirectX.td` - add the llvm intrinsic
1 parent b2ca23a commit 2807ea6

File tree

8 files changed

+332
-1
lines changed

8 files changed

+332
-1
lines changed

clang/include/clang/Basic/Builtins.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4542,6 +4542,12 @@ def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> {
45424542
}
45434543

45444544
// HLSL
4545+
def HLSLAny : LangBuiltin<"HLSL_LANG"> {
4546+
let Spellings = ["__builtin_hlsl_elementwise_any"];
4547+
let Attributes = [NoThrow, Const];
4548+
let Prototype = "bool(...)";
4549+
}
4550+
45454551
def HLSLWaveActiveCountBits : LangBuiltin<"HLSL_LANG"> {
45464552
let Spellings = ["__builtin_hlsl_wave_active_count_bits"];
45474553
let Attributes = [NoThrow, Const];

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17963,6 +17963,12 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
1796317963
return nullptr;
1796417964

1796517965
switch (BuiltinID) {
17966+
case Builtin::BI__builtin_hlsl_elementwise_any: {
17967+
Value *Op0 = EmitScalarExpr(E->getArg(0));
17968+
return Builder.CreateIntrinsic(
17969+
/*ReturnType*/ llvm::Type::getInt1Ty(getLLVMContext()),
17970+
Intrinsic::dx_any, ArrayRef<Value *>{Op0}, nullptr, "dx.any");
17971+
}
1796617972
case Builtin::BI__builtin_hlsl_dot: {
1796717973
Value *Op0 = EmitScalarExpr(E->getArg(0));
1796817974
Value *Op1 = EmitScalarExpr(E->getArg(1));

clang/lib/Headers/hlsl/hlsl_basic_types.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ typedef vector<uint16_t, 2> uint16_t2;
4242
typedef vector<uint16_t, 3> uint16_t3;
4343
typedef vector<uint16_t, 4> uint16_t4;
4444
#endif
45-
45+
typedef vector<bool, 2> bool2;
46+
typedef vector<bool, 3> bool3;
47+
typedef vector<bool, 4> bool4;
4648
typedef vector<int, 2> int2;
4749
typedef vector<int, 3> int3;
4850
typedef vector<int, 4> int4;

clang/lib/Headers/hlsl/hlsl_intrinsics.h

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,118 @@ double3 abs(double3);
100100
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
101101
double4 abs(double4);
102102

103+
//===----------------------------------------------------------------------===//
104+
// any builtins
105+
//===----------------------------------------------------------------------===//
106+
107+
/// \fn bool any(T x)
108+
/// \brief Returns True if any components of the \a x parameter are non-zero;
109+
/// otherwise, false. \param x The input value.
110+
111+
#ifdef __HLSL_ENABLE_16_BIT
112+
_HLSL_AVAILABILITY(shadermodel, 6.2)
113+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
114+
bool any(int16_t);
115+
_HLSL_AVAILABILITY(shadermodel, 6.2)
116+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
117+
bool any(int16_t2);
118+
_HLSL_AVAILABILITY(shadermodel, 6.2)
119+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
120+
bool any(int16_t3);
121+
_HLSL_AVAILABILITY(shadermodel, 6.2)
122+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
123+
bool any(int16_t4);
124+
_HLSL_AVAILABILITY(shadermodel, 6.2)
125+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
126+
bool any(uint16_t);
127+
_HLSL_AVAILABILITY(shadermodel, 6.2)
128+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
129+
bool any(uint16_t2);
130+
_HLSL_AVAILABILITY(shadermodel, 6.2)
131+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
132+
bool any(uint16_t3);
133+
_HLSL_AVAILABILITY(shadermodel, 6.2)
134+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
135+
bool any(uint16_t4);
136+
#endif
137+
138+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
139+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
140+
bool any(half);
141+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
142+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
143+
bool any(half2);
144+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
145+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
146+
bool any(half3);
147+
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
148+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
149+
bool any(half4);
150+
151+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
152+
bool any(bool);
153+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
154+
bool any(bool2);
155+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
156+
bool any(bool3);
157+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
158+
bool any(bool4);
159+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
160+
161+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
162+
bool any(int);
163+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
164+
bool any(int2);
165+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
166+
bool any(int3);
167+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
168+
bool any(int4);
169+
170+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
171+
bool any(uint);
172+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
173+
bool any(uint2);
174+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
175+
bool any(uint3);
176+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
177+
bool any(uint4);
178+
179+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
180+
bool any(float);
181+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
182+
bool any(float2);
183+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
184+
bool any(float3);
185+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
186+
bool any(float4);
187+
188+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
189+
bool any(int64_t);
190+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
191+
bool any(int64_t2);
192+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
193+
bool any(int64_t3);
194+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
195+
bool any(int64_t4);
196+
197+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
198+
bool any(uint64_t);
199+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
200+
bool any(uint64_t2);
201+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
202+
bool any(uint64_t3);
203+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
204+
bool any(uint64_t4);
205+
206+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
207+
bool any(double);
208+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
209+
bool any(double2);
210+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
211+
bool any(double3);
212+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any)
213+
bool any(double4);
214+
103215
//===----------------------------------------------------------------------===//
104216
// ceil builtins
105217
//===----------------------------------------------------------------------===//

clang/lib/Sema/SemaChecking.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5271,6 +5271,11 @@ bool CheckAllArgsHaveFloatRepresentation(Sema *S, CallExpr *TheCall) {
52715271
// returning an ExprError
52725272
bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
52735273
switch (BuiltinID) {
5274+
case Builtin::BI__builtin_hlsl_elementwise_any: {
5275+
if (checkArgCount(*this, TheCall, 1))
5276+
return true;
5277+
break;
5278+
}
52745279
case Builtin::BI__builtin_hlsl_dot: {
52755280
if (checkArgCount(*this, TheCall, 2))
52765281
return true;
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
2+
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
3+
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
4+
// RUN: --check-prefixes=CHECK,NATIVE_HALF
5+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
6+
// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
7+
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF
8+
9+
#ifdef __HLSL_ENABLE_16_BIT
10+
// NATIVE_HALF: define noundef i1 @
11+
// NATIVE_HALF: %dx.any = call i1 @llvm.dx.any.i16
12+
// NATIVE_HALF: ret i1 %dx.any
13+
bool test_any_int16_t(int16_t p0) { return any(p0); }
14+
// NATIVE_HALF: define noundef i1 @
15+
// NATIVE_HALF: %dx.any = call i1 @llvm.dx.any.v2i16
16+
// NATIVE_HALF: ret i1 %dx.any
17+
bool test_any_int16_t2(int16_t2 p0) { return any(p0); }
18+
// NATIVE_HALF: define noundef i1 @
19+
// NATIVE_HALF: %dx.any = call i1 @llvm.dx.any.v3i16
20+
// NATIVE_HALF: ret i1 %dx.any
21+
bool test_any_int16_t3(int16_t3 p0) { return any(p0); }
22+
// NATIVE_HALF: define noundef i1 @
23+
// NATIVE_HALF: %dx.any = call i1 @llvm.dx.any.v4i16
24+
// NATIVE_HALF: ret i1 %dx.any
25+
bool test_any_int16_t4(int16_t4 p0) { return any(p0); }
26+
27+
// NATIVE_HALF: define noundef i1 @
28+
// NATIVE_HALF: %dx.any = call i1 @llvm.dx.any.i16
29+
// NATIVE_HALF: ret i1 %dx.any
30+
bool test_any_uint16_t(uint16_t p0) { return any(p0); }
31+
// NATIVE_HALF: define noundef i1 @
32+
// NATIVE_HALF: %dx.any = call i1 @llvm.dx.any.v2i16
33+
// NATIVE_HALF: ret i1 %dx.any
34+
bool test_any_uint16_t2(uint16_t2 p0) { return any(p0); }
35+
// NATIVE_HALF: define noundef i1 @
36+
// NATIVE_HALF: %dx.any = call i1 @llvm.dx.any.v3i16
37+
// NATIVE_HALF: ret i1 %dx.any
38+
bool test_any_uint16_t3(uint16_t3 p0) { return any(p0); }
39+
// NATIVE_HALF: define noundef i1 @
40+
// NATIVE_HALF: %dx.any = call i1 @llvm.dx.any.v4i16
41+
// NATIVE_HALF: ret i1 %dx.any
42+
bool test_any_uint16_t4(uint16_t4 p0) { return any(p0); }
43+
#endif // __HLSL_ENABLE_16_BIT
44+
45+
// CHECK: define noundef i1 @
46+
// NATIVE_HALF: %dx.any = call i1 @llvm.dx.any.f16
47+
// NO_HALF: %dx.any = call i1 @llvm.dx.any.f32
48+
// CHECK: ret i1 %dx.any
49+
bool test_any_half(half p0) { return any(p0); }
50+
51+
// CHECK: define noundef i1 @
52+
// NATIVE_HALF: %dx.any = call i1 @llvm.dx.any.v2f16
53+
// NO_HALF: %dx.any = call i1 @llvm.dx.any.v2f32
54+
// CHECK: ret i1 %dx.any
55+
bool test_any_half2(half2 p0) { return any(p0); }
56+
57+
// CHECK: define noundef i1 @
58+
// NATIVE_HALF: %dx.any = call i1 @llvm.dx.any.v3f16
59+
// NO_HALF: %dx.any = call i1 @llvm.dx.any.v3f32
60+
// CHECK: ret i1 %dx.any
61+
bool test_any_half3(half3 p0) { return any(p0); }
62+
63+
// CHECK: define noundef i1 @
64+
// NATIVE_HALF: %dx.any = call i1 @llvm.dx.any.v4f16
65+
// NO_HALF: %dx.any = call i1 @llvm.dx.any.v4f32
66+
// CHECK: ret i1 %dx.any
67+
bool test_any_half4(half4 p0) { return any(p0); }
68+
69+
// CHECK: define noundef i1 @
70+
// CHECK: %dx.any = call i1 @llvm.dx.any.f32
71+
// CHECK: ret i1 %dx.any
72+
bool test_any_float(float p0) { return any(p0); }
73+
// CHECK: define noundef i1 @
74+
// CHECK: %dx.any = call i1 @llvm.dx.any.v2f32
75+
// CHECK: ret i1 %dx.any
76+
bool test_any_float2(float2 p0) { return any(p0); }
77+
// CHECK: define noundef i1 @
78+
// CHECK: %dx.any = call i1 @llvm.dx.any.v3f32
79+
// CHECK: ret i1 %dx.any
80+
bool test_any_float3(float3 p0) { return any(p0); }
81+
// CHECK: define noundef i1 @
82+
// CHECK: %dx.any = call i1 @llvm.dx.any.v4f32
83+
// CHECK: ret i1 %dx.any
84+
bool test_any_float4(float4 p0) { return any(p0); }
85+
86+
// CHECK: define noundef i1 @
87+
// CHECK: %dx.any = call i1 @llvm.dx.any.f64
88+
// CHECK: ret i1 %dx.any
89+
bool test_any_double(double p0) { return any(p0); }
90+
// CHECK: define noundef i1 @
91+
// CHECK: %dx.any = call i1 @llvm.dx.any.v2f64
92+
// CHECK: ret i1 %dx.any
93+
bool test_any_double2(double2 p0) { return any(p0); }
94+
// CHECK: define noundef i1 @
95+
// CHECK: %dx.any = call i1 @llvm.dx.any.v3f64
96+
// CHECK: ret i1 %dx.any
97+
bool test_any_double3(double3 p0) { return any(p0); }
98+
// CHECK: define noundef i1 @
99+
// CHECK: %dx.any = call i1 @llvm.dx.any.v4f64
100+
// CHECK: ret i1 %dx.any
101+
bool test_any_double4(double4 p0) { return any(p0); }
102+
103+
// CHECK: define noundef i1 @
104+
// CHECK: %dx.any = call i1 @llvm.dx.any.i32
105+
// CHECK: ret i1 %dx.any
106+
bool test_any_int(int p0) { return any(p0); }
107+
// CHECK: define noundef i1 @
108+
// CHECK: %dx.any = call i1 @llvm.dx.any.v2i32
109+
// CHECK: ret i1 %dx.any
110+
bool test_any_int2(int2 p0) { return any(p0); }
111+
// CHECK: define noundef i1 @
112+
// CHECK: %dx.any = call i1 @llvm.dx.any.v3i32
113+
// CHECK: ret i1 %dx.any
114+
bool test_any_int3(int3 p0) { return any(p0); }
115+
// CHECK: define noundef i1 @
116+
// CHECK: %dx.any = call i1 @llvm.dx.any.v4i32
117+
// CHECK: ret i1 %dx.any
118+
bool test_any_int4(int4 p0) { return any(p0); }
119+
120+
// CHECK: define noundef i1 @
121+
// CHECK: %dx.any = call i1 @llvm.dx.any.i32
122+
// CHECK: ret i1 %dx.any
123+
bool test_any_uint(uint p0) { return any(p0); }
124+
// CHECK: define noundef i1 @
125+
// CHECK: %dx.any = call i1 @llvm.dx.any.v2i32
126+
// CHECK: ret i1 %dx.any
127+
bool test_any_uint2(uint2 p0) { return any(p0); }
128+
// CHECK: define noundef i1 @
129+
// CHECK: %dx.any = call i1 @llvm.dx.any.v3i32
130+
// CHECK: ret i1 %dx.any
131+
bool test_any_uint3(uint3 p0) { return any(p0); }
132+
// CHECK: define noundef i1 @
133+
// CHECK: %dx.any = call i1 @llvm.dx.any.v4i32
134+
// CHECK: ret i1 %dx.any
135+
bool test_any_uint4(uint4 p0) { return any(p0); }
136+
137+
// CHECK: define noundef i1 @
138+
// CHECK: %dx.any = call i1 @llvm.dx.any.i64
139+
// CHECK: ret i1 %dx.any
140+
bool test_any_int64_t(int64_t p0) { return any(p0); }
141+
// CHECK: define noundef i1 @
142+
// CHECK: %dx.any = call i1 @llvm.dx.any.v2i64
143+
// CHECK: ret i1 %dx.any
144+
bool test_any_int64_t2(int64_t2 p0) { return any(p0); }
145+
// CHECK: define noundef i1 @
146+
// CHECK: %dx.any = call i1 @llvm.dx.any.v3i64
147+
// CHECK: ret i1 %dx.any
148+
bool test_any_int64_t3(int64_t3 p0) { return any(p0); }
149+
// CHECK: define noundef i1 @
150+
// CHECK: %dx.any = call i1 @llvm.dx.any.v4i64
151+
// CHECK: ret i1 %dx.any
152+
bool test_any_int64_t4(int64_t4 p0) { return any(p0); }
153+
154+
// CHECK: define noundef i1 @
155+
// CHECK: %dx.any = call i1 @llvm.dx.any.i64
156+
// CHECK: ret i1 %dx.any
157+
bool test_any_uint64_t(uint64_t p0) { return any(p0); }
158+
// CHECK: define noundef i1 @
159+
// CHECK: %dx.any = call i1 @llvm.dx.any.v2i64
160+
// CHECK: ret i1 %dx.any
161+
bool test_any_uint64_t2(uint64_t2 p0) { return any(p0); }
162+
// CHECK: define noundef i1 @
163+
// CHECK: %dx.any = call i1 @llvm.dx.any.v3i64
164+
// CHECK: ret i1 %dx.any
165+
bool test_any_uint64_t3(uint64_t3 p0) { return any(p0); }
166+
// CHECK: define noundef i1 @
167+
// CHECK: %dx.any = call i1 @llvm.dx.any.v4i64
168+
// CHECK: ret i1 %dx.any
169+
bool test_any_uint64_t4(uint64_t4 p0) { return any(p0); }
170+
171+
// CHECK: define noundef i1 @
172+
// CHECK: %dx.any = call i1 @llvm.dx.any.i1
173+
// CHECK: ret i1 %dx.any
174+
bool test_any_bool(bool p0) { return any(p0); }
175+
// CHECK: define noundef i1 @
176+
// CHECK: %dx.any = call i1 @llvm.dx.any.v2i1
177+
// CHECK: ret i1 %dx.any
178+
bool test_any_bool2(bool2 p0) { return any(p0); }
179+
// CHECK: define noundef i1 @
180+
// CHECK: %dx.any = call i1 @llvm.dx.any.v3i1
181+
// CHECK: ret i1 %dx.any
182+
bool test_any_bool3(bool3 p0) { return any(p0); }
183+
// CHECK: define noundef i1 @
184+
// CHECK: %dx.any = call i1 @llvm.dx.any.v4i1
185+
// CHECK: ret i1 %dx.any
186+
bool test_any_bool4(bool4 p0) { return any(p0); }
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected
3+
4+
bool test_too_few_arg() {
5+
return __builtin_hlsl_elementwise_any();
6+
// expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
7+
}
8+
9+
bool test_too_many_arg(float2 p0) {
10+
return __builtin_hlsl_elementwise_any(p0, p0);
11+
// expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
12+
}

llvm/include/llvm/IR/IntrinsicsDirectX.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ def int_dx_flattened_thread_id_in_group : Intrinsic<[llvm_i32_ty], [], [IntrNoMe
2020
def int_dx_create_handle : ClangBuiltin<"__builtin_hlsl_create_handle">,
2121
Intrinsic<[ llvm_ptr_ty ], [llvm_i8_ty], [IntrWillReturn]>;
2222

23+
def int_dx_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty]>;
24+
2325
def int_dx_dot :
2426
Intrinsic<[LLVMVectorElementType<0>],
2527
[llvm_anyvector_ty, LLVMScalarOrSameVectorWidth<0, LLVMVectorElementType<0>>],

0 commit comments

Comments
 (0)