xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/sext-signed-predicates.ll (revision 4e9fe860d2dd462e514586a3b90ad373dc07b797)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3
4define i1 @cmp_sext(i32 %a, i32 %b){
5; CHECK-LABEL: define i1 @cmp_sext(
6; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
7; CHECK-NEXT:  entry:
8; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
9; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
10; CHECK:       then:
11; CHECK-NEXT:    [[SA:%.*]] = sext i32 [[A]] to i64
12; CHECK-NEXT:    [[SB:%.*]] = sext i32 [[B]] to i64
13; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SA]], 1
14; CHECK-NEXT:    ret i1 true
15; CHECK:       else:
16; CHECK-NEXT:    ret i1 false
17;
18entry:
19  %cmp = icmp slt i32 %a, %b
20  br i1 %cmp, label %then, label %else
21
22then:
23  %sa = sext i32 %a to i64
24  %sb = sext i32 %b to i64
25  %add = add nsw i64 %sa, 1
26  %cmp2 = icmp sge i64 %sb, %add
27  ret i1 %cmp2
28
29else:
30  ret i1 false
31}
32
33define i1 @cmp_sext_add(i32 %a, i32 %b){
34; CHECK-LABEL: define i1 @cmp_sext_add(
35; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
36; CHECK-NEXT:  entry:
37; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
38; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
39; CHECK:       then:
40; CHECK-NEXT:    [[A1:%.*]] = add nsw i32 [[A]], 1
41; CHECK-NEXT:    [[B1:%.*]] = add nsw i32 [[B]], 1
42; CHECK-NEXT:    [[SA:%.*]] = sext i32 [[A1]] to i64
43; CHECK-NEXT:    [[SB:%.*]] = sext i32 [[B1]] to i64
44; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SA]], 1
45; CHECK-NEXT:    ret i1 true
46; CHECK:       else:
47; CHECK-NEXT:    ret i1 false
48;
49entry:
50  %cmp = icmp slt i32 %a, %b
51  br i1 %cmp, label %then, label %else
52
53then:
54  %a1 = add nsw i32 %a, 1
55  %b1 = add nsw i32 %b, 1
56  %sa = sext i32 %a1 to i64
57  %sb = sext i32 %b1 to i64
58  %add = add nsw i64 %sa, 1
59  %cmp2 = icmp sge i64 %sb, %add
60  ret i1 %cmp2
61
62else:
63  ret i1 false
64}
65
66define i1 @cmp_sext_dynamic_increment(i32 %a, i32 %b, i64 %c){
67; CHECK-LABEL: define i1 @cmp_sext_dynamic_increment(
68; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) {
69; CHECK-NEXT:  entry:
70; CHECK-NEXT:    [[POS:%.*]] = icmp slt i64 [[C]], 2
71; CHECK-NEXT:    call void @llvm.assume(i1 [[POS]])
72; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
73; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
74; CHECK:       then:
75; CHECK-NEXT:    [[SA:%.*]] = sext i32 [[A]] to i64
76; CHECK-NEXT:    [[SB:%.*]] = sext i32 [[B]] to i64
77; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SA]], [[C]]
78; CHECK-NEXT:    ret i1 true
79; CHECK:       else:
80; CHECK-NEXT:    ret i1 false
81;
82entry:
83  %pos = icmp slt i64 %c, 2
84  call void @llvm.assume(i1 %pos)
85  %cmp = icmp slt i32 %a, %b
86  br i1 %cmp, label %then, label %else
87
88then:
89  %sa = sext i32 %a to i64
90  %sb = sext i32 %b to i64
91  %add = add nsw i64 %sa, %c
92  %cmp2 = icmp sge i64 %sb, %add
93  ret i1 %cmp2
94
95else:
96  ret i1 false
97}
98
99define i1 @cmp_zext_nneg(i32 %a, i32 %b){
100; CHECK-LABEL: define i1 @cmp_zext_nneg(
101; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
102; CHECK-NEXT:  entry:
103; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
104; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
105; CHECK:       then:
106; CHECK-NEXT:    [[SA:%.*]] = zext nneg i32 [[A]] to i64
107; CHECK-NEXT:    [[SB:%.*]] = zext nneg i32 [[B]] to i64
108; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SA]], 1
109; CHECK-NEXT:    ret i1 true
110; CHECK:       else:
111; CHECK-NEXT:    ret i1 false
112;
113entry:
114  %cmp = icmp slt i32 %a, %b
115  br i1 %cmp, label %then, label %else
116
117then:
118  %sa = zext nneg i32 %a to i64
119  %sb = zext nneg i32 %b to i64
120  %add = add nsw i64 %sa, 1
121  %cmp2 = icmp sge i64 %sb, %add
122  ret i1 %cmp2
123
124else:
125  ret i1 false
126}
127
128; Negative tests
129
130define i1 @cmp_zext(i32 %a, i32 %b){
131; CHECK-LABEL: define i1 @cmp_zext(
132; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
133; CHECK-NEXT:  entry:
134; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
135; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
136; CHECK:       then:
137; CHECK-NEXT:    [[SA:%.*]] = zext i32 [[A]] to i64
138; CHECK-NEXT:    [[SB:%.*]] = zext i32 [[B]] to i64
139; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SA]], 1
140; CHECK-NEXT:    [[CMP2:%.*]] = icmp sge i64 [[SB]], [[ADD]]
141; CHECK-NEXT:    ret i1 [[CMP2]]
142; CHECK:       else:
143; CHECK-NEXT:    ret i1 false
144;
145entry:
146  %cmp = icmp slt i32 %a, %b
147  br i1 %cmp, label %then, label %else
148
149then:
150  %sa = zext i32 %a to i64
151  %sb = zext i32 %b to i64
152  %add = add nsw i64 %sa, 1
153  %cmp2 = icmp sge i64 %sb, %add
154  ret i1 %cmp2
155
156else:
157  ret i1 false
158}
159
160define i1 @cmp_sext_unknown_increment(i32 %a, i32 %b, i64 %c){
161; CHECK-LABEL: define i1 @cmp_sext_unknown_increment(
162; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) {
163; CHECK-NEXT:  entry:
164; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
165; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
166; CHECK:       then:
167; CHECK-NEXT:    [[SA:%.*]] = sext i32 [[A]] to i64
168; CHECK-NEXT:    [[SB:%.*]] = sext i32 [[B]] to i64
169; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SA]], [[C]]
170; CHECK-NEXT:    [[CMP2:%.*]] = icmp sge i64 [[SB]], [[ADD]]
171; CHECK-NEXT:    ret i1 [[CMP2]]
172; CHECK:       else:
173; CHECK-NEXT:    ret i1 false
174;
175entry:
176  %cmp = icmp slt i32 %a, %b
177  br i1 %cmp, label %then, label %else
178
179then:
180  %sa = sext i32 %a to i64
181  %sb = sext i32 %b to i64
182  %add = add nsw i64 %sa, %c
183  %cmp2 = icmp sge i64 %sb, %add
184  ret i1 %cmp2
185
186else:
187  ret i1 false
188}
189
190define i1 @cmp_sext_sgt(i32 %a, i32 %b){
191; CHECK-LABEL: define i1 @cmp_sext_sgt(
192; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
193; CHECK-NEXT:  entry:
194; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
195; CHECK-NEXT:    br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
196; CHECK:       then:
197; CHECK-NEXT:    [[SA:%.*]] = sext i32 [[A]] to i64
198; CHECK-NEXT:    [[SB:%.*]] = sext i32 [[B]] to i64
199; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SA]], 1
200; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i64 [[SB]], [[ADD]]
201; CHECK-NEXT:    ret i1 [[CMP2]]
202; CHECK:       else:
203; CHECK-NEXT:    ret i1 false
204;
205entry:
206  %cmp = icmp slt i32 %a, %b
207  br i1 %cmp, label %then, label %else
208
209then:
210  %sa = sext i32 %a to i64
211  %sb = sext i32 %b to i64
212  %add = add nsw i64 %sa, 1
213  %cmp2 = icmp sgt i64 %sb, %add
214  ret i1 %cmp2
215
216else:
217  ret i1 false
218}
219
220declare void @use(i1)
221
222define void @sge_sext(i16 %x, i32 %y) {
223; CHECK-LABEL: define void @sge_sext(
224; CHECK-SAME: i16 [[X:%.*]], i32 [[Y:%.*]]) {
225; CHECK-NEXT:  entry:
226; CHECK-NEXT:    [[X_EXT:%.*]] = sext i16 [[X]] to i32
227; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i32 [[X_EXT]], [[Y]]
228; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i32 [[Y]], -10
229; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]
230; CHECK-NEXT:    br i1 [[AND]], label [[BB1:%.*]], label [[BB2:%.*]]
231; CHECK:       bb1:
232; CHECK-NEXT:    call void @use(i1 true)
233; CHECK-NEXT:    call void @use(i1 true)
234; CHECK-NEXT:    [[T_3:%.*]] = icmp sge i32 [[X_EXT]], -9
235; CHECK-NEXT:    call void @use(i1 [[T_3]])
236; CHECK-NEXT:    [[C_3:%.*]] = icmp sge i32 [[X_EXT]], -9
237; CHECK-NEXT:    call void @use(i1 [[C_3]])
238; CHECK-NEXT:    [[C_4:%.*]] = icmp sge i32 [[Y]], [[X_EXT]]
239; CHECK-NEXT:    call void @use(i1 [[C_4]])
240; CHECK-NEXT:    [[C_5:%.*]] = icmp sge i16 [[X]], -9
241; CHECK-NEXT:    call void @use(i1 [[C_5]])
242; CHECK-NEXT:    ret void
243; CHECK:       bb2:
244; CHECK-NEXT:    ret void
245;
246entry:
247  %x.ext = sext i16 %x to i32
248  %c.1 = icmp sge i32 %x.ext, %y
249  %c.2 = icmp sge i32 %y, -10
250  %and = and i1 %c.1, %c.2
251  br i1 %and, label %bb1, label %bb2
252
253bb1:
254  %t.1 = icmp sge i32 %x.ext, %y
255  call void @use(i1 %t.1)
256  %t.2 = icmp sge i16 %x, -10
257  call void @use(i1 %t.2)
258  %t.3 = icmp sge i32 %x.ext, -9
259  call void @use(i1 %t.3)
260  %c.3 = icmp sge i32 %x.ext, -9
261  call void @use(i1 %c.3)
262  %c.4 = icmp sge i32 %y, %x.ext
263  call void @use(i1 %c.4)
264  %c.5 = icmp sge i16 %x, -9
265  call void @use(i1 %c.5)
266  ret void
267
268bb2:
269  ret void
270}
271