[TTI] getTypeBasedIntrinsicInstrCost - add basic handling for strided load/store...
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / trunc.ll
blob620d9781498749859acecf29790cbba93628a355
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
4 define 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
16   %ext = zext i16 %x to i32
17   %cond = icmp ult i32 %y, %ext
18   br i1 %cond, label %if.then, label %if.else
20 if.then:
21   %conv = trunc nuw i32 %y to i16
22   %cmp = icmp eq i16 %x, %conv
23   ret i1 %cmp
25 if.else:
26   ret i1 false
29 define 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
41   %ext = sext i16 %x to i32
42   %cond = icmp slt i32 %y, %ext
43   br i1 %cond, label %if.then, label %if.else
45 if.then:
46   %conv = trunc nsw i32 %y to i16
47   %cmp = icmp slt i16 %x, %conv
48   ret i1 %cmp
50 if.else:
51   ret i1 false
54 define 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
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
74 if.then:
75   %conv = zext i32 %y to i64
76   %cmp = icmp eq i64 %x, %conv
77   ret i1 %cmp
79 if.else:
80   ret i1 false
83 define 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
106   %cond = icmp sgt i32 %n, 0
107   br i1 %cond, label %if.then, label %if.else
109 if.then:
110   %ext = zext nneg i32 %n to i64
111   %end = add nsw i64 %ext, -1
112   br label %for.body
114 for.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
119 for.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
124 for.end:
125   %trunc = trunc nsw i64 %indvar.next to i32
126   %res = icmp sgt i32 %n, %trunc
127   ret i1 %res
129 if.else:
130   ret i1 false
133 define 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
146   %ext = zext i16 %x to i32
147   %cond = icmp ult i32 %y, %ext
148   br i1 %cond, label %if.then, label %if.else
150 if.then:
151   %conv = trunc i32 %y to i16
152   %cmp = icmp eq i16 %x, %conv
153   ret i1 %cmp
155 if.else:
156   ret i1 false
159 define 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
172   %ext = zext i16 %x to i128
173   %cond = icmp ult i128 %y, %ext
174   br i1 %cond, label %if.then, label %if.else
176 if.then:
177   %conv = trunc nuw i128 %y to i16
178   %cmp = icmp eq i16 %x, %conv
179   ret i1 %cmp
181 if.else:
182   ret i1 false
185 ; We do not know the sign of %x, so we cannot infer nuw for %ext.
186 define 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
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
203 if.then:
204   %conv = zext i32 %y to i64
205   %cmp = icmp eq i64 %x, %conv
206   ret i1 %cmp
208 if.else:
209   ret i1 false
212 declare void @cond()