Skip to content

Commit 3ac44bc

Browse files
authored
Make DxilRemoveDeadBlocks init DxilModule, fix test (microsoft#5919)
DxilRemoveDeadBlocks assumed it could run with an uninitialized DxilModule, because the test case had been captured from live state without the needed DXIL metadata. DxilRemoveDeadBlocks relies on DxilValueCache, which relies on code in DxilSimplify, which assumes we have a DxilModule if there are dxil ops. Without an initialized DxilModule with the correct low-precision mode, cached ops and types may be wrong. This change: - modifies DxilRemoveDeadBlocks to remove bSkipInit - updates the test to contain the metadata needed to initialize DxilModule
1 parent 7f0662f commit 3ac44bc

File tree

2 files changed

+70
-45
lines changed

2 files changed

+70
-45
lines changed

lib/Transforms/Scalar/DxilRemoveDeadBlocks.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,8 +346,7 @@ static void EnsureDxilModule(Module *M) {
346346
return;
347347
for (Function &F : *M) {
348348
if (OP::IsDxilOpFunc(&F)) {
349-
bool bSkipInit = true; // Metadata is not necessarily valid yet.
350-
M->GetOrCreateDxilModule(bSkipInit);
349+
M->GetOrCreateDxilModule();
351350
break;
352351
}
353352
}

tools/clang/test/HLSLFileCheck/passes/dxil/dxil_remove_dead_pass/delete_constant_dce.ll

Lines changed: 69 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: %opt %s -dxil-remove-dead-blocks -S | FileCheck %s
1+
; RUN: %opt %s -hlsl-passes-resume -dxil-remove-dead-blocks -S | FileCheck %s
22

33
; Run the pass, to make sure that %val.0 is deleted since its only use is multiplied by 0.
44
; %val.0 = phi float [ 1.000000e+00, %if.then ], [ 0.000000e+00, %entry ]
@@ -7,7 +7,6 @@
77
; CHECK: @main
88
; CHECK-NOT: phi float
99

10-
; ModuleID = 'F:\dxc\tools\clang\test\HLSLFileCheck\passes\dxil\dxil_remove_dead_pass\delete_constant_dce.hlsl'
1110
target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
1211
target triple = "dxil-ms-dx"
1312

@@ -32,31 +31,31 @@ declare void @dx.noop() #1
3231
define void @main(float* noalias) #2 {
3332
entry:
3433
%1 = load %cb, %cb* @cb
35-
%cb = call %dx.types.Handle @dx.op.createHandleForLib.cb(i32 160, %cb %1)
36-
%2 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %cb, %dx.types.ResourceProperties { i32 13, i32 4 })
37-
call void @dx.noop(), !dbg !18
38-
call void @llvm.dbg.value(metadata float 0.000000e+00, i64 0, metadata !19, metadata !20), !dbg !18
39-
%3 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %2, i32 0), !dbg !21
40-
%4 = extractvalue %dx.types.CBufRet.f32 %3, 0, !dbg !21
41-
%tobool = fcmp fast une float %4, 0.000000e+00, !dbg !21
42-
br i1 %tobool, label %if.then, label %if.end, !dbg !23
34+
%cb = call %dx.types.Handle @dx.op.createHandleForLib.cb(i32 160, %cb %1) ; CreateHandleForLib(Resource)
35+
%2 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %cb, %dx.types.ResourceProperties { i32 13, i32 4 }) ; AnnotateHandle(res,props) resource: CBuffer
36+
call void @dx.noop(), !dbg !38 ; line:19 col:9
37+
call void @llvm.dbg.value(metadata float 0.000000e+00, i64 0, metadata !39, metadata !40), !dbg !38 ; var:"val" !DIExpression() func:"main"
38+
%3 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %2, i32 0), !dbg !41 ; line:20 col:7 ; CBufferLoadLegacy(handle,regIndex)
39+
%4 = extractvalue %dx.types.CBufRet.f32 %3, 0, !dbg !41 ; line:20 col:7
40+
%tobool = fcmp fast une float %4, 0.000000e+00, !dbg !41 ; line:20 col:7
41+
br i1 %tobool, label %if.then, label %if.end, !dbg !43 ; line:20 col:7
4342

4443
if.then: ; preds = %entry
45-
call void @dx.noop(), !dbg !24
46-
call void @llvm.dbg.value(metadata float 1.000000e+00, i64 0, metadata !19, metadata !20), !dbg !18
47-
br label %if.end, !dbg !25
44+
call void @dx.noop(), !dbg !44 ; line:21 col:9
45+
call void @llvm.dbg.value(metadata float 1.000000e+00, i64 0, metadata !39, metadata !40), !dbg !38 ; var:"val" !DIExpression() func:"main"
46+
br label %if.end, !dbg !45 ; line:21 col:5
4847

4948
if.end: ; preds = %if.then, %entry
5049
%val.0 = phi float [ 1.000000e+00, %if.then ], [ 0.000000e+00, %entry ]
51-
call void @llvm.dbg.value(metadata float %val.0, i64 0, metadata !19, metadata !20), !dbg !18
52-
call void @dx.noop(), !dbg !26
53-
call void @llvm.dbg.value(metadata float 0.000000e+00, i64 0, metadata !27, metadata !20), !dbg !26
54-
%mul = fmul fast float %val.0, 0.000000e+00, !dbg !28
55-
call void @dx.noop(), !dbg !29
56-
call void @llvm.dbg.value(metadata float %mul, i64 0, metadata !30, metadata !20), !dbg !29
57-
call void @dx.noop(), !dbg !31
58-
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %mul), !dbg !31
59-
ret void, !dbg !31
50+
call void @llvm.dbg.value(metadata float %val.0, i64 0, metadata !39, metadata !40), !dbg !38 ; var:"val" !DIExpression() func:"main"
51+
call void @dx.noop(), !dbg !46 ; line:23 col:9
52+
call void @llvm.dbg.value(metadata float 0.000000e+00, i64 0, metadata !47, metadata !40), !dbg !46 ; var:"zero" !DIExpression() func:"main"
53+
%mul = fmul fast float %val.0, 0.000000e+00, !dbg !48 ; line:24 col:19
54+
call void @dx.noop(), !dbg !49 ; line:24 col:9
55+
call void @llvm.dbg.value(metadata float %mul, i64 0, metadata !50, metadata !40), !dbg !49 ; var:"ret" !DIExpression() func:"main"
56+
call void @dx.noop(), !dbg !51 ; line:26 col:3
57+
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %mul), !dbg !51 ; line:26 col:3 ; StoreOutput(outputSigId,rowIndex,colIndex,value)
58+
ret void, !dbg !51 ; line:26 col:3
6059
}
6160

6261
; Function Attrs: nounwind readnone
@@ -87,9 +86,16 @@ attributes #3 = { nounwind readonly }
8786
!dx.source.defines = !{!2}
8887
!dx.source.mainFileName = !{!16}
8988
!dx.source.args = !{!17}
90-
91-
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.7 (tags/RELEASE_370/final)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3, globals: !8)
92-
!1 = !DIFile(filename: "F:\5Cdxc\5Ctools\5Cclang\5Ctest\5CHLSLFileCheck\5Cpasses\5Cdxil\5Cdxil_remove_dead_pass\5Cdelete_constant_dce.hlsl", directory: "")
89+
!dx.version = !{!18}
90+
!dx.valver = !{!19}
91+
!dx.shaderModel = !{!20}
92+
!dx.resources = !{!21}
93+
!dx.typeAnnotations = !{!24, !27}
94+
!dx.entryPoints = !{!33}
95+
!dx.rootSignature = !{!37}
96+
97+
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "dxc(private) 1.7.0.3848 (dxil-op-cache-init, 44ba911a0)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3, globals: !8)
98+
!1 = !DIFile(filename: "delete_constant_dce.hlsl", directory: "")
9399
!2 = !{}
94100
!3 = !{!4}
95101
!4 = !DISubprogram(name: "main", scope: !1, file: !1, line: 18, type: !5, isLocal: false, isDefinition: true, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: false, function: void (float*)* @main)
@@ -102,21 +108,41 @@ attributes #3 = { nounwind readonly }
102108
!11 = !{i32 2, !"Dwarf Version", i32 4}
103109
!12 = !{i32 2, !"Debug Info Version", i32 3}
104110
!13 = !{!"hlsl-dxilemit", !"hlsl-dxilload"}
105-
!14 = !{!"clang version 3.7 (tags/RELEASE_370/final)"}
106-
!15 = !{!"F:\5Cdxc\5Ctools\5Cclang\5Ctest\5CHLSLFileCheck\5Cpasses\5Cdxil\5Cdxil_remove_dead_pass\5Cdelete_constant_dce.hlsl", !"// RUN: %dxc %s -T ps_6_0 -Od | FileCheck %s\0D\0A\0D\0A// This test verifies the fix for a deficiency in RemoveDeadBlocks where:\0D\0A//\0D\0A// - Value 'ret' that can be reduced to constant by DxilValueCache is removed\0D\0A// - It held on uses for a PHI 'val', but 'val' was not removed\0D\0A// - 'val' is not used, but also not DCE'ed until after DeleteDeadRegion is run\0D\0A// - DeleteDeadRegion cannot delete 'if (foo)' because 'val' still exists.\0D\0A\0D\0A// CHECK: @main\0D\0A// CHECK-NOT: phi\0D\0A\0D\0Acbuffer cb : register(b0) {\0D\0A float foo;\0D\0A}\0D\0A\0D\0A[RootSignature(\22\22)]\0D\0Afloat main() : SV_Target {\0D\0A float val = 0;\0D\0A if (foo)\0D\0A val = 1;\0D\0A\0D\0A float zero = 0;\0D\0A float ret = val * zero;\0D\0A\0D\0A return ret;\0D\0A}\0D\0A"}
107-
!16 = !{!"F:\5Cdxc\5Ctools\5Cclang\5Ctest\5CHLSLFileCheck\5Cpasses\5Cdxil\5Cdxil_remove_dead_pass\5Cdelete_constant_dce.hlsl"}
108-
!17 = !{!"-E", !"main", !"-T", !"ps_6_0", !"/Od", !"/Zi", !"-Qembed_debug"}
109-
!18 = !DILocation(line: 19, column: 9, scope: !4)
110-
!19 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "val", scope: !4, file: !1, line: 19, type: !7)
111-
!20 = !DIExpression()
112-
!21 = !DILocation(line: 20, column: 7, scope: !22)
113-
!22 = distinct !DILexicalBlock(scope: !4, file: !1, line: 20, column: 7)
114-
!23 = !DILocation(line: 20, column: 7, scope: !4)
115-
!24 = !DILocation(line: 21, column: 9, scope: !22)
116-
!25 = !DILocation(line: 21, column: 5, scope: !22)
117-
!26 = !DILocation(line: 23, column: 9, scope: !4)
118-
!27 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "zero", scope: !4, file: !1, line: 23, type: !7)
119-
!28 = !DILocation(line: 24, column: 19, scope: !4)
120-
!29 = !DILocation(line: 24, column: 9, scope: !4)
121-
!30 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "ret", scope: !4, file: !1, line: 24, type: !7)
122-
!31 = !DILocation(line: 26, column: 3, scope: !4)
111+
!14 = !{!"dxc(private) 1.7.0.3848 (dxil-op-cache-init, 44ba911a0)"}
112+
!15 = !{!"delete_constant_dce.hlsl", !"// RUN: %dxc %s -T ps_6_0 -Od | FileCheck %s\0D\0A\0D\0A// This test verifies the fix for a deficiency in RemoveDeadBlocks where:\0D\0A//\0D\0A// - Value 'ret' that can be reduced to constant by DxilValueCache is removed\0D\0A// - It held on uses for a PHI 'val', but 'val' was not removed\0D\0A// - 'val' is not used, but also not DCE'ed until after DeleteDeadRegion is run\0D\0A// - DeleteDeadRegion cannot delete 'if (foo)' because 'val' still exists.\0D\0A\0D\0A// CHECK: @main\0D\0A// CHECK-NOT: phi\0D\0A\0D\0Acbuffer cb : register(b0) {\0D\0A float foo;\0D\0A}\0D\0A\0D\0A[RootSignature(\22\22)]\0D\0Afloat main() : SV_Target {\0D\0A float val = 0;\0D\0A if (foo)\0D\0A val = 1;\0D\0A\0D\0A float zero = 0;\0D\0A float ret = val * zero;\0D\0A\0D\0A return ret;\0D\0A}\0D\0A"}
113+
!16 = !{!"delete_constant_dce.hlsl"}
114+
!17 = !{!"-E", !"main", !"-T", !"ps_6_0", !"-fcgl", !"-Od", !"-Zi", !"-Qembed_debug"}
115+
!18 = !{i32 1, i32 0}
116+
!19 = !{i32 1, i32 7}
117+
!20 = !{!"ps", i32 6, i32 0}
118+
!21 = !{null, null, !22, null}
119+
!22 = !{!23}
120+
!23 = !{i32 0, %cb* @cb, !"cb", i32 0, i32 0, i32 1, i32 4, null}
121+
!24 = !{i32 0, %cb undef, !25}
122+
!25 = !{i32 4, !26}
123+
!26 = !{i32 6, !"foo", i32 3, i32 0, i32 7, i32 9}
124+
!27 = !{i32 1, void (float*)* @main, !28}
125+
!28 = !{!29, !30}
126+
!29 = !{i32 0, !2, !2}
127+
!30 = !{i32 1, !31, !32}
128+
!31 = !{i32 4, !"SV_Target", i32 7, i32 9}
129+
!32 = !{i32 0}
130+
!33 = !{void (float*)* @main, !"main", !34, !21, null}
131+
!34 = !{null, !35, null}
132+
!35 = !{!36}
133+
!36 = !{i32 0, !"SV_Target", i8 9, i8 16, !32, i8 0, i32 1, i8 1, i32 0, i8 0, null}
134+
!37 = !{[24 x i8] c"\02\00\00\00\00\00\00\00\18\00\00\00\00\00\00\00\18\00\00\00\00\00\00\00"}
135+
!38 = !DILocation(line: 19, column: 9, scope: !4)
136+
!39 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "val", scope: !4, file: !1, line: 19, type: !7)
137+
!40 = !DIExpression()
138+
!41 = !DILocation(line: 20, column: 7, scope: !42)
139+
!42 = distinct !DILexicalBlock(scope: !4, file: !1, line: 20, column: 7)
140+
!43 = !DILocation(line: 20, column: 7, scope: !4)
141+
!44 = !DILocation(line: 21, column: 9, scope: !42)
142+
!45 = !DILocation(line: 21, column: 5, scope: !42)
143+
!46 = !DILocation(line: 23, column: 9, scope: !4)
144+
!47 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "zero", scope: !4, file: !1, line: 23, type: !7)
145+
!48 = !DILocation(line: 24, column: 19, scope: !4)
146+
!49 = !DILocation(line: 24, column: 9, scope: !4)
147+
!50 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "ret", scope: !4, file: !1, line: 24, type: !7)
148+
!51 = !DILocation(line: 26, column: 3, scope: !4)

0 commit comments

Comments
 (0)