Skip to content

Commit f1406f8

Browse files
committed
[SPIRV][HLSL] Add mad intrinsic lowering for spirv
1 parent db2f64e commit f1406f8

File tree

8 files changed

+521
-122
lines changed

8 files changed

+521
-122
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18186,6 +18186,40 @@ Intrinsic::ID getDotProductIntrinsic(QualType QT, int elementCount) {
1818618186
return Intrinsic::dx_udot;
1818718187
}
1818818188

18189+
Value *CodeGenFunction::EmitHLSLMadIntrinsic(const CallExpr *E) {
18190+
Value *M = EmitScalarExpr(E->getArg(0));
18191+
Value *A = EmitScalarExpr(E->getArg(1));
18192+
Value *B = EmitScalarExpr(E->getArg(2));
18193+
if (E->getArg(0)->getType()->hasFloatingRepresentation())
18194+
return Builder.CreateIntrinsic(
18195+
/*ReturnType*/ M->getType(), Intrinsic::fmuladd,
18196+
ArrayRef<Value *>{M, A, B}, nullptr, "hlsl.fmad");
18197+
18198+
auto EmitHLSLIMadDirectX = [E, M, A, B, this]() -> Value * {
18199+
if (E->getArg(0)->getType()->hasSignedIntegerRepresentation())
18200+
return Builder.CreateIntrinsic(
18201+
/*ReturnType*/ M->getType(), Intrinsic::dx_imad,
18202+
ArrayRef<Value *>{M, A, B}, nullptr, "dx.imad");
18203+
assert(E->getArg(0)->getType()->hasUnsignedIntegerRepresentation());
18204+
return Builder.CreateIntrinsic(
18205+
/*ReturnType=*/M->getType(), Intrinsic::dx_umad,
18206+
ArrayRef<Value *>{M, A, B}, nullptr, "dx.umad");
18207+
};
18208+
18209+
auto EmitHLSLIMadGeneric = [E, M, A, B, this]() -> Value * {
18210+
if (E->getArg(0)->getType()->hasSignedIntegerRepresentation()) {
18211+
Value *Mul = Builder.CreateNSWMul(M, A);
18212+
return Builder.CreateNSWAdd(Mul, B);
18213+
}
18214+
assert(E->getArg(0)->getType()->hasUnsignedIntegerRepresentation());
18215+
Value *Mul = Builder.CreateNUWMul(M, A);
18216+
return Builder.CreateNUWAdd(Mul, B);
18217+
};
18218+
18219+
return CGM.getHLSLRuntime().emitHLSLIntrinsic(
18220+
EmitHLSLIMadDirectX, EmitHLSLIMadGeneric, EmitHLSLIMadGeneric);
18221+
}
18222+
1818918223
Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
1819018224
const CallExpr *E) {
1819118225
if (!getLangOpts().HLSL)
@@ -18291,23 +18325,7 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
1829118325
ArrayRef<Value *>{Op0}, nullptr, "dx.isinf");
1829218326
}
1829318327
case Builtin::BI__builtin_hlsl_mad: {
18294-
Value *M = EmitScalarExpr(E->getArg(0));
18295-
Value *A = EmitScalarExpr(E->getArg(1));
18296-
Value *B = EmitScalarExpr(E->getArg(2));
18297-
if (E->getArg(0)->getType()->hasFloatingRepresentation()) {
18298-
return Builder.CreateIntrinsic(
18299-
/*ReturnType*/ M->getType(), Intrinsic::fmuladd,
18300-
ArrayRef<Value *>{M, A, B}, nullptr, "dx.fmad");
18301-
}
18302-
if (E->getArg(0)->getType()->hasSignedIntegerRepresentation()) {
18303-
return Builder.CreateIntrinsic(
18304-
/*ReturnType*/ M->getType(), Intrinsic::dx_imad,
18305-
ArrayRef<Value *>{M, A, B}, nullptr, "dx.imad");
18306-
}
18307-
assert(E->getArg(0)->getType()->hasUnsignedIntegerRepresentation());
18308-
return Builder.CreateIntrinsic(
18309-
/*ReturnType=*/M->getType(), Intrinsic::dx_umad,
18310-
ArrayRef<Value *>{M, A, B}, nullptr, "dx.umad");
18328+
return EmitHLSLMadIntrinsic(E);
1831118329
}
1831218330
case Builtin::BI__builtin_hlsl_elementwise_rcp: {
1831318331
Value *Op0 = EmitScalarExpr(E->getArg(0));

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,21 @@ llvm::Triple::ArchType CGHLSLRuntime::getArch() {
119119
return CGM.getTarget().getTriple().getArch();
120120
}
121121

122+
Value *
123+
CGHLSLRuntime::emitHLSLIntrinsic(llvm::function_ref<Value *()> DxilEmitter,
124+
llvm::function_ref<Value *()> SPIRVEmitter,
125+
llvm::function_ref<Value *()> GenericEmitter) {
126+
llvm::Triple::ArchType Arch = getArch();
127+
switch (Arch) {
128+
case llvm::Triple::dxil:
129+
return DxilEmitter();
130+
case llvm::Triple::spirv:
131+
return SPIRVEmitter();
132+
default:
133+
return GenericEmitter();
134+
}
135+
}
136+
122137
void CGHLSLRuntime::addConstant(VarDecl *D, Buffer &CB) {
123138
if (D->getStorageClass() == SC_Static) {
124139
// For static inside cbuffer, take as global static.

clang/lib/CodeGen/CGHLSLRuntime.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ namespace llvm {
5050
class GlobalVariable;
5151
class Function;
5252
class StructType;
53+
class Value;
5354
} // namespace llvm
5455

5556
namespace clang {
@@ -79,7 +80,13 @@ class CGHLSLRuntime {
7980
//===----------------------------------------------------------------------===//
8081
// End of reserved area for HLSL intrinsic getters.
8182
//===----------------------------------------------------------------------===//
82-
83+
llvm::Value *emitHLSLIntrinsic(
84+
llvm::function_ref<llvm::Value *()> DxilEmitter,
85+
llvm::function_ref<llvm::Value *()> SPIRVEmitter,
86+
llvm::function_ref<llvm::Value *()> GenericEmitter =
87+
[]() -> llvm::Value * {
88+
llvm_unreachable("Intrinsic not supported by target architecture.");
89+
});
8390
struct BufferResBinding {
8491
// The ID like 2 in register(b2, space1).
8592
std::optional<unsigned> Reg;

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4548,6 +4548,7 @@ class CodeGenFunction : public CodeGenTypeCache {
45484548
llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
45494549
llvm::Value *EmitAMDGPUBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
45504550
llvm::Value *EmitHLSLBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
4551+
llvm::Value *EmitHLSLMadIntrinsic(const CallExpr *E);
45514552
llvm::Value *EmitScalarOrConstFoldImmArg(unsigned ICEArguments, unsigned Idx,
45524553
const CallExpr *E);
45534554
llvm::Value *EmitSystemZBuiltinExpr(unsigned BuiltinID, const CallExpr *E);

0 commit comments

Comments
 (0)