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

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 9 12:53:42 PDT 2015


Does this need to handle invokes?

Philip

On 10/09/2015 11:40 AM, Owen Anderson via llvm-commits wrote:
> 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
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list