xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/trunc.ll (revision 5fa59edfa73a69ab146d7b9cc115de5770d11dca)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3
4define i1 @test_icmp_ult_zext_icmp_trunc_nuw(i16 %x, i32 %y) {
5; CHECK-LABEL: define i1 @test_icmp_ult_zext_icmp_trunc_nuw(
6; CHECK-SAME: i16 [[X:%.*]], i32 [[Y:%.*]]) {
7; CHECK-NEXT:    [[EXT:%.*]] = zext i16 [[X]] to i32
8; CHECK-NEXT:    [[COND:%.*]] = icmp ult i32 [[Y]], [[EXT]]
9; CHECK-NEXT:    br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
10; CHECK:       [[IF_THEN]]:
11; CHECK-NEXT:    [[CONV:%.*]] = trunc nuw i32 [[Y]] to i16
12; CHECK-NEXT:    ret i1 false
13; CHECK:       [[IF_ELSE]]:
14; CHECK-NEXT:    ret i1 false
15;
16  %ext = zext i16 %x to i32
17  %cond = icmp ult i32 %y, %ext
18  br i1 %cond, label %if.then, label %if.else
19
20if.then:
21  %conv = trunc nuw i32 %y to i16
22  %cmp = icmp eq i16 %x, %conv
23  ret i1 %cmp
24
25if.else:
26  ret i1 false
27}
28
29define i1 @test_icmp_slt_sext_icmp_trunc_nsw(i16 %x, i32 %y) {
30; CHECK-LABEL: define i1 @test_icmp_slt_sext_icmp_trunc_nsw(
31; CHECK-SAME: i16 [[X:%.*]], i32 [[Y:%.*]]) {
32; CHECK-NEXT:    [[EXT:%.*]] = sext i16 [[X]] to i32
33; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[Y]], [[EXT]]
34; CHECK-NEXT:    br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
35; CHECK:       [[IF_THEN]]:
36; CHECK-NEXT:    [[CONV:%.*]] = trunc nsw i32 [[Y]] to i16
37; CHECK-NEXT:    ret i1 false
38; CHECK:       [[IF_ELSE]]:
39; CHECK-NEXT:    ret i1 false
40;
41  %ext = sext i16 %x to i32
42  %cond = icmp slt i32 %y, %ext
43  br i1 %cond, label %if.then, label %if.else
44
45if.then:
46  %conv = trunc nsw i32 %y to i16
47  %cmp = icmp slt i16 %x, %conv
48  ret i1 %cmp
49
50if.else:
51  ret i1 false
52}
53
54define i1 @test_icmp_ult_trunc_nsw_nneg_icmp_trunc_nuw(i64 %x, i32 %y) {
55; CHECK-LABEL: define i1 @test_icmp_ult_trunc_nsw_nneg_icmp_trunc_nuw(
56; CHECK-SAME: i64 [[X:%.*]], i32 [[Y:%.*]]) {
57; CHECK-NEXT:    [[EXT:%.*]] = trunc nsw i64 [[X]] to i32
58; CHECK-NEXT:    [[NNEG:%.*]] = icmp sgt i64 [[X]], -1
59; CHECK-NEXT:    [[COND:%.*]] = icmp ult i32 [[Y]], [[EXT]]
60; CHECK-NEXT:    [[AND:%.*]] = and i1 [[NNEG]], [[COND]]
61; CHECK-NEXT:    br i1 [[AND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
62; CHECK:       [[IF_THEN]]:
63; CHECK-NEXT:    [[CONV:%.*]] = zext i32 [[Y]] to i64
64; CHECK-NEXT:    ret i1 false
65; CHECK:       [[IF_ELSE]]:
66; CHECK-NEXT:    ret i1 false
67;
68  %ext = trunc nsw i64 %x to i32
69  %nneg = icmp sgt i64 %x, -1
70  %cond = icmp ult i32 %y, %ext
71  %and = and i1 %nneg, %cond
72  br i1 %and, label %if.then, label %if.else
73
74if.then:
75  %conv = zext i32 %y to i64
76  %cmp = icmp eq i64 %x, %conv
77  ret i1 %cmp
78
79if.else:
80  ret i1 false
81}
82
83define i1 @test2(i32 %n) {
84; CHECK-LABEL: define i1 @test2(
85; CHECK-SAME: i32 [[N:%.*]]) {
86; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i32 [[N]], 0
87; CHECK-NEXT:    br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
88; CHECK:       [[IF_THEN]]:
89; CHECK-NEXT:    [[EXT:%.*]] = zext nneg i32 [[N]] to i64
90; CHECK-NEXT:    [[END:%.*]] = add nsw i64 [[EXT]], -1
91; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
92; CHECK:       [[FOR_BODY]]:
93; CHECK-NEXT:    [[INDVAR:%.*]] = phi i64 [ 0, %[[IF_THEN]] ], [ [[INDVAR_NEXT:%.*]], %[[FOR_NEXT:.*]] ]
94; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[INDVAR]], [[END]]
95; CHECK-NEXT:    br i1 [[CMP]], label %[[IF_ELSE]], label %[[FOR_NEXT]]
96; CHECK:       [[FOR_NEXT]]:
97; CHECK-NEXT:    [[INDVAR_NEXT]] = add nuw nsw i64 [[INDVAR]], 1
98; CHECK-NEXT:    [[COND2:%.*]] = call i1 @cond()
99; CHECK-NEXT:    br i1 [[COND2]], label %[[FOR_BODY]], label %[[FOR_END:.*]]
100; CHECK:       [[FOR_END]]:
101; CHECK-NEXT:    [[TRUNC:%.*]] = trunc nsw i64 [[INDVAR_NEXT]] to i32
102; CHECK-NEXT:    ret i1 true
103; CHECK:       [[IF_ELSE]]:
104; CHECK-NEXT:    ret i1 false
105;
106  %cond = icmp sgt i32 %n, 0
107  br i1 %cond, label %if.then, label %if.else
108
109if.then:
110  %ext = zext nneg i32 %n to i64
111  %end = add nsw i64 %ext, -1
112  br label %for.body
113
114for.body:
115  %indvar = phi i64 [ 0, %if.then ], [ %indvar.next, %for.next ]
116  %cmp = icmp eq i64 %indvar, %end
117  br i1 %cmp, label %if.else, label %for.next
118
119for.next:
120  %indvar.next = add nuw nsw i64 %indvar, 1
121  %cond2 = call i1 @cond()
122  br i1 %cond2, label %for.body, label %for.end
123
124for.end:
125  %trunc = trunc nsw i64 %indvar.next to i32
126  %res = icmp sgt i32 %n, %trunc
127  ret i1 %res
128
129if.else:
130  ret i1 false
131}
132
133define i1 @test_icmp_ult_zext_icmp_trunc(i16 %x, i32 %y) {
134; CHECK-LABEL: define i1 @test_icmp_ult_zext_icmp_trunc(
135; CHECK-SAME: i16 [[X:%.*]], i32 [[Y:%.*]]) {
136; CHECK-NEXT:    [[EXT:%.*]] = zext i16 [[X]] to i32
137; CHECK-NEXT:    [[COND:%.*]] = icmp ult i32 [[Y]], [[EXT]]
138; CHECK-NEXT:    br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
139; CHECK:       [[IF_THEN]]:
140; CHECK-NEXT:    [[CONV:%.*]] = trunc i32 [[Y]] to i16
141; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[X]], [[CONV]]
142; CHECK-NEXT:    ret i1 [[CMP]]
143; CHECK:       [[IF_ELSE]]:
144; CHECK-NEXT:    ret i1 false
145;
146  %ext = zext i16 %x to i32
147  %cond = icmp ult i32 %y, %ext
148  br i1 %cond, label %if.then, label %if.else
149
150if.then:
151  %conv = trunc i32 %y to i16
152  %cmp = icmp eq i16 %x, %conv
153  ret i1 %cmp
154
155if.else:
156  ret i1 false
157}
158
159define i1 @test_icmp_ult_zext_icmp_trunc_nuw_i128(i16 %x, i128 %y) {
160; CHECK-LABEL: define i1 @test_icmp_ult_zext_icmp_trunc_nuw_i128(
161; CHECK-SAME: i16 [[X:%.*]], i128 [[Y:%.*]]) {
162; CHECK-NEXT:    [[EXT:%.*]] = zext i16 [[X]] to i128
163; CHECK-NEXT:    [[COND:%.*]] = icmp ult i128 [[Y]], [[EXT]]
164; CHECK-NEXT:    br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
165; CHECK:       [[IF_THEN]]:
166; CHECK-NEXT:    [[CONV:%.*]] = trunc nuw i128 [[Y]] to i16
167; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[X]], [[CONV]]
168; CHECK-NEXT:    ret i1 [[CMP]]
169; CHECK:       [[IF_ELSE]]:
170; CHECK-NEXT:    ret i1 false
171;
172  %ext = zext i16 %x to i128
173  %cond = icmp ult i128 %y, %ext
174  br i1 %cond, label %if.then, label %if.else
175
176if.then:
177  %conv = trunc nuw i128 %y to i16
178  %cmp = icmp eq i16 %x, %conv
179  ret i1 %cmp
180
181if.else:
182  ret i1 false
183}
184
185; We do not know the sign of %x, so we cannot infer nuw for %ext.
186define i1 @test_icmp_ult_trunc_nsw_icmp_trunc_nuw(i64 %x, i32 %y) {
187; CHECK-LABEL: define i1 @test_icmp_ult_trunc_nsw_icmp_trunc_nuw(
188; CHECK-SAME: i64 [[X:%.*]], i32 [[Y:%.*]]) {
189; CHECK-NEXT:    [[EXT:%.*]] = trunc nsw i64 [[X]] to i32
190; CHECK-NEXT:    [[COND:%.*]] = icmp ult i32 [[Y]], [[EXT]]
191; CHECK-NEXT:    br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
192; CHECK:       [[IF_THEN]]:
193; CHECK-NEXT:    [[CONV:%.*]] = zext i32 [[Y]] to i64
194; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[X]], [[CONV]]
195; CHECK-NEXT:    ret i1 [[CMP]]
196; CHECK:       [[IF_ELSE]]:
197; CHECK-NEXT:    ret i1 false
198;
199  %ext = trunc nsw i64 %x to i32
200  %cond = icmp ult i32 %y, %ext
201  br i1 %cond, label %if.then, label %if.else
202
203if.then:
204  %conv = zext i32 %y to i64
205  %cmp = icmp eq i64 %x, %conv
206  ret i1 %cmp
207
208if.else:
209  ret i1 false
210}
211
212declare void @cond()
213