• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
4
5target datalayout = "p:32:32-p1:32:32-p2:16:16"
6
7@global = global i8 0
8
9; This shouldn't convert to getelementptr because the relationship
10; between the arithmetic and the layout of allocated memory is
11; entirely unknown.
12
13define 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]]
19;
20  %tc = ptrtoint i8* %t to i32
21  %ta = add i32 %tc, 32
22  %tv = inttoptr i32 %ta to i8*
23  ret i8* %tv
24}
25
26; These casts should be folded away.
27
28define 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]]
32;
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
37}
38
39; These casts should be folded away.
40
41define 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]]
45;
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
50}
51
52; These casts should be folded away.
53
54define 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]]
58;
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
63}
64
65; These casts should not be folded away.
66
67define 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]]
73;
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
78}
79
80; These casts should not be folded away.
81
82define 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]]
87;
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
92}
93
94; These casts should also be folded away.
95
96define i1 @test3(i8* %a) {
97; CHECK-LABEL: @test3(
98; CHECK-NEXT:    [[R:%.*]] = icmp eq i8* [[A:%.*]], @global
99; CHECK-NEXT:    ret i1 [[R]]
100;
101  %ta = ptrtoint i8* %a to i32
102  %r = icmp eq i32 %ta, ptrtoint (i8* @global to i32)
103  ret i1 %r
104}
105
106define i1 @test4(i32 %A) {
107; CHECK-LABEL: @test4(
108; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[A:%.*]], 0
109; CHECK-NEXT:    ret i1 [[C]]
110;
111  %B = inttoptr i32 %A to i8*
112  %C = icmp eq i8* %B, null
113  ret i1 %C
114}
115
116define 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]]
120;
121  %B = inttoptr i16 %A to i8 addrspace(2)*
122  %C = icmp eq i8 addrspace(2)* %B, null
123  ret i1 %C
124}
125
126
127; Pulling the cast out of the load allows us to eliminate the load, and then
128; the whole array.
129
130        %op = type { float }
131        %unop = type { i32 }
132@Array = internal constant [1 x %op* (%op*)*] [ %op* (%op*)* @foo ]
133
134declare %op* @foo(%op* %X)
135
136define %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]]
141;
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
145}
146
147
148
149; InstCombine can not 'load (cast P)' -> cast (load P)' if the cast changes
150; the address space.
151
152define 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]]
158;
159entry:
160  %arrayidx223 = addrspacecast i8 addrspace(1)* %source to i8*
161  %t4 = load i8, i8* %arrayidx223
162  ret i8 %t4
163}
164
165define <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]]
170;
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
175}
176
177define <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]]
183;
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
188}
189
190define <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]]
196;
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
201}
202
203define <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]]
210;
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
215}
216
217declare void @use(<2 x i32*>)
218
219define <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]]
226;
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
232}
233
234define <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]]
241;
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
247}
248