blob: 7fac78a40f569f47b1293f4f3fa1a05bcac453dd [file] [log] [blame]
Matt Arsenault7a960a82013-08-20 21:20:04 +00001; RUN: opt -S -instcombine %s -o - | FileCheck %s
2target datalayout = "e-p:32:32:32-p1:64:64:64-p2:8:8:8-p3:16:16:16-p4:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:32"
3
4@g = addrspace(3) global i32 89
5
6@const_zero_i8_as1 = addrspace(1) constant i8 0
7@const_zero_i32_as1 = addrspace(1) constant i32 0
8
9@const_zero_i8_as2 = addrspace(2) constant i8 0
10@const_zero_i32_as2 = addrspace(2) constant i32 0
11
12@const_zero_i8_as3 = addrspace(3) constant i8 0
13@const_zero_i32_as3 = addrspace(3) constant i32 0
14
15; Test constant folding of inttoptr (ptrtoint constantexpr)
16; The intermediate integer size is the same as the pointer size
17define i32 addrspace(3)* @test_constant_fold_inttoptr_as_pointer_same_size() {
18; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_same_size(
19; CHECK-NEXT: ret i32 addrspace(3)* @const_zero_i32_as3
20 %x = ptrtoint i32 addrspace(3)* @const_zero_i32_as3 to i32
21 %y = inttoptr i32 %x to i32 addrspace(3)*
22 ret i32 addrspace(3)* %y
23}
24
25; The intermediate integer size is larger than the pointer size
26define i32 addrspace(2)* @test_constant_fold_inttoptr_as_pointer_smaller() {
27; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_smaller(
28; CHECK-NEXT: ret i32 addrspace(2)* @const_zero_i32_as2
29 %x = ptrtoint i32 addrspace(2)* @const_zero_i32_as2 to i16
30 %y = inttoptr i16 %x to i32 addrspace(2)*
31 ret i32 addrspace(2)* %y
32}
33
34; Different address spaces that are the same size, but they are
Matt Arsenaultb03bd4d2013-11-15 01:34:59 +000035; different so nothing should happen
Matt Arsenault7a960a82013-08-20 21:20:04 +000036define i32 addrspace(4)* @test_constant_fold_inttoptr_as_pointer_smaller_different_as() {
37; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_smaller_different_as(
Matt Arsenaultb03bd4d2013-11-15 01:34:59 +000038; CHECK-NEXT: ret i32 addrspace(4)* inttoptr (i16 ptrtoint (i32 addrspace(3)* @const_zero_i32_as3 to i16) to i32 addrspace(4)*)
Matt Arsenault7a960a82013-08-20 21:20:04 +000039 %x = ptrtoint i32 addrspace(3)* @const_zero_i32_as3 to i16
40 %y = inttoptr i16 %x to i32 addrspace(4)*
41 ret i32 addrspace(4)* %y
42}
43
44; Make sure we don't introduce a bitcast between different sized
45; address spaces when folding this
46define i32 addrspace(2)* @test_constant_fold_inttoptr_as_pointer_smaller_different_size_as() {
47; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_smaller_different_size_as(
48; CHECK-NEXT: ret i32 addrspace(2)* inttoptr (i32 ptrtoint (i32 addrspace(3)* @const_zero_i32_as3 to i32) to i32 addrspace(2)*)
49 %x = ptrtoint i32 addrspace(3)* @const_zero_i32_as3 to i32
50 %y = inttoptr i32 %x to i32 addrspace(2)*
51 ret i32 addrspace(2)* %y
52}
53
54; The intermediate integer size is too small, nothing should happen
55define i32 addrspace(3)* @test_constant_fold_inttoptr_as_pointer_larger() {
56; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_larger(
57; CHECK-NEXT: ret i32 addrspace(3)* inttoptr (i8 ptrtoint (i32 addrspace(3)* @const_zero_i32_as3 to i8) to i32 addrspace(3)*)
58 %x = ptrtoint i32 addrspace(3)* @const_zero_i32_as3 to i8
59 %y = inttoptr i8 %x to i32 addrspace(3)*
60 ret i32 addrspace(3)* %y
61}
62
63define i8 @const_fold_ptrtoint() {
64; CHECK-LABEL: @const_fold_ptrtoint(
65; CHECK-NEXT: ret i8 4
66 ret i8 ptrtoint (i32 addrspace(2)* inttoptr (i4 4 to i32 addrspace(2)*) to i8)
67}
68
69; Test that mask happens when the destination pointer is smaller than
70; the original
71define i8 @const_fold_ptrtoint_mask() {
72; CHECK-LABEL: @const_fold_ptrtoint_mask(
73; CHECK-NEXT: ret i8 1
74 ret i8 ptrtoint (i32 addrspace(3)* inttoptr (i32 257 to i32 addrspace(3)*) to i8)
75}
76
Matt Arsenaultd12e8022013-09-17 23:23:16 +000077; Address space 0 is too small for the correct mask, should mask with
78; 64-bits instead of 32
79define i64 @const_fold_ptrtoint_mask_small_as0() {
80; CHECK-LABEL: @const_fold_ptrtoint_mask_small_as0(
81; CHECK: ret i64 -1
82 ret i64 ptrtoint (i32 addrspace(1)* inttoptr (i128 -1 to i32 addrspace(1)*) to i64)
83}
84
Matt Arsenault7a960a82013-08-20 21:20:04 +000085define i32 addrspace(3)* @const_inttoptr() {
86; CHECK-LABEL: @const_inttoptr(
87; CHECK-NEXT: ret i32 addrspace(3)* inttoptr (i16 4 to i32 addrspace(3)*)
88 %p = inttoptr i16 4 to i32 addrspace(3)*
89 ret i32 addrspace(3)* %p
90}
91
92define i16 @const_ptrtoint() {
93; CHECK-LABEL: @const_ptrtoint(
94; CHECK-NEXT: ret i16 ptrtoint (i32 addrspace(3)* @g to i16)
95 %i = ptrtoint i32 addrspace(3)* @g to i16
96 ret i16 %i
97}
98
99define i16 @const_inttoptr_ptrtoint() {
100; CHECK-LABEL: @const_inttoptr_ptrtoint(
101; CHECK-NEXT: ret i16 9
102 ret i16 ptrtoint (i32 addrspace(3)* inttoptr (i16 9 to i32 addrspace(3)*) to i16)
103}
104
105define i1 @constant_fold_cmp_constantexpr_inttoptr() {
106; CHECK-LABEL: @constant_fold_cmp_constantexpr_inttoptr(
107; CHECK-NEXT: ret i1 true
108 %x = icmp eq i32 addrspace(3)* inttoptr (i16 0 to i32 addrspace(3)*), null
109 ret i1 %x
110}
111
112define i1 @constant_fold_inttoptr_null(i16 %i) {
113; CHECK-LABEL: @constant_fold_inttoptr_null(
114; CHECK-NEXT: ret i1 false
115 %x = icmp eq i32 addrspace(3)* inttoptr (i16 99 to i32 addrspace(3)*), inttoptr (i16 0 to i32 addrspace(3)*)
116 ret i1 %x
117}
118
119define i1 @constant_fold_ptrtoint_null() {
120; CHECK-LABEL: @constant_fold_ptrtoint_null(
121; CHECK-NEXT: ret i1 false
122 %x = icmp eq i16 ptrtoint (i32 addrspace(3)* @g to i16), ptrtoint (i32 addrspace(3)* null to i16)
123 ret i1 %x
124}
125
126define i1 @constant_fold_ptrtoint_null_2() {
127; CHECK-LABEL: @constant_fold_ptrtoint_null_2(
128; CHECK-NEXT: ret i1 false
129 %x = icmp eq i16 ptrtoint (i32 addrspace(3)* null to i16), ptrtoint (i32 addrspace(3)* @g to i16)
130 ret i1 %x
131}
132
133define i1 @constant_fold_ptrtoint() {
134; CHECK-LABEL: @constant_fold_ptrtoint(
135; CHECK-NEXT: ret i1 true
136 %x = icmp eq i16 ptrtoint (i32 addrspace(3)* @g to i16), ptrtoint (i32 addrspace(3)* @g to i16)
137 ret i1 %x
138}
139
140define i1 @constant_fold_inttoptr() {
141; CHECK-LABEL: @constant_fold_inttoptr(
142; CHECK-NEXT: ret i1 false
143 %x = icmp eq i32 addrspace(3)* inttoptr (i16 99 to i32 addrspace(3)*), inttoptr (i16 27 to i32 addrspace(3)*)
144 ret i1 %x
145}
146
147@g_float_as3 = addrspace(3) global float zeroinitializer
148@g_v4f_as3 = addrspace(3) global <4 x float> zeroinitializer
149
150define float @constant_fold_bitcast_ftoi_load() {
151; CHECK-LABEL: @constant_fold_bitcast_ftoi_load(
152; CHECK: load float addrspace(3)* bitcast (i32 addrspace(3)* @g to float addrspace(3)*), align 4
153 %a = load float addrspace(3)* bitcast (i32 addrspace(3)* @g to float addrspace(3)*), align 4
154 ret float %a
155}
156
157define i32 @constant_fold_bitcast_itof_load() {
158; CHECK-LABEL: @constant_fold_bitcast_itof_load(
159; CHECK: load i32 addrspace(3)* bitcast (float addrspace(3)* @g_float_as3 to i32 addrspace(3)*), align 4
160 %a = load i32 addrspace(3)* bitcast (float addrspace(3)* @g_float_as3 to i32 addrspace(3)*), align 4
161 ret i32 %a
162}
163
164define <4 x i32> @constant_fold_bitcast_vector_as() {
165; CHECK-LABEL: @constant_fold_bitcast_vector_as(
166; CHECK: load <4 x float> addrspace(3)* @g_v4f_as3, align 16
167; CHECK: bitcast <4 x float> %1 to <4 x i32>
168 %a = load <4 x i32> addrspace(3)* bitcast (<4 x float> addrspace(3)* @g_v4f_as3 to <4 x i32> addrspace(3)*), align 4
169 ret <4 x i32> %a
170}
171
172@i32_array_as3 = addrspace(3) global [10 x i32] zeroinitializer
173
174define i32 @test_cast_gep_small_indices_as() {
175; CHECK-LABEL: @test_cast_gep_small_indices_as(
176; CHECK: load i32 addrspace(3)* getelementptr inbounds ([10 x i32] addrspace(3)* @i32_array_as3, i16 0, i16 0), align 16
177 %p = getelementptr [10 x i32] addrspace(3)* @i32_array_as3, i7 0, i7 0
178 %x = load i32 addrspace(3)* %p, align 4
179 ret i32 %x
180}
181
182%struct.foo = type { float, float, [4 x i32], i32 addrspace(3)* }
183
184@constant_fold_global_ptr = addrspace(3) global %struct.foo {
185 float 0.0,
186 float 0.0,
187 [4 x i32] zeroinitializer,
188 i32 addrspace(3)* getelementptr ([10 x i32] addrspace(3)* @i32_array_as3, i64 0, i64 0)
189}
190
191define i32 @test_cast_gep_large_indices_as() {
192; CHECK-LABEL: @test_cast_gep_large_indices_as(
193; CHECK: load i32 addrspace(3)* getelementptr inbounds ([10 x i32] addrspace(3)* @i32_array_as3, i16 0, i16 0), align 16
194 %p = getelementptr [10 x i32] addrspace(3)* @i32_array_as3, i64 0, i64 0
195 %x = load i32 addrspace(3)* %p, align 4
196 ret i32 %x
197}
198
199define i32 @test_constant_cast_gep_struct_indices_as() {
200; CHECK-LABEL: @test_constant_cast_gep_struct_indices_as(
201; CHECK: load i32 addrspace(3)* getelementptr inbounds (%struct.foo addrspace(3)* @constant_fold_global_ptr, i16 0, i32 2, i16 2), align 8
202 %x = getelementptr %struct.foo addrspace(3)* @constant_fold_global_ptr, i18 0, i32 2, i12 2
203 %y = load i32 addrspace(3)* %x, align 4
204 ret i32 %y
205}
206
207@constant_data_as3 = addrspace(3) constant [5 x i32] [i32 1, i32 2, i32 3, i32 4, i32 5]
208
209define i32 @test_read_data_from_global_as3() {
210; CHECK-LABEL: @test_read_data_from_global_as3(
211; CHECK-NEXT: ret i32 2
212 %x = getelementptr [5 x i32] addrspace(3)* @constant_data_as3, i32 0, i32 1
213 %y = load i32 addrspace(3)* %x, align 4
214 ret i32 %y
215}
216
217@a = addrspace(1) constant i32 9
218@b = addrspace(1) constant i32 23
219@c = addrspace(1) constant i32 34
220@d = addrspace(1) constant i32 99
221
222@ptr_array = addrspace(2) constant [4 x i32 addrspace(1)*] [ i32 addrspace(1)* @a, i32 addrspace(1)* @b, i32 addrspace(1)* @c, i32 addrspace(1)* @d]
223@indirect = addrspace(0) constant i32 addrspace(1)* addrspace(2)* getelementptr inbounds ([4 x i32 addrspace(1)*] addrspace(2)* @ptr_array, i1 0, i32 2)
224
225define i32 @constant_through_array_as_ptrs() {
226; CHECK-LABEL: @constant_through_array_as_ptrs(
227; CHECK-NEXT: ret i32 34
228 %p = load i32 addrspace(1)* addrspace(2)* addrspace(0)* @indirect, align 4
229 %a = load i32 addrspace(1)* addrspace(2)* %p, align 4
230 %b = load i32 addrspace(1)* %a, align 4
231 ret i32 %b
232}
Jingyue Wubaabe502014-06-15 21:40:57 +0000233
234@shared_mem = external addrspace(3) global [0 x i8]
235
236define float @canonicalize_addrspacecast(i32 %i) {
237; CHECK-LABEL: @canonicalize_addrspacecast
238; CHECK-NEXT: getelementptr inbounds float* addrspacecast (float addrspace(3)* bitcast ([0 x i8] addrspace(3)* @shared_mem to float addrspace(3)*) to float*), i32 %i
239 %p = getelementptr inbounds float* addrspacecast ([0 x i8] addrspace(3)* @shared_mem to float*), i32 %i
240 %v = load float* %p
241 ret float %v
242}