[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / InstCombine / cast_ptr.ll
blob1b46e3666c9d05879a154e462f3f488d094b6635
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; Tests to make sure elimination of casts is working correctly
3 ; RUN: opt < %s -instcombine -S | FileCheck %s
5 target datalayout = "p:32:32-p1:32:32-p2:16:16"
7 @global = global i8 0
9 ; This shouldn't convert to getelementptr because the relationship
10 ; between the arithmetic and the layout of allocated memory is
11 ; entirely unknown.
13 define i8* @test1(i8* %t) {
14 ; CHECK-LABEL: @test1(
15 ; CHECK-NEXT:    [[TC:%.*]] = ptrtoint i8* [[T:%.*]] to i32
16 ; CHECK-NEXT:    [[TA:%.*]] = add i32 [[TC]], 32
17 ; CHECK-NEXT:    [[TV:%.*]] = inttoptr i32 [[TA]] to i8*
18 ; CHECK-NEXT:    ret i8* [[TV]]
20   %tc = ptrtoint i8* %t to i32
21   %ta = add i32 %tc, 32
22   %tv = inttoptr i32 %ta to i8*
23   ret i8* %tv
26 ; These casts should be folded away.
28 define i1 @test2(i8* %a, i8* %b) {
29 ; CHECK-LABEL: @test2(
30 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8* [[A:%.*]], [[B:%.*]]
31 ; CHECK-NEXT:    ret i1 [[R]]
33   %ta = ptrtoint i8* %a to i32
34   %tb = ptrtoint i8* %b to i32
35   %r = icmp eq i32 %ta, %tb
36   ret i1 %r
39 ; These casts should be folded away.
41 define i1 @test2_as2_same_int(i8 addrspace(2)* %a, i8 addrspace(2)* %b) {
42 ; CHECK-LABEL: @test2_as2_same_int(
43 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 addrspace(2)* [[A:%.*]], [[B:%.*]]
44 ; CHECK-NEXT:    ret i1 [[R]]
46   %ta = ptrtoint i8 addrspace(2)* %a to i16
47   %tb = ptrtoint i8 addrspace(2)* %b to i16
48   %r = icmp eq i16 %ta, %tb
49   ret i1 %r
52 ; These casts should be folded away.
54 define i1 @test2_as2_larger(i8 addrspace(2)* %a, i8 addrspace(2)* %b) {
55 ; CHECK-LABEL: @test2_as2_larger(
56 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 addrspace(2)* [[A:%.*]], [[B:%.*]]
57 ; CHECK-NEXT:    ret i1 [[R]]
59   %ta = ptrtoint i8 addrspace(2)* %a to i32
60   %tb = ptrtoint i8 addrspace(2)* %b to i32
61   %r = icmp eq i32 %ta, %tb
62   ret i1 %r
65 ; These casts should not be folded away.
67 define i1 @test2_diff_as(i8* %p, i8 addrspace(1)* %q) {
68 ; CHECK-LABEL: @test2_diff_as(
69 ; CHECK-NEXT:    [[I0:%.*]] = ptrtoint i8* [[P:%.*]] to i32
70 ; CHECK-NEXT:    [[I1:%.*]] = ptrtoint i8 addrspace(1)* [[Q:%.*]] to i32
71 ; CHECK-NEXT:    [[R0:%.*]] = icmp sge i32 [[I0]], [[I1]]
72 ; CHECK-NEXT:    ret i1 [[R0]]
74   %i0 = ptrtoint i8* %p to i32
75   %i1 = ptrtoint i8 addrspace(1)* %q to i32
76   %r0 = icmp sge i32 %i0, %i1
77   ret i1 %r0
80 ; These casts should not be folded away.
82 define i1 @test2_diff_as_global(i8 addrspace(1)* %q) {
83 ; CHECK-LABEL: @test2_diff_as_global(
84 ; CHECK-NEXT:    [[I1:%.*]] = ptrtoint i8 addrspace(1)* [[Q:%.*]] to i32
85 ; CHECK-NEXT:    [[R0:%.*]] = icmp sge i32 [[I1]], ptrtoint (i8* @global to i32)
86 ; CHECK-NEXT:    ret i1 [[R0]]
88   %i0 = ptrtoint i8* @global to i32
89   %i1 = ptrtoint i8 addrspace(1)* %q to i32
90   %r0 = icmp sge i32 %i1, %i0
91   ret i1 %r0
94 ; These casts should also be folded away.
96 define i1 @test3(i8* %a) {
97 ; CHECK-LABEL: @test3(
98 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8* [[A:%.*]], @global
99 ; CHECK-NEXT:    ret i1 [[R]]
101   %ta = ptrtoint i8* %a to i32
102   %r = icmp eq i32 %ta, ptrtoint (i8* @global to i32)
103   ret i1 %r
106 define i1 @test4(i32 %A) {
107 ; CHECK-LABEL: @test4(
108 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[A:%.*]], 0
109 ; CHECK-NEXT:    ret i1 [[C]]
111   %B = inttoptr i32 %A to i8*
112   %C = icmp eq i8* %B, null
113   ret i1 %C
116 define i1 @test4_as2(i16 %A) {
117 ; CHECK-LABEL: @test4_as2(
118 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i16 [[A:%.*]], 0
119 ; CHECK-NEXT:    ret i1 [[C]]
121   %B = inttoptr i16 %A to i8 addrspace(2)*
122   %C = icmp eq i8 addrspace(2)* %B, null
123   ret i1 %C
127 ; Pulling the cast out of the load allows us to eliminate the load, and then
128 ; the whole array.
130   %op = type { float }
131   %unop = type { i32 }
132 @Array = internal constant [1 x %op* (%op*)*] [ %op* (%op*)* @foo ]
134 declare %op* @foo(%op* %X)
136 define %unop* @test5(%op* %O) {
137 ; CHECK-LABEL: @test5(
138 ; CHECK-NEXT:    [[T_2:%.*]] = call %op* @foo(%op* [[O:%.*]])
139 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast %op* [[T_2]] to %unop*
140 ; CHECK-NEXT:    ret %unop* [[TMP1]]
142   %t = load %unop* (%op*)*, %unop* (%op*)** bitcast ([1 x %op* (%op*)*]* @Array to %unop* (%op*)**); <%unop* (%op*)*> [#uses=1]
143   %t.2 = call %unop* %t( %op* %O )
144   ret %unop* %t.2
149 ; InstCombine can not 'load (cast P)' -> cast (load P)' if the cast changes
150 ; the address space.
152 define i8 @test6(i8 addrspace(1)* %source) {
153 ; CHECK-LABEL: @test6(
154 ; CHECK-NEXT:  entry:
155 ; CHECK-NEXT:    [[ARRAYIDX223:%.*]] = addrspacecast i8 addrspace(1)* [[SOURCE:%.*]] to i8*
156 ; CHECK-NEXT:    [[T4:%.*]] = load i8, i8* [[ARRAYIDX223]], align 1
157 ; CHECK-NEXT:    ret i8 [[T4]]
159 entry:
160   %arrayidx223 = addrspacecast i8 addrspace(1)* %source to i8*
161   %t4 = load i8, i8* %arrayidx223
162   ret i8 %t4
165 define <2 x i32> @insertelt(<2 x i32> %x, i32* %p, i133 %index) {
166 ; CHECK-LABEL: @insertelt(
167 ; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint i32* [[P:%.*]] to i32
168 ; CHECK-NEXT:    [[R:%.*]] = insertelement <2 x i32> [[X:%.*]], i32 [[TMP1]], i133 [[INDEX:%.*]]
169 ; CHECK-NEXT:    ret <2 x i32> [[R]]
171   %v = inttoptr <2 x i32> %x to <2 x i32*>
172   %i = insertelement <2 x i32*> %v, i32* %p, i133 %index
173   %r = ptrtoint <2 x i32*> %i to <2 x i32>
174   ret <2 x i32> %r
177 define <2 x i32> @insertelt_intptr_trunc(<2 x i64> %x, i32* %p) {
178 ; CHECK-LABEL: @insertelt_intptr_trunc(
179 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i64> [[X:%.*]] to <2 x i32>
180 ; CHECK-NEXT:    [[TMP2:%.*]] = ptrtoint i32* [[P:%.*]] to i32
181 ; CHECK-NEXT:    [[R:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[TMP2]], i32 0
182 ; CHECK-NEXT:    ret <2 x i32> [[R]]
184   %v = inttoptr <2 x i64> %x to <2 x i32*>
185   %i = insertelement <2 x i32*> %v, i32* %p, i32 0
186   %r = ptrtoint <2 x i32*> %i to <2 x i32>
187   ret <2 x i32> %r
190 define <2 x i32> @insertelt_intptr_zext(<2 x i8> %x, i32* %p) {
191 ; CHECK-LABEL: @insertelt_intptr_zext(
192 ; CHECK-NEXT:    [[TMP1:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i32>
193 ; CHECK-NEXT:    [[TMP2:%.*]] = ptrtoint i32* [[P:%.*]] to i32
194 ; CHECK-NEXT:    [[R:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[TMP2]], i32 1
195 ; CHECK-NEXT:    ret <2 x i32> [[R]]
197   %v = inttoptr <2 x i8> %x to <2 x i32*>
198   %i = insertelement <2 x i32*> %v, i32* %p, i32 1
199   %r = ptrtoint <2 x i32*> %i to <2 x i32>
200   ret <2 x i32> %r
203 define <2 x i64> @insertelt_intptr_zext_zext(<2 x i8> %x, i32* %p) {
204 ; CHECK-LABEL: @insertelt_intptr_zext_zext(
205 ; CHECK-NEXT:    [[TMP1:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i32>
206 ; CHECK-NEXT:    [[TMP2:%.*]] = ptrtoint i32* [[P:%.*]] to i32
207 ; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[TMP2]], i32 0
208 ; CHECK-NEXT:    [[R:%.*]] = zext <2 x i32> [[TMP3]] to <2 x i64>
209 ; CHECK-NEXT:    ret <2 x i64> [[R]]
211   %v = inttoptr <2 x i8> %x to <2 x i32*>
212   %i = insertelement <2 x i32*> %v, i32* %p, i32 0
213   %r = ptrtoint <2 x i32*> %i to <2 x i64>
214   ret <2 x i64> %r
217 declare void @use(<2 x i32*>)
219 define <2 x i32> @insertelt_extra_use1(<2 x i32> %x, i32* %p) {
220 ; CHECK-LABEL: @insertelt_extra_use1(
221 ; CHECK-NEXT:    [[V:%.*]] = inttoptr <2 x i32> [[X:%.*]] to <2 x i32*>
222 ; CHECK-NEXT:    call void @use(<2 x i32*> [[V]])
223 ; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint i32* [[P:%.*]] to i32
224 ; CHECK-NEXT:    [[R:%.*]] = insertelement <2 x i32> [[X]], i32 [[TMP1]], i32 0
225 ; CHECK-NEXT:    ret <2 x i32> [[R]]
227   %v = inttoptr <2 x i32> %x to <2 x i32*>
228   call void @use(<2 x i32*> %v)
229   %i = insertelement <2 x i32*> %v, i32* %p, i32 0
230   %r = ptrtoint <2 x i32*> %i to <2 x i32>
231   ret <2 x i32> %r
234 define <2 x i32> @insertelt_extra_use2(<2 x i32> %x, i32* %p) {
235 ; CHECK-LABEL: @insertelt_extra_use2(
236 ; CHECK-NEXT:    [[V:%.*]] = inttoptr <2 x i32> [[X:%.*]] to <2 x i32*>
237 ; CHECK-NEXT:    [[I:%.*]] = insertelement <2 x i32*> [[V]], i32* [[P:%.*]], i32 0
238 ; CHECK-NEXT:    call void @use(<2 x i32*> [[I]])
239 ; CHECK-NEXT:    [[R:%.*]] = ptrtoint <2 x i32*> [[I]] to <2 x i32>
240 ; CHECK-NEXT:    ret <2 x i32> [[R]]
242   %v = inttoptr <2 x i32> %x to <2 x i32*>
243   %i = insertelement <2 x i32*> %v, i32* %p, i32 0
244   call void @use(<2 x i32*> %i)
245   %r = ptrtoint <2 x i32*> %i to <2 x i32>
246   ret <2 x i32> %r