llvm-project/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-trivial-select.ll
Florian Hahn f96aa493f0
[SimpleLoopUnswitch] Always skip trivial select and set condition.
When updating the branch instruction outside the loopduring non-trivial
 unswitching, always skip trivial selects and update the condition.

Otherwise we might create invalid IR, because the trivial select is
inside the loop, while the condition is outside the loop.

Fixes #55697.
2022-05-26 09:46:24 +01:00

120 lines
3.4 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes='simple-loop-unswitch<nontrivial>' -S < %s | FileCheck %s
; If we try to replace uses of `true` outside of `@foo`, we'll see it here.
define i1 @bar() {
; CHECK-LABEL: @bar(
; CHECK-NEXT: ret i1 true
;
ret i1 true
}
; We shouldn't unswitch this loop.
define void @foo() {
; CHECK-LABEL: @foo(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[HEADER:%.*]]
; CHECK: header:
; CHECK-NEXT: [[VAL:%.*]] = select i1 true, i1 true, i1 false
; CHECK-NEXT: br i1 [[VAL]], label [[EXIT:%.*]], label [[HEADER]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %header
header:
%val = select i1 true, i1 true, i1 false
br i1 %val, label %exit, label %header
exit:
ret void
}
define void @unswitch_trivial_select(i1 %c.1, i1 %c.2, i8 %a) {
; CHECK-LABEL: @unswitch_trivial_select(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[PH_1:%.*]], label [[EXIT:%.*]]
; CHECK: ph.1:
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[PH_2:%.*]], label [[EXIT]]
; CHECK: ph.2:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 30
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i1 true, i1 false
; CHECK-NEXT: [[CMP_FR:%.*]] = freeze i1 [[CMP]]
; CHECK-NEXT: br i1 [[CMP_FR]], label [[PH_2_SPLIT_US:%.*]], label [[PH_2_SPLIT:%.*]]
; CHECK: ph.2.split.us:
; CHECK-NEXT: br label [[LOOP_US:%.*]]
; CHECK: loop.us:
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: br label [[EXIT_LOOPEXIT_SPLIT_US:%.*]]
; CHECK: exit.loopexit.split.us:
; CHECK-NEXT: br label [[EXIT_LOOPEXIT:%.*]]
; CHECK: ph.2.split:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: br label [[LOOP_LATCH:%.*]]
; CHECK: loop.latch:
; CHECK-NEXT: br label [[LOOP]]
; CHECK: exit.loopexit:
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br i1 %c.1, label %ph.1, label %exit
ph.1:
br i1 %c.2, label %ph.2, label %exit
ph.2:
%cmp = icmp eq i8 %a, 30
%sel = select i1 %cmp, i1 true, i1 false
br label %loop
loop:
call void @foo()
br i1 %sel, label %exit, label %loop.latch
loop.latch:
br label %loop
exit:
ret void
}
; Test case for PR55697.
define i32 @unswitch_trivial_select_cmp_outside(i32 %x) {
; CHECK-LABEL: @unswitch_trivial_select_cmp_outside(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], 100
; CHECK-NEXT: br i1 [[C]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
; CHECK: entry.split.us:
; CHECK-NEXT: br label [[LOOP_US:%.*]]
; CHECK: loop.us:
; CHECK-NEXT: [[P_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ 35, [[LOOP_US]] ]
; CHECK-NEXT: br label [[LOOP_US]]
; CHECK: entry.split:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ]
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 false, i1 true, i1 false
; CHECK-NEXT: br label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: [[LCSSA:%.*]] = phi i32 [ [[P]], [[LOOP]] ]
; CHECK-NEXT: ret i32 [[LCSSA]]
;
entry:
%c = icmp ult i32 %x, 100
br label %loop
loop:
%p = phi i32 [ 0, %entry ], [ 35, %loop ]
%spec.select = select i1 %c, i1 true, i1 false
br i1 %spec.select, label %loop, label %exit
exit:
%lcssa = phi i32 [ %p, %loop ]
ret i32 %lcssa
}