Ver Fonte

Correct break followed by additional statements (#2997)

Anything after a break should be ignored. An unconditional break
followed by additional statements was producing a basic block with a
branch that was not the final instruction.

By clearing the builder insertion point, all subsequent instructions in
the compound statement are completely ignored, making the branch the
final instruction as it should be.

Includes a simple test that verifies that no crash occurs and the
subsequent instructions are excluded.
Greg Roth há 5 anos atrás
pai
commit
bf4b75abb1

+ 1 - 0
tools/clang/lib/CodeGen/CGStmt.cpp

@@ -1207,6 +1207,7 @@ void CodeGenFunction::EmitBreakStmt(const BreakStmt &S) {
     assert(EHStack.getInnermostActiveNormalCleanup() == EHStack.stable_end() && "HLSL Shouldn't need cleanups");
     assert(EHStack.getInnermostActiveNormalCleanup() == EHStack.stable_end() && "HLSL Shouldn't need cleanups");
     CGM.getHLSLRuntime().EmitHLSLCondBreak(*this, CurFn, BreakContinueStack.back().BreakBlock.getBlock(),
     CGM.getHLSLRuntime().EmitHLSLCondBreak(*this, CurFn, BreakContinueStack.back().BreakBlock.getBlock(),
                                            BreakContinueStack.back().ContinueBlock.getBlock());
                                            BreakContinueStack.back().ContinueBlock.getBlock());
+    Builder.ClearInsertionPoint();
   } else
   } else
   // HLSL Change End - incorporate unconditional branch blocks into loops
   // HLSL Change End - incorporate unconditional branch blocks into loops
   EmitBranchThroughCleanup(BreakContinueStack.back().BreakBlock);
   EmitBranchThroughCleanup(BreakContinueStack.back().BreakBlock);

+ 19 - 0
tools/clang/test/HLSLFileCheck/hlsl/control_flow/loops/midbreak.hlsl

@@ -0,0 +1,19 @@
+// RUN: %dxc -T ps_6_0 %s | FileCheck %s
+
+// A simple test to ensure that an unconditional break
+// followed by additional statements is handled correctly.
+
+// make sure the cos is included and the dot isn't
+//CHECK: dx.op.unary
+//CHECK-NOT: dx.op.dot
+
+float4 main(float4 a:A, int b:B) :SV_Target
+{
+  while(b) {
+    b--;
+    a += cos(a);
+    break;
+    a += dot(a,a);
+  }
+  return a;
+}