Skip to content

Commit 5e9dd88

Browse files
authored
[DirectX] remove string function attribute DXIL not allowed (llvm#90778)
Remove string function attribute other than "waveops-include-helper-lanes" and "fp32-denorm-mode". Move DXILPrepareModulePass after DXILTranslateMetadataPass since DXILTranslateMetadataPass needs to use attribute like hlsl.numthreads. Fixes llvm#90773
1 parent dad1109 commit 5e9dd88

File tree

7 files changed

+86
-7
lines changed

7 files changed

+86
-7
lines changed

llvm/lib/Target/DirectX/DXILMetadata.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,15 @@ void ValidatorVersionMD::update(VersionTuple ValidatorVer) {
4040

4141
bool ValidatorVersionMD::isEmpty() { return Entry->getNumOperands() == 0; }
4242

43+
VersionTuple ValidatorVersionMD::getAsVersionTuple() {
44+
if (isEmpty())
45+
return VersionTuple(1, 0);
46+
auto *ValVerMD = cast<MDNode>(Entry->getOperand(0));
47+
auto *MajorMD = mdconst::extract<ConstantInt>(ValVerMD->getOperand(0));
48+
auto *MinorMD = mdconst::extract<ConstantInt>(ValVerMD->getOperand(1));
49+
return VersionTuple(MajorMD->getZExtValue(), MinorMD->getZExtValue());
50+
}
51+
4352
static StringRef getShortShaderStage(Triple::EnvironmentType Env) {
4453
switch (Env) {
4554
case Triple::Pixel:

llvm/lib/Target/DirectX/DXILMetadata.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class ValidatorVersionMD {
3030
void update(VersionTuple ValidatorVer);
3131

3232
bool isEmpty();
33+
VersionTuple getAsVersionTuple();
3334
};
3435

3536
void createShaderModelMD(Module &M);

llvm/lib/Target/DirectX/DXILPrepare.cpp

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,14 @@
1111
/// Language (DXIL).
1212
//===----------------------------------------------------------------------===//
1313

14+
#include "DXILMetadata.h"
15+
#include "DXILResourceAnalysis.h"
16+
#include "DXILShaderFlags.h"
1417
#include "DirectX.h"
1518
#include "DirectXIRPasses/PointerTypeAnalysis.h"
1619
#include "llvm/ADT/STLExtras.h"
1720
#include "llvm/ADT/SmallVector.h"
21+
#include "llvm/ADT/StringSet.h"
1822
#include "llvm/CodeGen/Passes.h"
1923
#include "llvm/IR/AttributeMask.h"
2024
#include "llvm/IR/IRBuilder.h"
@@ -23,6 +27,7 @@
2327
#include "llvm/InitializePasses.h"
2428
#include "llvm/Pass.h"
2529
#include "llvm/Support/Compiler.h"
30+
#include "llvm/Support/VersionTuple.h"
2631

2732
#define DEBUG_TYPE "dxil-prepare"
2833

@@ -80,6 +85,37 @@ constexpr bool isValidForDXIL(Attribute::AttrKind Attr) {
8085
Attr);
8186
}
8287

88+
static void collectDeadStringAttrs(AttributeMask &DeadAttrs, AttributeSet &&AS,
89+
const StringSet<> &LiveKeys,
90+
bool AllowExperimental) {
91+
for (auto &Attr : AS) {
92+
if (!Attr.isStringAttribute())
93+
continue;
94+
StringRef Key = Attr.getKindAsString();
95+
if (LiveKeys.contains(Key))
96+
continue;
97+
if (AllowExperimental && Key.starts_with("exp-"))
98+
continue;
99+
DeadAttrs.addAttribute(Key);
100+
}
101+
}
102+
103+
static void removeStringFunctionAttributes(Function &F,
104+
bool AllowExperimental) {
105+
AttributeList Attrs = F.getAttributes();
106+
const StringSet<> LiveKeys = {"waveops-include-helper-lanes",
107+
"fp32-denorm-mode"};
108+
// Collect DeadKeys in FnAttrs.
109+
AttributeMask DeadAttrs;
110+
collectDeadStringAttrs(DeadAttrs, Attrs.getFnAttrs(), LiveKeys,
111+
AllowExperimental);
112+
collectDeadStringAttrs(DeadAttrs, Attrs.getRetAttrs(), LiveKeys,
113+
AllowExperimental);
114+
115+
F.removeFnAttrs(DeadAttrs);
116+
F.removeRetAttrs(DeadAttrs);
117+
}
118+
83119
class DXILPrepareModule : public ModulePass {
84120

85121
static Value *maybeGenerateBitcast(IRBuilder<> &Builder,
@@ -110,9 +146,18 @@ class DXILPrepareModule : public ModulePass {
110146
if (!isValidForDXIL(I))
111147
AttrMask.addAttribute(I);
112148
}
149+
150+
dxil::ValidatorVersionMD ValVerMD(M);
151+
VersionTuple ValVer = ValVerMD.getAsVersionTuple();
152+
bool SkipValidation = ValVer.getMajor() == 0 && ValVer.getMinor() == 0;
153+
113154
for (auto &F : M.functions()) {
114155
F.removeFnAttrs(AttrMask);
115156
F.removeRetAttrs(AttrMask);
157+
// Only remove string attributes if we are not skipping validation.
158+
// This will reserve the experimental attributes when validation version
159+
// is 0.0 for experiment mode.
160+
removeStringFunctionAttributes(F, SkipValidation);
116161
for (size_t Idx = 0, End = F.arg_size(); Idx < End; ++Idx)
117162
F.removeParamAttrs(Idx, AttrMask);
118163

@@ -172,7 +217,10 @@ class DXILPrepareModule : public ModulePass {
172217
}
173218

174219
DXILPrepareModule() : ModulePass(ID) {}
175-
220+
void getAnalysisUsage(AnalysisUsage &AU) const override {
221+
AU.addPreserved<ShaderFlagsAnalysisWrapper>();
222+
AU.addPreserved<DXILResourceWrapper>();
223+
}
176224
static char ID; // Pass identification.
177225
};
178226
char DXILPrepareModule::ID = 0;

llvm/lib/Target/DirectX/DirectXTargetMachine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ class DirectXPassConfig : public TargetPassConfig {
7979
void addCodeGenPrepare() override {
8080
addPass(createDXILIntrinsicExpansionLegacyPass());
8181
addPass(createDXILOpLoweringLegacyPass());
82-
addPass(createDXILPrepareModulePass());
8382
addPass(createDXILTranslateMetadataPass());
83+
addPass(createDXILPrepareModulePass());
8484
}
8585
};
8686

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
; RUN: opt -S -dxil-prepare %s | FileCheck %s
2+
3+
target triple = "dxil-pc-shadermodel6.6-compute"
4+
5+
define void @entry() #0 {
6+
entry:
7+
ret void
8+
}
9+
10+
; Make sure experimental attribute is left when validation version is 0.0.
11+
; CHECK:attributes #0 = { noinline nounwind "exp-shader"="cs" }
12+
attributes #0 = { noinline nounwind "exp-shader"="cs" "hlsl.numthreads"="1,2,1" "hlsl.shader"="compute" }
13+
14+
!dx.valver = !{!0}
15+
16+
!0 = !{i32 0, i32 0}

llvm/test/CodeGen/DirectX/Metadata/shaderModel-cs.ll

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s
2+
; RUN: opt -S -dxil-prepare %s | FileCheck %s --check-prefix=REMOVE_EXTRA_ATTRIBUTE
3+
24
target triple = "dxil-pc-shadermodel6.6-compute"
35

46
; CHECK: !dx.shaderModel = !{![[SM:[0-9]+]]}
@@ -9,4 +11,7 @@ entry:
911
ret void
1012
}
1113

12-
attributes #0 = { noinline nounwind "hlsl.numthreads"="1,2,1" "hlsl.shader"="compute" }
14+
; Make sure extra attribute like hlsl.numthreads are removed.
15+
; And experimental attribute is removed when validator version is not 0.0.
16+
; REMOVE_EXTRA_ATTRIBUTE:attributes #0 = { noinline nounwind }
17+
attributes #0 = { noinline nounwind "exp-shader"="cs" "hlsl.numthreads"="1,2,1" "hlsl.shader"="compute" }

llvm/test/tools/dxil-dis/attribute-filter.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ define float @fma2(float %0, float %1, float %2) #1 {
1919
ret float %5
2020
}
2121

22-
; CHECK: attributes #0 = { nounwind readnone "disable-tail-calls"="false" }
23-
attributes #0 = { norecurse nounwind readnone willreturn "disable-tail-calls"="false" }
22+
; CHECK: attributes #0 = { nounwind readnone "fp32-denorm-mode"="any" "waveops-include-helper-lanes" }
23+
attributes #0 = { norecurse nounwind readnone willreturn "disable-tail-calls"="false" "waveops-include-helper-lanes" "fp32-denorm-mode"="any" }
2424

25-
; CHECK: attributes #1 = { readnone "disable-tail-calls"="false" }
26-
attributes #1 = { norecurse memory(none) willreturn "disable-tail-calls"="false" }
25+
; CHECK: attributes #1 = { readnone "fp32-denorm-mode"="ftz" "waveops-include-helper-lanes" }
26+
attributes #1 = { norecurse memory(none) willreturn "disable-tail-calls"="false" "waveops-include-helper-lanes" "fp32-denorm-mode"="ftz" }

0 commit comments

Comments
 (0)