[llvm] r249874 - Teach LoopUnswitch not to perform non-trivial unswitching on loops containing convergent operations.

Owen Anderson via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 9 11:40:20 PDT 2015


Author: resistor
Date: Fri Oct  9 13:40:20 2015
New Revision: 249874

URL: http://llvm.org/viewvc/llvm-project?rev=249874&view=rev
Log:
Teach LoopUnswitch not to perform non-trivial unswitching on loops containing convergent operations.

Doing so could cause the post-unswitching convergent ops to be
control-dependent on the unswitch condition where they were not before.
This check could be refined to allow unswitching where the convergent
operation was already control-dependent on the unswitch condition.

Modified:
    llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
    llvm/trunk/test/Transforms/LoopUnswitch/basictest.ll

Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=249874&r1=249873&r2=249874&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Fri Oct  9 13:40:20 2015
@@ -500,6 +500,20 @@ bool LoopUnswitch::processCurrentLoop()
     return true;
   }
 
+  // Do not unswitch loops containing convergent operations, as we might be
+  // making them control dependent on the unswitch value when they were not
+  // before.
+  // FIXME: This could be refined to only bail if the convergent operation is
+  // not already control-dependent on the unswitch value.
+  for (const auto BB : currentLoop->blocks()) {
+    for (const auto &I : *BB) {
+      const auto CI = dyn_cast<CallInst>(&I);
+      if (!CI) continue;
+      if (CI->isConvergent())
+        return false;
+    }
+  }
+
   // Do not do non-trivial unswitch while optimizing for size.
   // FIXME: Use Function::optForSize().
   if (OptimizeForSize ||

Modified: llvm/trunk/test/Transforms/LoopUnswitch/basictest.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopUnswitch/basictest.ll?rev=249874&r1=249873&r2=249874&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LoopUnswitch/basictest.ll (original)
+++ llvm/trunk/test/Transforms/LoopUnswitch/basictest.ll Fri Oct  9 13:40:20 2015
@@ -64,5 +64,44 @@ loop_exit:
 ; CHECK: }
 }
 
+; This simple test would normally unswitch, but should be inhibited by the presence of
+; the convergent call that is not control-dependent on the unswitch condition.
+
+; CHECK-LABEL: @test3(
+define i32 @test3(i32* %var) {
+  %mem = alloca i32
+  store i32 2, i32* %mem
+  %c = load i32, i32* %mem
+
+  br label %loop_begin
+
+loop_begin:
+
+  %var_val = load i32, i32* %var
+
+; CHECK: call void @conv()
+; CHECK-NOT: call void @conv()
+  call void @conv() convergent
+
+  switch i32 %c, label %default [
+      i32 1, label %inc
+      i32 2, label %dec
+  ]
+
+inc:
+  call void @incf() noreturn nounwind
+  br label %loop_begin
+dec:
+  call void @decf() noreturn nounwind
+  br label %loop_begin
+default:
+  br label %loop_exit
+loop_exit:
+  ret i32 0
+; CHECK: }
+}
+
+
 declare void @incf() noreturn
 declare void @decf() noreturn
+declare void @conv() convergent




More information about the llvm-commits mailing list