Skip to content

Commit 1cb64d7

Browse files
authored
[HLSL][DXIL][SPIRV] Implementation of an abstraction for intrinsic selection of HLSL backends (#87171)
Start of #83882 - `Builtins.td` - add the `hlsl` `all` elementwise builtin. - `CGBuiltin.cpp` - Show a use case for CGHLSLUtils via an `all` intrinsic codegen. - `CGHLSLRuntime.cpp` - move `thread_id` to use CGHLSLUtils. - `CGHLSLRuntime.h` - Create a macro to help pick the right intrinsic for the backend. - `hlsl_intrinsics.h` - Add the `all` api. - `SemaChecking.cpp` - Add `all` builtin type checking - `IntrinsicsDirectX.td` - Add the `all` `dx` intrinsic - `IntrinsicsSPIRV.td` - Add the `all` `spv` intrinsic Work still needed: - `SPIRVInstructionSelector.cpp` - Add an implementation of `OpAll` for `spv_all` intrinsic
1 parent 1341760 commit 1cb64d7

File tree

9 files changed

+445
-15
lines changed

9 files changed

+445
-15
lines changed

clang/include/clang/Basic/Builtins.td

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

45894589
// HLSL
4590+
def HLSLAll : LangBuiltin<"HLSL_LANG"> {
4591+
let Spellings = ["__builtin_hlsl_elementwise_all"];
4592+
let Attributes = [NoThrow, Const];
4593+
let Prototype = "bool(...)";
4594+
}
4595+
45904596
def HLSLAny : LangBuiltin<"HLSL_LANG"> {
45914597
let Spellings = ["__builtin_hlsl_elementwise_any"];
45924598
let Attributes = [NoThrow, Const];

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "ABIInfo.h"
1414
#include "CGCUDARuntime.h"
1515
#include "CGCXXABI.h"
16+
#include "CGHLSLRuntime.h"
1617
#include "CGObjCRuntime.h"
1718
#include "CGOpenCLRuntime.h"
1819
#include "CGRecordLayout.h"
@@ -18172,6 +18173,13 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
1817218173
return nullptr;
1817318174

1817418175
switch (BuiltinID) {
18176+
case Builtin::BI__builtin_hlsl_elementwise_all: {
18177+
Value *Op0 = EmitScalarExpr(E->getArg(0));
18178+
return Builder.CreateIntrinsic(
18179+
/*ReturnType=*/llvm::Type::getInt1Ty(getLLVMContext()),
18180+
CGM.getHLSLRuntime().getAllIntrinsic(), ArrayRef<Value *>{Op0}, nullptr,
18181+
"hlsl.all");
18182+
}
1817518183
case Builtin::BI__builtin_hlsl_elementwise_any: {
1817618184
Value *Op0 = EmitScalarExpr(E->getArg(0));
1817718185
return Builder.CreateIntrinsic(

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
#include "CodeGenModule.h"
1818
#include "clang/AST/Decl.h"
1919
#include "clang/Basic/TargetOptions.h"
20-
#include "llvm/IR/IntrinsicsDirectX.h"
21-
#include "llvm/IR/IntrinsicsSPIRV.h"
2220
#include "llvm/IR/Metadata.h"
2321
#include "llvm/IR/Module.h"
2422
#include "llvm/Support/FormatVariadic.h"
@@ -117,6 +115,10 @@ GlobalVariable *replaceBuffer(CGHLSLRuntime::Buffer &Buf) {
117115

118116
} // namespace
119117

118+
llvm::Triple::ArchType CGHLSLRuntime::getArch() {
119+
return CGM.getTarget().getTriple().getArch();
120+
}
121+
120122
void CGHLSLRuntime::addConstant(VarDecl *D, Buffer &CB) {
121123
if (D->getStorageClass() == SC_Static) {
122124
// For static inside cbuffer, take as global static.
@@ -343,18 +345,8 @@ llvm::Value *CGHLSLRuntime::emitInputSemantic(IRBuilder<> &B,
343345
return B.CreateCall(FunctionCallee(DxGroupIndex));
344346
}
345347
if (D.hasAttr<HLSLSV_DispatchThreadIDAttr>()) {
346-
llvm::Function *ThreadIDIntrinsic;
347-
switch (CGM.getTarget().getTriple().getArch()) {
348-
case llvm::Triple::dxil:
349-
ThreadIDIntrinsic = CGM.getIntrinsic(Intrinsic::dx_thread_id);
350-
break;
351-
case llvm::Triple::spirv:
352-
ThreadIDIntrinsic = CGM.getIntrinsic(Intrinsic::spv_thread_id);
353-
break;
354-
default:
355-
llvm_unreachable("Input semantic not supported by target");
356-
break;
357-
}
348+
llvm::Function *ThreadIDIntrinsic =
349+
CGM.getIntrinsic(getThreadIdIntrinsic());
358350
return buildVectorInput(B, ThreadIDIntrinsic, Ty);
359351
}
360352
assert(false && "Unhandled parameter attribute");

clang/lib/CodeGen/CGHLSLRuntime.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@
1616
#define LLVM_CLANG_LIB_CODEGEN_CGHLSLRUNTIME_H
1717

1818
#include "llvm/IR/IRBuilder.h"
19+
#include "llvm/IR/Intrinsics.h"
20+
#include "llvm/IR/IntrinsicsDirectX.h"
21+
#include "llvm/IR/IntrinsicsSPIRV.h"
1922

23+
#include "clang/Basic/Builtins.h"
2024
#include "clang/Basic/HLSLRuntime.h"
2125

2226
#include "llvm/ADT/SmallVector.h"
@@ -26,6 +30,22 @@
2630
#include <optional>
2731
#include <vector>
2832

33+
// A function generator macro for picking the right intrinsic
34+
// for the target backend
35+
#define GENERATE_HLSL_INTRINSIC_FUNCTION(FunctionName, IntrinsicPostfix) \
36+
llvm::Intrinsic::ID get##FunctionName##Intrinsic() { \
37+
llvm::Triple::ArchType Arch = getArch(); \
38+
switch (Arch) { \
39+
case llvm::Triple::dxil: \
40+
return llvm::Intrinsic::dx_##IntrinsicPostfix; \
41+
case llvm::Triple::spirv: \
42+
return llvm::Intrinsic::spv_##IntrinsicPostfix; \
43+
default: \
44+
llvm_unreachable("Intrinsic " #IntrinsicPostfix \
45+
" not supported by target architecture"); \
46+
} \
47+
}
48+
2949
namespace llvm {
3050
class GlobalVariable;
3151
class Function;
@@ -48,6 +68,17 @@ class CodeGenModule;
4868

4969
class CGHLSLRuntime {
5070
public:
71+
//===----------------------------------------------------------------------===//
72+
// Start of reserved area for HLSL intrinsic getters.
73+
//===----------------------------------------------------------------------===//
74+
75+
GENERATE_HLSL_INTRINSIC_FUNCTION(All, all)
76+
GENERATE_HLSL_INTRINSIC_FUNCTION(ThreadId, thread_id)
77+
78+
//===----------------------------------------------------------------------===//
79+
// End of reserved area for HLSL intrinsic getters.
80+
//===----------------------------------------------------------------------===//
81+
5182
struct BufferResBinding {
5283
// The ID like 2 in register(b2, space1).
5384
std::optional<unsigned> Reg;
@@ -96,6 +127,7 @@ class CGHLSLRuntime {
96127
BufferResBinding &Binding);
97128
void addConstant(VarDecl *D, Buffer &CB);
98129
void addBufferDecls(const DeclContext *DC, Buffer &CB);
130+
llvm::Triple::ArchType getArch();
99131
llvm::SmallVector<Buffer> Buffers;
100132
};
101133

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

clang/lib/Sema/SemaChecking.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5563,6 +5563,7 @@ void SetElementTypeAsReturnType(Sema *S, CallExpr *TheCall,
55635563
// returning an ExprError
55645564
bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
55655565
switch (BuiltinID) {
5566+
case Builtin::BI__builtin_hlsl_elementwise_all:
55665567
case Builtin::BI__builtin_hlsl_elementwise_any: {
55675568
if (checkArgCount(*this, TheCall, 1))
55685569
return true;

0 commit comments

Comments
 (0)