소스 검색

Fixed a bug where max unroll iteration attempt is cached. (#2291)

Adam Yang 6 년 전
부모
커밋
5ac1b30c2b
2개의 변경된 파일50개의 추가작업 그리고 4개의 파일을 삭제
  1. 5 4
      lib/Transforms/Scalar/DxilLoopUnroll.cpp
  2. 45 0
      tools/clang/test/CodeGenHLSL/batch/unroll/max_iteration_cache.hlsl

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

@@ -110,7 +110,7 @@ public:
   static char ID;
 
   std::unordered_set<Function *> CleanedUpAlloca;
-  unsigned MaxIterationAttempt = 0;
+  const unsigned MaxIterationAttempt;
 
   DxilLoopUnroll(unsigned MaxIterationAttempt = 1024) :
     LoopPass(ID),
@@ -849,16 +849,17 @@ bool DxilLoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
   SmallVector<std::unique_ptr<LoopIteration>, 16> Iterations; // List of cloned iterations
   bool Succeeded = false;
 
+  unsigned MaxAttempt = this->MaxIterationAttempt;
   // If we were able to figure out the definitive trip count,
   // just unroll that many times.
   if (HasTripCount) {
-    this->MaxIterationAttempt = TripCount;
+    MaxAttempt = TripCount;
   }
   else if (HasExplicitLoopCount) {
-    this->MaxIterationAttempt = ExplicitUnrollCount;
+    MaxAttempt = ExplicitUnrollCount;
   }
 
-  for (unsigned IterationI = 0; IterationI < this->MaxIterationAttempt; IterationI++) {
+  for (unsigned IterationI = 0; IterationI < MaxAttempt; IterationI++) {
 
     LoopIteration *PrevIteration = nullptr;
     if (Iterations.size())

+ 45 - 0
tools/clang/test/CodeGenHLSL/batch/unroll/max_iteration_cache.hlsl

@@ -0,0 +1,45 @@
+// RUN: %dxc -Od -E main -T ps_6_0 %s /E main_ps | FileCheck %s
+
+// Regression test for bug #2269
+// The max iteration attempt for loop unroll was initialized once but modified
+// by each loop pass run if an explicit loop bound/trip count is available.  If
+// a loop was unrolled first, the max trip count would be cached; a subsequent
+// unroll that needs iterative unrolling would end up with a max attempt count
+// bound with a (potentially too low) number from an earlier unroll.
+
+// CHECK: @main_ps
+
+#define MM 2
+#define KK 3
+#define NN 1    // change from 1 to 2 and no errors
+
+float c1()
+{
+    float a = 1.f;
+    
+    [unroll]
+    for( uint i = 0 ; i < MM && a > 1e-4; ++i )
+    //for( uint i = 0 ; i < MM;  ++i )          // uncomment this -> no errors
+    {
+        float b = 0.01;     // comment this out -> no errors
+        a *= 1.0f - b;
+    }
+    return 0;
+}
+
+float c3()
+{
+    [unroll] for (int i = 0; i < NN; ++i)         // comment this out -> no errors
+    {
+        [unroll] for (int j = 0; j < (KK - 1); ++j)     // comment this out -> no errors
+        {
+        }
+    }
+    
+	return 0;
+}
+
+float main_ps() : SV_Target
+{
+    return c1() * c3();
+}