xref: /llvm-project/llvm/test/Transforms/InstCombine/known-phi-br.ll (revision f1106ef6c9d14d5b516ec352279aeee8f9d12818)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3
4;
5; Tests to show cases where computeKnownBits should be able to determine
6; the known bits of a phi edge based off a conditional branch feeding the phi.
7;
8
9; %x either eq 7 or is set to 7
10define i64 @limit_i64_eq_7(i64 %x) {
11; CHECK-LABEL: @limit_i64_eq_7(
12; CHECK-NEXT:  entry:
13; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[X:%.*]], 7
14; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[BODY:%.*]]
15; CHECK:       body:
16; CHECK-NEXT:    br label [[END]]
17; CHECK:       end:
18; CHECK-NEXT:    [[RES:%.*]] = phi i64 [ [[X]], [[ENTRY:%.*]] ], [ 7, [[BODY]] ]
19; CHECK-NEXT:    ret i64 [[RES]]
20;
21entry:
22  %cmp = icmp eq i64 %x, 7
23  br i1 %cmp, label %end, label %body
24body:
25  br label %end
26end:
27  %res = phi i64 [ %x, %entry ], [ 7, %body ]
28  ret i64 %res
29}
30
31; %x either eq 255 or is set to 255
32define i64 @limit_i64_ne_255(i64 %x) {
33; CHECK-LABEL: @limit_i64_ne_255(
34; CHECK-NEXT:  entry:
35; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[X:%.*]], 255
36; CHECK-NEXT:    call void @use(i1 [[CMP]])
37; CHECK-NEXT:    br i1 [[CMP]], label [[BODY:%.*]], label [[END:%.*]]
38; CHECK:       body:
39; CHECK-NEXT:    br label [[END]]
40; CHECK:       end:
41; CHECK-NEXT:    [[RES:%.*]] = phi i64 [ [[X]], [[ENTRY:%.*]] ], [ 255, [[BODY]] ]
42; CHECK-NEXT:    ret i64 [[RES]]
43;
44entry:
45  %cmp = icmp ne i64 %x, 255
46  call void @use(i1 %cmp)
47  br i1 %cmp, label %body, label %end
48body:
49  br label %end
50end:
51  %res = phi i64 [ %x, %entry ], [ 255, %body ]
52  ret i64 %res
53}
54declare void @use(i1)
55
56; %x either ule 15 or is masked with 15
57define i64 @limit_i64_ule_15(i64 %x) {
58; CHECK-LABEL: @limit_i64_ule_15(
59; CHECK-NEXT:  entry:
60; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[X:%.*]], 16
61; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[BODY:%.*]]
62; CHECK:       body:
63; CHECK-NEXT:    [[MASK:%.*]] = and i64 [[X]], 15
64; CHECK-NEXT:    br label [[END]]
65; CHECK:       end:
66; CHECK-NEXT:    [[X_MASK:%.*]] = phi i64 [ [[X]], [[ENTRY:%.*]] ], [ [[MASK]], [[BODY]] ]
67; CHECK-NEXT:    ret i64 [[X_MASK]]
68;
69entry:
70  %cmp = icmp ule i64 %x, 15
71  br i1 %cmp, label %end, label %body
72body:
73  %mask = and i64 %x, 15
74  br label %end
75end:
76  %x.mask = phi i64 [ %x, %entry ], [ %mask, %body ]
77  %res = and i64 %x.mask, 15
78  ret i64 %res
79}
80
81; %x either uge 8 or is masked with 7
82define i64 @limit_i64_uge_8(i64 %x) {
83; CHECK-LABEL: @limit_i64_uge_8(
84; CHECK-NEXT:  entry:
85; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[X:%.*]], 7
86; CHECK-NEXT:    br i1 [[CMP]], label [[BODY:%.*]], label [[END:%.*]]
87; CHECK:       body:
88; CHECK-NEXT:    [[MASK:%.*]] = and i64 [[X]], 7
89; CHECK-NEXT:    br label [[END]]
90; CHECK:       end:
91; CHECK-NEXT:    [[X_MASK:%.*]] = phi i64 [ [[X]], [[ENTRY:%.*]] ], [ [[MASK]], [[BODY]] ]
92; CHECK-NEXT:    ret i64 [[X_MASK]]
93;
94entry:
95  %cmp = icmp uge i64 %x, 8
96  br i1 %cmp, label %body, label %end
97body:
98  %mask = and i64 %x, 7
99  br label %end
100end:
101  %x.mask = phi i64 [ %x, %entry ], [ %mask, %body ]
102  %res = and i64 %x.mask, 7
103  ret i64 %res
104}
105
106; %x either ult 8 or is masked with 7
107define i64 @limit_i64_ult_8(i64 %x) {
108; CHECK-LABEL: @limit_i64_ult_8(
109; CHECK-NEXT:  entry:
110; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[X:%.*]], 8
111; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[BODY:%.*]]
112; CHECK:       body:
113; CHECK-NEXT:    [[MASK:%.*]] = and i64 [[X]], 7
114; CHECK-NEXT:    br label [[END]]
115; CHECK:       end:
116; CHECK-NEXT:    [[X_MASK:%.*]] = phi i64 [ [[X]], [[ENTRY:%.*]] ], [ [[MASK]], [[BODY]] ]
117; CHECK-NEXT:    ret i64 [[X_MASK]]
118;
119entry:
120  %cmp = icmp ult i64 %x, 8
121  br i1 %cmp, label %end, label %body
122body:
123  %mask = and i64 %x, 7
124  br label %end
125end:
126  %x.mask = phi i64 [ %x, %entry ], [ %mask, %body ]
127  %res = and i64 %x.mask, 7
128  ret i64 %res
129}
130
131; %x either ugt 7 or is masked with 7
132define i64 @limit_i64_ugt_7(i64 %x) {
133; CHECK-LABEL: @limit_i64_ugt_7(
134; CHECK-NEXT:  entry:
135; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[X:%.*]], 7
136; CHECK-NEXT:    br i1 [[CMP]], label [[BODY:%.*]], label [[END:%.*]]
137; CHECK:       body:
138; CHECK-NEXT:    [[MASK:%.*]] = and i64 [[X]], 7
139; CHECK-NEXT:    br label [[END]]
140; CHECK:       end:
141; CHECK-NEXT:    [[X_MASK:%.*]] = phi i64 [ [[X]], [[ENTRY:%.*]] ], [ [[MASK]], [[BODY]] ]
142; CHECK-NEXT:    ret i64 [[X_MASK]]
143;
144entry:
145  %cmp = icmp ugt i64 %x, 7
146  br i1 %cmp, label %body, label %end
147body:
148  %mask = and i64 %x, 7
149  br label %end
150end:
151  %x.mask = phi i64 [ %x, %entry ], [ %mask, %body ]
152  %res = and i64 %x.mask, 7
153  ret i64 %res
154}
155
156;
157; negative tests
158;
159
160; %x either ule 15 or is masked with 15
161define i64 @limit_i64_ule_15_mask3(i64 %x) {
162; CHECK-LABEL: @limit_i64_ule_15_mask3(
163; CHECK-NEXT:  entry:
164; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[X:%.*]], 16
165; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[BODY:%.*]]
166; CHECK:       body:
167; CHECK-NEXT:    [[MASK:%.*]] = and i64 [[X]], 15
168; CHECK-NEXT:    br label [[END]]
169; CHECK:       end:
170; CHECK-NEXT:    [[X_MASK:%.*]] = phi i64 [ [[X]], [[ENTRY:%.*]] ], [ [[MASK]], [[BODY]] ]
171; CHECK-NEXT:    [[RES:%.*]] = and i64 [[X_MASK]], 3
172; CHECK-NEXT:    ret i64 [[RES]]
173;
174entry:
175  %cmp = icmp ule i64 %x, 15
176  br i1 %cmp, label %end, label %body
177body:
178  %mask = and i64 %x, 15
179  br label %end
180end:
181  %x.mask = phi i64 [ %x, %entry ], [ %mask, %body ]
182  %res = and i64 %x.mask, 3
183  ret i64 %res
184}
185
186; %x either ult 8 or is masked with 7
187define i64 @limit_i64_ult_8_mask1(i64 %x) {
188; CHECK-LABEL: @limit_i64_ult_8_mask1(
189; CHECK-NEXT:  entry:
190; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[X:%.*]], 8
191; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[BODY:%.*]]
192; CHECK:       body:
193; CHECK-NEXT:    [[MASK:%.*]] = and i64 [[X]], 7
194; CHECK-NEXT:    br label [[END]]
195; CHECK:       end:
196; CHECK-NEXT:    [[X_MASK:%.*]] = phi i64 [ [[X]], [[ENTRY:%.*]] ], [ [[MASK]], [[BODY]] ]
197; CHECK-NEXT:    [[RES:%.*]] = and i64 [[X_MASK]], 1
198; CHECK-NEXT:    ret i64 [[RES]]
199;
200entry:
201  %cmp = icmp ult i64 %x, 8
202  br i1 %cmp, label %end, label %body
203body:
204  %mask = and i64 %x, 7
205  br label %end
206end:
207  %x.mask = phi i64 [ %x, %entry ], [ %mask, %body ]
208  %res = and i64 %x.mask, 1
209  ret i64 %res
210}
211