瀏覽代碼

Handle incoming values not in VarMap (constants) in DxilLoopUnroll (#2012)

Tex Riddell 6 年之前
父節點
當前提交
5d0511a4a6

+ 4 - 1
lib/Transforms/Scalar/DxilLoopUnroll.cpp

@@ -901,7 +901,10 @@ bool DxilLoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
       // Replace the phi nodes with the value defined INSIDE the previous iteration.
       for (PHINode *PN : PHIs) {
         PHINode *ClonedPN = cast<PHINode>(CurIteration.VarMap[PN]);
-        Value *ReplacementVal = PrevIteration->VarMap[PN->getIncomingValueForBlock(Latch)];
+        Value *ReplacementVal = PN->getIncomingValueForBlock(Latch);
+        auto itRep = PrevIteration->VarMap.find(ReplacementVal);
+        if (itRep != PrevIteration->VarMap.end())
+          ReplacementVal = itRep->second;
         ClonedPN->replaceAllUsesWith(ReplacementVal);
         ClonedPN->eraseFromParent();
         CurIteration.VarMap[PN] = ReplacementVal;

+ 43 - 0
tools/clang/test/CodeGenHLSL/quick-test/unroll-incoming-phi-const.hlsl

@@ -0,0 +1,43 @@
+// RUN: %dxc -E main -T cs_6_0 -HV 2016 %s | FileCheck %s
+
+// Make sure we still produced second loop, and unrolled outer and inner loops,
+// producing two stores, and no more.
+
+// CHECK: void @main()
+// CHECK-NOT: call void @dx.op.bufferStore.i32(i32 69
+// CHECK: phi i32
+
+// CHECK: call void @dx.op.bufferStore.i32(i32 69
+// CHECK: call void @dx.op.bufferStore.i32(i32 69
+// CHECK-NOT: call void @dx.op.bufferStore.i32(i32 69
+
+// CHECK: !llvm.loop
+// CHECK-NOT: call void @dx.op.bufferStore.i32(i32 69
+// CHECK: ret void
+
+struct Foo {
+  bool b;
+};
+
+RWStructuredBuffer<Foo> sb;
+
+[numthreads(1,1,1)]
+void main() {
+  Foo foo;
+  bool b = true;
+
+  [unroll]
+  for (int i = 2; i >= 0; i--) {
+    foo.b = b;
+    [loop]
+    for (int j = 0; j < i + 1; j++) {
+      [unroll]
+      for (int k = 0; k < 2; k++) {
+        if (foo.b) {
+          sb[0] = foo;
+        }
+      }
+    }
+    b = false;
+  }
+}