Skip to content

Commit 896b3ad

Browse files
committed
[NFC][DXIL] add ability to alias to an intrinsic
- allows an intrinsic to be aliased for another one and provide additional arguments when being replaced
1 parent 6d13cc9 commit 896b3ad

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

llvm/lib/Target/DirectX/DXIL.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,9 @@ class DXILOp<int opcode, DXILOpClass opclass> {
321321

322322
// Versioned attributes of operation
323323
list<Attributes> attributes = [];
324+
325+
// List of valid aliases
326+
list<Intrinsic> aliases = [];
324327
}
325328

326329
// Concrete definitions of DXIL Operations

llvm/lib/Target/DirectX/DXILOpLowering.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,19 @@ static bool isVectorArgExpansion(Function &F) {
4040
return false;
4141
}
4242

43+
static SmallVector<Value *> getAliasArgs(Function &F, IRBuilder<> &Builder) {
44+
switch (F.getIntrinsicID()) {
45+
case Intrinsic::dx_wave_active_sum:
46+
return getWaveActiveOpArgs<0, true>(F, Builder);
47+
case Intrinsic::dx_wave_active_usum:
48+
return getWaveActiveOpArgs<0, false>(F, Builder);
49+
default:
50+
break;
51+
}
52+
SmallVector<Value *, 0> Args;
53+
return Args;
54+
}
55+
4356
static SmallVector<Value *> populateOperands(Value *Arg, IRBuilder<> &Builder) {
4457
SmallVector<Value *> ExtractedElements;
4558
auto *VecArg = dyn_cast<FixedVectorType>(Arg->getType());
@@ -106,7 +119,9 @@ class OpLowerer {
106119
}
107120

108121
[[nodiscard]]
109-
bool replaceFunctionWithOp(Function &F, dxil::OpCode DXILOp) {
122+
bool replaceFunctionWithOp(
123+
Function &F, dxil::OpCode DXILOp,
124+
std::optional<SmallVector<Value *>> AliasArgs = std::nullopt) {
110125
bool IsVectorArgExpansion = isVectorArgExpansion(F);
111126
return replaceFunction(F, [&](CallInst *CI) -> Error {
112127
SmallVector<Value *> Args;
@@ -117,6 +132,11 @@ class OpLowerer {
117132
} else
118133
Args.append(CI->arg_begin(), CI->arg_end());
119134

135+
// Append any given alias arguments
136+
if (AliasArgs) {
137+
Args.append(AliasArgs->begin(), AliasArgs->end());
138+
}
139+
120140
Expected<CallInst *> OpCall =
121141
OpBuilder.tryCreateOp(DXILOp, Args, CI->getName(), F.getReturnType());
122142
if (Error E = OpCall.takeError())
@@ -476,6 +496,13 @@ class OpLowerer {
476496
case Intrin: \
477497
HasErrors |= replaceFunctionWithOp(F, OpCode); \
478498
break;
499+
#include "DXILOperation.inc"
500+
#define DXIL_OP_INTRINSIC_ALIAS(OpCode, Intrin) \
501+
case Intrin: { \
502+
SmallVector<Value *> AliasArgs = getAliasArgs(F, OpBuilder.getIRB()); \
503+
HasErrors |= replaceFunctionWithOp(F, OpCode, AliasArgs); \
504+
break; \
505+
}
479506
#include "DXILOperation.inc"
480507
case Intrinsic::dx_handle_fromBinding:
481508
HasErrors |= lowerHandleFromBinding(F);

llvm/utils/TableGen/DXILEmitter.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct DXILOperationDesc {
4545
SmallVector<const Record *> AttrRecs;
4646
StringRef Intrinsic; // The llvm intrinsic map to OpName. Default is "" which
4747
// means no map exists
48+
SmallVector<StringRef> IntrinsicAliases;
4849
SmallVector<StringRef, 4>
4950
ShaderStages; // shader stages to which this applies, empty for all.
5051
int OverloadParamIndex; // Index of parameter with overload type.
@@ -168,6 +169,15 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) {
168169
Intrinsic = DefName.substr(4);
169170
}
170171
}
172+
173+
Recs = R->getValueAsListOfDefs("aliases");
174+
175+
for (const Record *CR : Recs) {
176+
auto DefName = CR->getName();
177+
assert(DefName.starts_with("int_") && "invalid intrinsic name");
178+
// Remove the int_ from intrinsic name.
179+
IntrinsicAliases.push_back(DefName.substr(4));
180+
}
171181
}
172182

173183
/// Return a string representation of OverloadKind enum that maps to
@@ -388,6 +398,26 @@ static void emitDXILIntrinsicMap(ArrayRef<DXILOperationDesc> Ops,
388398
OS << "#endif\n\n";
389399
}
390400

401+
/// Emit map of DXIL operation to LLVM or DirectX intrinsic alias
402+
/// \param A vector of DXIL Ops
403+
/// \param Output stream
404+
static void emitDXILIntrinsicAliasMap(ArrayRef<DXILOperationDesc> Ops,
405+
raw_ostream &OS) {
406+
OS << "#ifdef DXIL_OP_INTRINSIC_ALIAS\n";
407+
OS << "\n";
408+
for (const auto &Op : Ops) {
409+
for (const auto &Alias : Op.IntrinsicAliases) {
410+
if (Alias.empty())
411+
continue;
412+
OS << "DXIL_OP_INTRINSIC_ALIAS(dxil::OpCode::" << Op.OpName
413+
<< ", Intrinsic::" << Alias << ")\n";
414+
}
415+
}
416+
OS << "\n";
417+
OS << "#undef DXIL_OP_INTRINSIC_ALIAS\n";
418+
OS << "#endif\n\n";
419+
}
420+
391421
/// Emit DXIL operation table
392422
/// \param A vector of DXIL Ops
393423
/// \param Output stream
@@ -529,6 +559,7 @@ static void EmitDXILOperation(const RecordKeeper &Records, raw_ostream &OS) {
529559
emitDXILOpParamTypes(Records, OS);
530560
emitDXILOpFunctionTypes(DXILOps, OS);
531561
emitDXILIntrinsicMap(DXILOps, OS);
562+
emitDXILIntrinsicAliasMap(DXILOps, OS);
532563
OS << "#ifdef DXIL_OP_OPERATION_TABLE\n\n";
533564
emitDXILOperationTableDataStructs(Records, OS);
534565
emitDXILOperationTable(DXILOps, OS);

0 commit comments

Comments
 (0)