Browse Source

Fix AV from DxBreak adding branch to null location (unreachable) (#4446)

CodeGen for unreachable break would normally skip generation, but DxBreak
mechanism would insert conditional branch still.  Unreachable location
means the builder has no insertion point.  This led to null preds for
blocks, and an AV in SimplifyCFG.

Checking CFG.HaveInsertPoint() is the mechanism used elsewhere to skip
CodeGen in unreachable locations, so this is added to EmitHLSLCondBreak.
Tex Riddell 3 years ago
parent
commit
733740f100

+ 4 - 0
tools/clang/lib/CodeGen/CGHLSLMS.cpp

@@ -4823,6 +4823,10 @@ void CGMSHLSLRuntime::EmitHLSLDiscard(CodeGenFunction &CGF) {
 // If the block uses values that are wave-sensitive, it needs to stay in the loop to prevent optimizations
 // that might produce incorrect results by ignoring the volatile aspect of wave operation results.
 BranchInst *CGMSHLSLRuntime::EmitHLSLCondBreak(CodeGenFunction &CGF, Function *F, BasicBlock *DestBB, BasicBlock *AltBB) {
+  // Skip if unreachable
+  if (!CGF.HaveInsertPoint())
+    return nullptr;
+
   // If not a wave-enabled stage, we can keep everything unconditional as before
   if (!m_pHLModule->GetShaderModel()->IsPS() && !m_pHLModule->GetShaderModel()->IsCS() &&
       !m_pHLModule->GetShaderModel()->IsLib()) {

+ 15 - 0
tools/clang/test/HLSLFileCheck/hlsl/control_flow/unreachable-break.hlsl

@@ -0,0 +1,15 @@
+// RUN: %dxc /T ps_6_5 -fcgl %s | FileCheck %s
+
+// CHECK-NOT: null operand
+// CHECK: define void @main()
+// CHECK: ret void
+
+void main() {
+  while (true) {
+    if (false) {
+    } else {
+      break;
+    }
+    break;
+  }
+}