Skip to content

Commit 2f357a9

Browse files
authored
Fix assert due to unreachable discard (microsoft#7289)
When emitting discard in an unreachable code context (e.g. after an infinite loop), DXC would assert (if asserts enabled), or trigger a UBSAN failure because the discard instruction would have no parent. When an infinite loop is emitted during CodeGen, the InsertPt is cleared, thus subsequent discard instructions would be created, but no parent set. We skip emitting discard in this case, which follows the same pattern as is done for EmitIfStmt, and EmitSwitchStmt.
1 parent a13938d commit 2f357a9

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

tools/clang/lib/CodeGen/CGStmt.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,10 @@ void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
525525

526526
// HLSL Change Begins.
527527
void CodeGenFunction::EmitDiscardStmt(const DiscardStmt &S) {
528+
// Skip unreachable discard.
529+
if (!HaveInsertPoint())
530+
return;
531+
528532
CGM.getHLSLRuntime().EmitHLSLDiscard(*this);
529533
}
530534
// HLSL Change Ends.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %dxc /T ps_6_5 -fcgl %s | FileCheck %s
2+
3+
// Compiling this HLSL would trigger an assertion:
4+
// While deleting: void (i32, float)* %dx.hl.op..void (i32, float)
5+
// Use still stuck around after Def is destroyed: call void @"dx.hl.op..void (i32, float)"(i32 120, float -1.000000e+00), !dbg <0x503000001cc8>
6+
// Error: assert(use_empty() && "Uses remain when a value is destroyed!")
7+
// File: <snip>/src/external/DirectXShaderCompiler/lib/IR/Value.cpp(83)
8+
//
9+
// Bug was fixed in CodeGenFunction::EmitDiscardStmt by skipping the emission of
10+
// an unreachable discard.
11+
12+
// CHECK: define void @main()
13+
// CHECK: br label %
14+
// CHECK-NOT: call void @"dx.hl.op..void (i32, float)"
15+
// CHECK: ret void
16+
17+
void main() {
18+
while (true) {
19+
}
20+
discard;
21+
}

0 commit comments

Comments
 (0)