mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
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. llvm-svn: 249874
This commit is contained in:
parent
57bd7dc824
commit
f8e3a19510
@ -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 ||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user