Skip to content

Commit 1d19665

Browse files
authored
Fix crash in scalarrepl-param-hlsl when dynamically indexing a GEP of a constant indexed GEP (microsoft#6670)
When processing global values to determine when to flatten vectors, this pass was only checking the immdiate users of the value for non-dynamic indexing of the vector. But this would fail in the case of a dynamic indexed GEP of a constant indexed GEP (e.g. h[0][a]) because the first level GEP was constant indexed, but not the second. We fix this by checking the full User tree of the value in `hasDynamicVectorIndexing`.
1 parent 8206fbd commit 1d19665

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1645,6 +1645,10 @@ bool hasDynamicVectorIndexing(Value *V) {
16451645
}
16461646
}
16471647
}
1648+
// Also recursively check the uses of this User to find a possible
1649+
// dynamically indexed GEP of this GEP.
1650+
if (hasDynamicVectorIndexing(U))
1651+
return true;
16481652
}
16491653
return false;
16501654
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
; RUN: %dxopt %s -hlsl-passes-resume -scalarrepl-param-hlsl -S | FileCheck %s
2+
3+
; Produced from the following HLSL:
4+
; static int4 g[4] = (int4[4])0;
5+
; static int4 h[4] = (int4[4])0;
6+
;
7+
; [numthreads(1, 1, 1)]
8+
; void main() {
9+
; int a = 0;
10+
; int b = h[0][a];
11+
; h = g;
12+
; }
13+
;
14+
; This was crashing in scalarrepl-param-hlsl because it was attempting to flatten
15+
; global variable 'h' even though it is dynamically indexed. This was not detected
16+
; because the resulting IR was a dynamically indexed GEP of a constant-indexed GEP,
17+
; and the code was only checking the immediate users of 'h':
18+
;
19+
; %1 = getelementptr <4 x i32>, <4 x i32>* getelementptr inbounds ([4 x <4 x i32>], [4 x <4 x i32>]* @h, i32 0, i32 0), i32 0, i32 %0, !dbg !26 ; line:7 col:11
20+
;
21+
; Verify that it does not get flattened
22+
; CHECK: %1 = getelementptr <4 x i32>, <4 x i32>* getelementptr inbounds ([4 x <4 x i32>], [4 x <4 x i32>]* @g, i32 0, i32 0), i32 0, i32 %0
23+
24+
;
25+
; Buffer Definitions:
26+
;
27+
; cbuffer $Globals
28+
; {
29+
;
30+
; [0 x i8] (type annotation not present)
31+
;
32+
; }
33+
;
34+
;
35+
; Resource Bindings:
36+
;
37+
; Name Type Format Dim ID HLSL Bind Count
38+
; ------------------------------ ---------- ------- ----------- ------- -------------- ------
39+
; $Globals cbuffer NA NA CB0 cb4294967295 1
40+
;
41+
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"
42+
target triple = "dxil-ms-dx"
43+
44+
%ConstantBuffer = type opaque
45+
46+
@h = internal global [4 x <4 x i32>] zeroinitializer, align 4
47+
@g = internal global [4 x <4 x i32>] zeroinitializer, align 4
48+
@"$Globals" = external constant %ConstantBuffer
49+
50+
; Function Attrs: nounwind
51+
define void @main() #0 {
52+
entry:
53+
%a = alloca i32, align 4
54+
%b = alloca i32, align 4
55+
store i32 0, i32* %a, align 4, !dbg !17, !tbaa !21 ; line:6 col:7
56+
%0 = load i32, i32* %a, align 4, !dbg !25, !tbaa !21 ; line:7 col:16
57+
%1 = getelementptr <4 x i32>, <4 x i32>* getelementptr inbounds ([4 x <4 x i32>], [4 x <4 x i32>]* @h, i32 0, i32 0), i32 0, i32 %0, !dbg !26 ; line:7 col:11
58+
%2 = load i32, i32* %1, !dbg !26, !tbaa !21 ; line:7 col:11
59+
store i32 %2, i32* %b, align 4, !dbg !27, !tbaa !21 ; line:7 col:7
60+
%3 = bitcast [4 x <4 x i32>]* @h to i8*, !dbg !28 ; line:8 col:7
61+
%4 = bitcast [4 x <4 x i32>]* @g to i8*, !dbg !28 ; line:8 col:7
62+
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* %4, i64 64, i32 1, i1 false), !dbg !28 ; line:8 col:7
63+
ret void, !dbg !29 ; line:9 col:1
64+
}
65+
66+
; Function Attrs: nounwind
67+
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) #0
68+
69+
attributes #0 = { nounwind }
70+
71+
!llvm.module.flags = !{!0}
72+
!pauseresume = !{!1}
73+
!llvm.ident = !{!2}
74+
!dx.version = !{!3}
75+
!dx.valver = !{!4}
76+
!dx.shaderModel = !{!5}
77+
!dx.typeAnnotations = !{!6}
78+
!dx.entryPoints = !{!10}
79+
!dx.fnprops = !{!14}
80+
!dx.options = !{!15, !16}
81+
82+
!0 = !{i32 2, !"Debug Info Version", i32 3}
83+
!1 = !{!"hlsl-hlemit", !"hlsl-hlensure"}
84+
!2 = !{!"dxc(private) 1.8.0.4514 (d9bd2a706-dirty)"}
85+
!3 = !{i32 1, i32 0}
86+
!4 = !{i32 1, i32 8}
87+
!5 = !{!"cs", i32 6, i32 0}
88+
!6 = !{i32 1, void ()* @main, !7}
89+
!7 = !{!8}
90+
!8 = !{i32 1, !9, !9}
91+
!9 = !{}
92+
!10 = !{void ()* @main, !"main", null, !11, null}
93+
!11 = !{null, null, !12, null}
94+
!12 = !{!13}
95+
!13 = !{i32 0, %ConstantBuffer* @"$Globals", !"$Globals", i32 0, i32 -1, i32 1, i32 0, null}
96+
!14 = !{void ()* @main, i32 5, i32 1, i32 1, i32 1}
97+
!15 = !{i32 64}
98+
!16 = !{i32 -1}
99+
!17 = !DILocation(line: 6, column: 7, scope: !18)
100+
!18 = !DISubprogram(name: "main", scope: !19, file: !19, line: 5, type: !20, isLocal: false, isDefinition: true, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false, function: void ()* @main)
101+
!19 = !DIFile(filename: "/mnt/c/Users/amaiorano/Downloads/342428008/standalone_reduced.hlsl", directory: "")
102+
!20 = !DISubroutineType(types: !9)
103+
!21 = !{!22, !22, i64 0}
104+
!22 = !{!"int", !23, i64 0}
105+
!23 = !{!"omnipotent char", !24, i64 0}
106+
!24 = !{!"Simple C/C++ TBAA"}
107+
!25 = !DILocation(line: 7, column: 16, scope: !18)
108+
!26 = !DILocation(line: 7, column: 11, scope: !18)
109+
!27 = !DILocation(line: 7, column: 7, scope: !18)
110+
!28 = !DILocation(line: 8, column: 7, scope: !18)
111+
!29 = !DILocation(line: 9, column: 1, scope: !18)

0 commit comments

Comments
 (0)