mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-02 11:16:06 +00:00

The old LoopUnswitch pass unswitched selects, but the changes were never ported to the new SimpleLoopUnswitch. We unswitch by turning: ``` S = select %cond, %a, %b ``` into: ``` head: br %cond, label %then, label %tail then: br label %tail tail: S = phi [ %a, %then ], [ %b, %head ] ``` Unswitch selects are always nontrivial, since the successors do not exit the loop and the loop body always needs to be cloned. Unswitch selects always need to freeze the conditional if the conditional could be poison or undef. Selects don't propagate poison/undef, and branches on poison/undef causes UB. Reland 1 - Fix the insertion of freeze instructions. The original implementation inserts a dead freeze instruction that is not used by the unswitched branch. Reland 2 - Include https://reviews.llvm.org/D149560 in the same patch, which was originally reverted along with this patch. The patch prevents unswitching of selects with a vector conditional. This could have been caught in SimpleLoopUnswitch/crash.ll if it included tests for nontrivial unswitching. This reland also adds a run for the test file with nontrivial unswitching. Reviewed By: nikic, kachkov98, vitalybuka Differential Revision: https://reviews.llvm.org/D138526
68 lines
2.5 KiB
LLVM
68 lines
2.5 KiB
LLVM
; RUN: opt < %s -passes=simple-loop-unswitch -verify-memoryssa -disable-output
|
|
; RUN: opt < %s -passes='simple-loop-unswitch<nontrivial>' -verify-memoryssa -disable-output
|
|
|
|
define void @test1(ptr %S2) {
|
|
entry:
|
|
br i1 false, label %list_Length.exit, label %cond_true.i
|
|
cond_true.i: ; preds = %entry
|
|
ret void
|
|
list_Length.exit: ; preds = %entry
|
|
br i1 false, label %list_Length.exit9, label %cond_true.i5
|
|
cond_true.i5: ; preds = %list_Length.exit
|
|
ret void
|
|
list_Length.exit9: ; preds = %list_Length.exit
|
|
br i1 false, label %bb78, label %return
|
|
bb44: ; preds = %bb78, %cond_next68
|
|
br i1 %tmp49.not, label %bb62, label %bb62.loopexit
|
|
bb62.loopexit: ; preds = %bb44
|
|
br label %bb62
|
|
bb62: ; preds = %bb62.loopexit, %bb44
|
|
br i1 false, label %return.loopexit, label %cond_next68
|
|
cond_next68: ; preds = %bb62
|
|
br i1 false, label %return.loopexit, label %bb44
|
|
bb78: ; preds = %list_Length.exit9
|
|
%tmp49.not = icmp eq ptr %S2, null ; <i1> [#uses=1]
|
|
br label %bb44
|
|
return.loopexit: ; preds = %cond_next68, %bb62
|
|
%retval.0.ph = phi i32 [ 1, %cond_next68 ], [ 0, %bb62 ] ; <i32> [#uses=1]
|
|
br label %return
|
|
return: ; preds = %return.loopexit, %list_Length.exit9
|
|
%retval.0 = phi i32 [ 0, %list_Length.exit9 ], [ %retval.0.ph, %return.loopexit ] ; <i32> [#uses=0]
|
|
ret void
|
|
}
|
|
|
|
define void @test2() nounwind {
|
|
entry:
|
|
br label %bb.nph
|
|
|
|
bb.nph: ; preds = %entry
|
|
%and.i13521 = and <4 x i1> undef, undef ; <<4 x i1>> [#uses=1]
|
|
br label %for.body
|
|
|
|
for.body: ; preds = %for.body, %bb.nph
|
|
%or.i = select <4 x i1> %and.i13521, <4 x i32> undef, <4 x i32> undef ; <<4 x i32>> [#uses=0]
|
|
br i1 false, label %for.body, label %for.end
|
|
|
|
for.end: ; preds = %for.body, %entry
|
|
ret void
|
|
}
|
|
|
|
; PR6879
|
|
define ptr @test3(ptr %p_45, i16 zeroext %p_46, i64 %p_47, i64 %p_48, i16 signext %p_49) nounwind {
|
|
entry:
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %for.cond4, %entry
|
|
br i1 false, label %for.cond4, label %for.end88
|
|
|
|
for.cond4: ; preds = %for.cond
|
|
%conv46 = trunc i32 0 to i8 ; <i8> [#uses=2]
|
|
%cmp60 = icmp sgt i8 %conv46, 124 ; <i1> [#uses=1]
|
|
%or.cond = and i1 undef, %cmp60 ; <i1> [#uses=1]
|
|
%cond = select i1 %or.cond, i8 %conv46, i8 undef ; <i8> [#uses=0]
|
|
br label %for.cond
|
|
|
|
for.end88: ; preds = %for.cond
|
|
ret ptr undef
|
|
}
|