Prechádzať zdrojové kódy

Removing child loops of successfully unrolled loops from queue (#2008)

Adam Yang 6 rokov pred
rodič
commit
4cb5e567aa

+ 9 - 2
lib/Transforms/Scalar/DxilLoopUnroll.cpp

@@ -667,7 +667,13 @@ static bool Mem2Reg(Function &F, DominatorTree &DT, AssumptionCache &AC) {
   return Changed;
 }
 
-
+static void RecursivelyRemoveLoopFromQueue(LPPassManager &LPM, Loop *L) {
+  // Must remove all child loops first.
+  for (Loop *ChildLoop : *L) {
+    RecursivelyRemoveLoopFromQueue(LPM, ChildLoop);
+  }
+  LPM.deleteLoopFromQueue(L);
+}
 
 bool DxilLoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
 
@@ -1001,7 +1007,8 @@ bool DxilLoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
     for (BasicBlock *BB : ToBeCloned)
       LI->removeBlock(BB);
 
-    LPM.deleteLoopFromQueue(L);
+    // Remove loop and all child loops from queue.
+    RecursivelyRemoveLoopFromQueue(LPM, L);
 
     // Remove dead blocks.
     for (BasicBlock *BB : ToBeCloned)

+ 14 - 0
tools/clang/test/CodeGenHLSL/unroll/intact_child_loops.hlsl

@@ -0,0 +1,14 @@
+// RUN: %dxc -Od -E main -T ps_6_0 %s | FileCheck %s
+// CHECK: @main
+
+// Test case for when an unrolled loop has a child loop that's not unrolled.
+// regression test for GitHub #2006
+
+void main()
+{
+  for (int i = 0; i < 1; i++)
+    [unroll]
+    for (int j = 0; j < 1; j++)
+      for (int k = 0; k < 1; k++)
+        ;
+}

+ 10 - 7
tools/clang/test/CodeGenHLSL/unroll/nested3.hlsl

@@ -46,15 +46,18 @@ float main(float3 a : A, float3 b : B) : SV_Target {
 
   float ret = 0;
   [unroll]
-  for (uint i = 0; i < 4; i++) {
+  for (uint l = 0; l < 1; l++) {
+    [unroll]
+    for (uint i = 0; i < 4; i++) {
 
-    [loop]
-    for (uint j = 0; j < 4; j++) {
-      ret += routine(j);
-      ret++;
-    }
+      [loop]
+      for (uint j = 0; j < 4; j++) {
+        ret += routine(j);
+        ret++;
+      }
 
-    ret--;
+      ret--;
+    }
   }
 
   return ret;