xref: /llvm-project/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-trivial-select.ll (revision 2f171b275f71f5f753980bfcbb2b1aeaa2b3701a)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes='simple-loop-unswitch<nontrivial>' -S < %s | FileCheck %s
3
4; If we try to replace uses of `true` outside of `@foo`, we'll see it here.
5define i1 @bar() {
6; CHECK-LABEL: @bar(
7; CHECK-NEXT:    ret i1 true
8;
9  ret i1 true
10}
11
12; We shouldn't unswitch this loop.
13define void @foo() {
14; CHECK-LABEL: @foo(
15; CHECK-NEXT:  entry:
16; CHECK-NEXT:    br label [[HEADER:%.*]]
17; CHECK:       header:
18; CHECK-NEXT:    [[VAL:%.*]] = select i1 true, i1 true, i1 false
19; CHECK-NEXT:    br i1 [[VAL]], label [[EXIT:%.*]], label [[HEADER]]
20; CHECK:       exit:
21; CHECK-NEXT:    ret void
22;
23entry:
24  br label %header
25
26header:
27  %val = select i1 true, i1 true, i1 false
28  br i1 %val, label %exit, label %header
29
30exit:
31  ret void
32}
33
34define void @unswitch_trivial_select(i1 %c.1, i1 %c.2, i8 %a) {
35; CHECK-LABEL: @unswitch_trivial_select(
36; CHECK-NEXT:  entry:
37; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[PH_1:%.*]], label [[EXIT:%.*]]
38; CHECK:       ph.1:
39; CHECK-NEXT:    br i1 [[C_2:%.*]], label [[PH_2:%.*]], label [[EXIT]]
40; CHECK:       ph.2:
41; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 30
42; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i1 true, i1 false
43; CHECK-NEXT:    [[CMP_FR:%.*]] = freeze i1 [[CMP]]
44; CHECK-NEXT:    br i1 [[CMP_FR]], label [[PH_2_SPLIT_US:%.*]], label [[PH_2_SPLIT:%.*]]
45; CHECK:       ph.2.split.us:
46; CHECK-NEXT:    br label [[LOOP_US:%.*]]
47; CHECK:       loop.us:
48; CHECK-NEXT:    call void @foo()
49; CHECK-NEXT:    br label [[EXIT_LOOPEXIT_SPLIT_US:%.*]]
50; CHECK:       exit.loopexit.split.us:
51; CHECK-NEXT:    br label [[EXIT_LOOPEXIT:%.*]]
52; CHECK:       ph.2.split:
53; CHECK-NEXT:    br label [[LOOP:%.*]]
54; CHECK:       loop:
55; CHECK-NEXT:    call void @foo()
56; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
57; CHECK:       loop.latch:
58; CHECK-NEXT:    br label [[LOOP]]
59; CHECK:       exit.loopexit:
60; CHECK-NEXT:    br label [[EXIT]]
61; CHECK:       exit:
62; CHECK-NEXT:    ret void
63;
64entry:
65  br i1 %c.1, label %ph.1, label %exit
66
67ph.1:
68  br i1 %c.2, label %ph.2, label %exit
69
70ph.2:
71  %cmp = icmp eq i8 %a, 30
72  %sel = select i1 %cmp, i1 true, i1 false
73  br label %loop
74
75loop:
76  call void @foo()
77  br i1 %sel, label %exit, label %loop.latch
78
79loop.latch:
80  br label %loop
81
82exit:
83  ret void
84}
85
86; Test case for PR55697.
87define i32 @unswitch_trivial_select_cmp_outside(i32 %x) {
88; CHECK-LABEL: @unswitch_trivial_select_cmp_outside(
89; CHECK-NEXT:  entry:
90; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[X:%.*]], 100
91; CHECK-NEXT:    br i1 [[C]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
92; CHECK:       entry.split.us:
93; CHECK-NEXT:    br label [[LOOP_US:%.*]]
94; CHECK:       loop.us:
95; CHECK-NEXT:    [[P_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ 35, [[LOOP_US]] ]
96; CHECK-NEXT:    br label [[LOOP_US]]
97; CHECK:       entry.split:
98; CHECK-NEXT:    br label [[LOOP:%.*]]
99; CHECK:       loop:
100; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ]
101; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 false, i1 true, i1 false
102; CHECK-NEXT:    br label [[EXIT:%.*]]
103; CHECK:       exit:
104; CHECK-NEXT:    [[LCSSA:%.*]] = phi i32 [ [[P]], [[LOOP]] ]
105; CHECK-NEXT:    ret i32 [[LCSSA]]
106;
107entry:
108  %c = icmp ult i32 %x, 100
109  br label %loop
110
111loop:
112  %p = phi i32 [ 0, %entry ], [ 35, %loop ]
113  %spec.select = select i1 %c, i1 true, i1 false
114  br i1 %spec.select, label %loop, label %exit
115
116exit:
117  %lcssa = phi i32 [ %p, %loop ]
118  ret i32 %lcssa
119}
120