1 ; Tests to make sure elimination of casts is working correctly
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 @inbuf = external global [32832 x i8] ; <[32832 x i8]*> [#uses=1]
6 define i32 @test1(i32 %A) {
7 %c1 = bitcast i32 %A to i32 ; <i32> [#uses=1]
8 %c2 = bitcast i32 %c1 to i32 ; <i32> [#uses=1]
13 define i64 @test2(i8 %A) {
14 %c1 = zext i8 %A to i16 ; <i16> [#uses=1]
15 %c2 = zext i16 %c1 to i32 ; <i32> [#uses=1]
16 %Ret = zext i32 %c2 to i64 ; <i64> [#uses=1]
18 ; CHECK: %Ret = zext i8 %A to i64
22 ; This function should just use bitwise AND
23 define i64 @test3(i64 %A) {
24 %c1 = trunc i64 %A to i8 ; <i8> [#uses=1]
25 %c2 = zext i8 %c1 to i64 ; <i64> [#uses=1]
27 ; CHECK: %c2 = and i64 %A, 255
31 define i32 @test4(i32 %A, i32 %B) {
32 %COND = icmp slt i32 %A, %B ; <i1> [#uses=1]
33 ; Booleans are unsigned integrals
34 %c = zext i1 %COND to i8 ; <i8> [#uses=1]
35 ; for the cast elim purpose
36 %result = zext i8 %c to i32 ; <i32> [#uses=1]
38 ; CHECK: %COND = icmp slt i32 %A, %B
39 ; CHECK: %result = zext i1 %COND to i32
40 ; CHECK: ret i32 %result
43 define i32 @test5(i1 %B) {
44 ; This cast should get folded into
45 %c = zext i1 %B to i8 ; <i8> [#uses=1]
47 %result = zext i8 %c to i32 ; <i32> [#uses=1]
49 ; CHECK: %result = zext i1 %B to i32
50 ; CHECK: ret i32 %result
53 define i32 @test6(i64 %A) {
54 %c1 = trunc i64 %A to i32 ; <i32> [#uses=1]
55 %res = bitcast i32 %c1 to i32 ; <i32> [#uses=1]
57 ; CHECK: %res = trunc i64 %A to i32
61 define i64 @test7(i1 %A) {
62 %c1 = zext i1 %A to i32 ; <i32> [#uses=1]
63 %res = sext i32 %c1 to i64 ; <i64> [#uses=1]
65 ; CHECK: %res = zext i1 %A to i64
69 define i64 @test8(i8 %A) {
70 %c1 = sext i8 %A to i64 ; <i64> [#uses=1]
71 %res = bitcast i64 %c1 to i64 ; <i64> [#uses=1]
73 ; CHECK: %res = sext i8 %A to i64
77 define i16 @test9(i16 %A) {
78 %c1 = sext i16 %A to i32 ; <i32> [#uses=1]
79 %c2 = trunc i32 %c1 to i16 ; <i16> [#uses=1]
84 define i16 @test10(i16 %A) {
85 %c1 = sext i16 %A to i32 ; <i32> [#uses=1]
86 %c2 = trunc i32 %c1 to i16 ; <i16> [#uses=1]
91 declare void @varargs(i32, ...)
93 define void @test11(i32* %P) {
94 %c = bitcast i32* %P to i16* ; <i16*> [#uses=1]
95 call void (i32, ...)* @varargs( i32 5, i16* %c )
97 ; CHECK: call void (i32, ...)* @varargs(i32 5, i32* %P)
101 define i32* @test12() {
102 %p = malloc [4 x i8] ; <[4 x i8]*> [#uses=1]
103 %c = bitcast [4 x i8]* %p to i32* ; <i32*> [#uses=1]
105 ; CHECK: %malloccall = tail call i8* @malloc(i32 ptrtoint ([4 x i8]* getelementptr ([4 x i8]* null, i32 1) to i32))
109 define i8* @test13(i64 %A) {
110 %c = getelementptr [0 x i8]* bitcast ([32832 x i8]* @inbuf to [0 x i8]*), i64 0, i64 %A ; <i8*> [#uses=1]
112 ; CHECK: %c = getelementptr [32832 x i8]* @inbuf, i64 0, i64 %A
116 define i1 @test14(i8 %A) {
117 %c = bitcast i8 %A to i8 ; <i8> [#uses=1]
118 %X = icmp ult i8 %c, -128 ; <i1> [#uses=1]
120 ; CHECK: %X = icmp sgt i8 %A, -1
125 ; This just won't occur when there's no difference between ubyte and sbyte
126 ;bool %test15(ubyte %A) {
127 ; %c = cast ubyte %A to sbyte
128 ; %X = setlt sbyte %c, 0 ; setgt %A, 127
132 define i1 @test16(i32* %P) {
133 %c = icmp ne i32* %P, null ; <i1> [#uses=1]
135 ; CHECK: %c = icmp ne i32* %P, null
139 define i16 @test17(i1 %tmp3) {
140 %c = zext i1 %tmp3 to i32 ; <i32> [#uses=1]
141 %t86 = trunc i32 %c to i16 ; <i16> [#uses=1]
143 ; CHECK: %t86 = zext i1 %tmp3 to i16
144 ; CHECK: ret i16 %t86
147 define i16 @test18(i8 %tmp3) {
148 %c = sext i8 %tmp3 to i32 ; <i32> [#uses=1]
149 %t86 = trunc i32 %c to i16 ; <i16> [#uses=1]
151 ; CHECK: %t86 = sext i8 %tmp3 to i16
152 ; CHECK: ret i16 %t86
155 define i1 @test19(i32 %X) {
156 %c = sext i32 %X to i64 ; <i64> [#uses=1]
157 %Z = icmp slt i64 %c, 12345 ; <i1> [#uses=1]
159 ; CHECK: %Z = icmp slt i32 %X, 12345
163 define i1 @test20(i1 %B) {
164 %c = zext i1 %B to i32 ; <i32> [#uses=1]
165 %D = icmp slt i32 %c, -1 ; <i1> [#uses=1]
168 ; CHECK: ret i1 false
171 define i32 @test21(i32 %X) {
172 %c1 = trunc i32 %X to i8 ; <i8> [#uses=1]
173 ;; sext -> zext -> and -> nop
174 %c2 = sext i8 %c1 to i32 ; <i32> [#uses=1]
175 %RV = and i32 %c2, 255 ; <i32> [#uses=1]
177 ; CHECK: %c21 = and i32 %X, 255
178 ; CHECK: ret i32 %c21
181 define i32 @test22(i32 %X) {
182 %c1 = trunc i32 %X to i8 ; <i8> [#uses=1]
183 ;; sext -> zext -> and -> nop
184 %c2 = sext i8 %c1 to i32 ; <i32> [#uses=1]
185 %RV = shl i32 %c2, 24 ; <i32> [#uses=1]
187 ; CHECK: %RV = shl i32 %X, 24
191 define i32 @test23(i32 %X) {
192 ;; Turn into an AND even though X
193 %c1 = trunc i32 %X to i16 ; <i16> [#uses=1]
195 %c2 = zext i16 %c1 to i32 ; <i32> [#uses=1]
197 ; CHECK: %c2 = and i32 %X, 65535
201 define i1 @test24(i1 %C) {
202 %X = select i1 %C, i32 14, i32 1234 ; <i32> [#uses=1]
203 ;; Fold cast into select
204 %c = icmp ne i32 %X, 0 ; <i1> [#uses=1]
209 define void @test25(i32** %P) {
210 %c = bitcast i32** %P to float** ; <float**> [#uses=1]
211 ;; Fold cast into null
212 store float* null, float** %c
214 ; CHECK: store i32* null, i32** %P
218 define i32 @test26(float %F) {
219 ;; no need to cast from float->double.
220 %c = fpext float %F to double ; <double> [#uses=1]
221 %D = fptosi double %c to i32 ; <i32> [#uses=1]
223 ; CHECK: %D = fptosi float %F to i32
227 define [4 x float]* @test27([9 x [4 x float]]* %A) {
228 %c = bitcast [9 x [4 x float]]* %A to [4 x float]* ; <[4 x float]*> [#uses=1]
230 ; CHECK: %c = getelementptr inbounds [9 x [4 x float]]* %A, i64 0, i64 0
231 ; CHECK: ret [4 x float]* %c
234 define float* @test28([4 x float]* %A) {
235 %c = bitcast [4 x float]* %A to float* ; <float*> [#uses=1]
237 ; CHECK: %c = getelementptr inbounds [4 x float]* %A, i64 0, i64 0
238 ; CHECK: ret float* %c
241 define i32 @test29(i32 %c1, i32 %c2) {
242 %tmp1 = trunc i32 %c1 to i8 ; <i8> [#uses=1]
243 %tmp4.mask = trunc i32 %c2 to i8 ; <i8> [#uses=1]
244 %tmp = or i8 %tmp4.mask, %tmp1 ; <i8> [#uses=1]
245 %tmp10 = zext i8 %tmp to i32 ; <i32> [#uses=1]
247 ; CHECK: %tmp2 = or i32 %c2, %c1
248 ; CHECK: %tmp10 = and i32 %tmp2, 255
249 ; CHECK: ret i32 %tmp10
252 define i32 @test30(i32 %c1) {
253 %c2 = trunc i32 %c1 to i8 ; <i8> [#uses=1]
254 %c3 = xor i8 %c2, 1 ; <i8> [#uses=1]
255 %c4 = zext i8 %c3 to i32 ; <i32> [#uses=1]
257 ; CHECK: %c3 = and i32 %c1, 255
258 ; CHECK: %c4 = xor i32 %c3, 1
262 define i1 @test31(i64 %A) {
263 %B = trunc i64 %A to i32 ; <i32> [#uses=1]
264 %C = and i32 %B, 42 ; <i32> [#uses=1]
265 %D = icmp eq i32 %C, 10 ; <i1> [#uses=1]
267 ; CHECK: %C1 = and i64 %A, 42
268 ; CHECK: %D = icmp eq i64 %C1, 10
272 define void @test32(double** %tmp) {
273 %tmp8 = malloc [16 x i8] ; <[16 x i8]*> [#uses=1]
274 %tmp8.upgrd.1 = bitcast [16 x i8]* %tmp8 to double* ; <double*> [#uses=1]
275 store double* %tmp8.upgrd.1, double** %tmp
277 ; CHECK: %malloccall = tail call i8* @malloc(i32 ptrtoint ([16 x i8]* getelementptr ([16 x i8]* null, i32 1) to i32))
278 ; CHECK: %tmp8.upgrd.1 = bitcast i8* %malloccall to double*
279 ; CHECK: store double* %tmp8.upgrd.1, double** %tmp
283 define i32 @test33(i32 %c1) {
284 %x = bitcast i32 %c1 to float ; <float> [#uses=1]
285 %y = bitcast float %x to i32 ; <i32> [#uses=1]
290 define i16 @test34(i16 %a) {
291 %c1 = zext i16 %a to i32 ; <i32> [#uses=1]
292 %tmp21 = lshr i32 %c1, 8 ; <i32> [#uses=1]
293 %c2 = trunc i32 %tmp21 to i16 ; <i16> [#uses=1]
295 ; CHECK: %tmp21 = lshr i16 %a, 8
296 ; CHECK: ret i16 %tmp21
299 define i16 @test35(i16 %a) {
300 %c1 = bitcast i16 %a to i16 ; <i16> [#uses=1]
301 %tmp2 = lshr i16 %c1, 8 ; <i16> [#uses=1]
302 %c2 = bitcast i16 %tmp2 to i16 ; <i16> [#uses=1]
304 ; CHECK: %tmp2 = lshr i16 %a, 8
305 ; CHECK: ret i16 %tmp2
308 ; icmp sgt i32 %a, -1
310 define i1 @test36(i32 %a) {
312 %c = trunc i32 %b to i8
313 %d = icmp eq i8 %c, 0
315 ; CHECK: %d = icmp sgt i32 %a, -1
320 define i1 @test37(i32 %a) {
323 %d = trunc i32 %c to i8
324 %e = icmp eq i8 %d, 11
326 ; CHECK: ret i1 false
329 define i64 @test38(i32 %a) {
330 %1 = icmp eq i32 %a, -2
331 %2 = zext i1 %1 to i8
333 %4 = zext i8 %3 to i64
335 ; CHECK: %1 = icmp ne i32 %a, -2
336 ; CHECK: %2 = zext i1 %1 to i64