Skip to content

Commit 5bf6f77

Browse files
[DXIL] Avoid infinite loop / stack overflow on invalid instruction (microsoft#7048)
The simplify instruction pass has a function called `findScalarElement`. This function will possibly recurse infinitely into the first operand of the instruction that it is passed. If this instruction, for example, is `%2 = insertelement <2 x i32> %2, i32 %sub, i32 0` Then the pass will recurse into the first operand of the insertelement instruction, which is the same insertelement instruction, and so on. This PR prevents infinite recursion and stack overflow by bailing out of the function early if there is a detection of the same value in the first operand. Fixes microsoft#7034 --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 905add5 commit 5bf6f77

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

lib/Analysis/VectorUtils2.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ llvm::Value *llvm::findScalarElement(llvm::Value *V, unsigned EltNo) {
4242
if (EltNo == IIElt)
4343
return III->getOperand(1);
4444

45+
// Guard against infinite loop on malformed, unreachable IR.
46+
if (III == III->getOperand(0))
47+
return nullptr;
48+
4549
// Otherwise, the insertelement doesn't modify the value, recurse on its
4650
// vector input.
4751
return findScalarElement(III->getOperand(0), EltNo);
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
; RUN: opt -simplify-inst -S < %s | FileCheck %s
2+
3+
%"class.Texture3D<unsigned int>" = type { i32, %"class.Texture3D<unsigned int>::mips_type" }
4+
%"class.Texture3D<unsigned int>::mips_type" = type { i32 }
5+
%dx.types.Handle = type { i8* }
6+
%dx.types.ResourceProperties = type { i32, i32 }
7+
8+
@"\01?t1@@3V?$Texture3D@I@@A" = external global %"class.Texture3D<unsigned int>", align 4
9+
10+
; Function Attrs: nounwind
11+
define void @main(<2 x i32> %dtid, i32 %laneID) #0 {
12+
"\01?f1@@s1@@U1@@Z.exit":
13+
br label %if.end.13
14+
15+
while.cond.6.preheader: ; No predecessors!
16+
; CHECK: %0 = extractelement <2 x i32> %1, i32 1
17+
%0 = extractelement <2 x i32> %2, i32 1
18+
%cmp7.14 = icmp ne i32 %0, 0
19+
br i1 %cmp7.14, label %while.body, label %if.end.13
20+
21+
while.body: ; preds = %while.cond.6.preheader
22+
%1 = extractelement <2 x i32> %2, i32 0
23+
; CHECK: %sub = sub i32 %sub, 1
24+
; CHECK: %1 = insertelement <2 x i32> %1, i32 %sub, i32 0
25+
%sub = sub i32 %1, 1
26+
%2 = insertelement <2 x i32> %2, i32 %sub, i32 0
27+
br label %if.end.13
28+
29+
if.end.13: ; preds = %while.body, %while.cond.6.preheader, %"\01?f1@@s1@@U1@@Z.exit"
30+
ret void
31+
}
32+
33+
; Function Attrs: nounwind
34+
declare void @llvm.lifetime.start(i64, i8* nocapture) #0
35+
36+
; Function Attrs: nounwind
37+
declare void @llvm.lifetime.end(i64, i8* nocapture) #0
38+
39+
; Function Attrs: nounwind readnone
40+
declare i1 @"dx.hl.op.rn.i1 (i32, i1)"(i32, i1) #1
41+
42+
; Function Attrs: nounwind readonly
43+
declare i32 @"dx.hl.op.ro.i32 (i32, %dx.types.Handle, <4 x i32>)"(i32, %dx.types.Handle, <4 x i32>) #2
44+
45+
; Function Attrs: nounwind readnone
46+
declare %dx.types.Handle @"dx.hl.createhandle..%dx.types.Handle (i32, %\22class.Texture3D<unsigned int>\22)"(i32, %"class.Texture3D<unsigned int>") #1
47+
48+
; Function Attrs: nounwind readnone
49+
declare %dx.types.Handle @"dx.hl.annotatehandle..%dx.types.Handle (i32, %dx.types.Handle, %dx.types.ResourceProperties, %\22class.Texture3D<unsigned int>\22)"(i32, %dx.types.Handle, %dx.types.ResourceProperties, %"class.Texture3D<unsigned int>") #1

0 commit comments

Comments
 (0)