[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / InstCombine / constant-fold-address-space-pointer.ll
blobdafe3900fef3b75407d52f623e3f028198c4cf19
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instcombine %s -o - | FileCheck %s
3 target 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"
5 @g = addrspace(3) global i32 89
7 @const_zero_i8_as1 = addrspace(1) constant i8 0
8 @const_zero_i32_as1 = addrspace(1) constant i32 0
10 @const_zero_i8_as2 = addrspace(2) constant i8 0
11 @const_zero_i32_as2 = addrspace(2) constant i32 0
13 @const_zero_i8_as3 = addrspace(3) constant i8 0
14 @const_zero_i32_as3 = addrspace(3) constant i32 0
16 ; Test constant folding of inttoptr (ptrtoint constantexpr)
17 ; The intermediate integer size is the same as the pointer size
18 define ptr addrspace(3) @test_constant_fold_inttoptr_as_pointer_same_size() {
19 ; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_same_size(
20 ; CHECK-NEXT:    ret ptr addrspace(3) @const_zero_i32_as3
22   %x = ptrtoint ptr addrspace(3) @const_zero_i32_as3 to i32
23   %y = inttoptr i32 %x to ptr addrspace(3)
24   ret ptr addrspace(3) %y
27 ; The intermediate integer size is larger than the pointer size
28 define ptr addrspace(2) @test_constant_fold_inttoptr_as_pointer_smaller() {
29 ; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_smaller(
30 ; CHECK-NEXT:    ret ptr addrspace(2) @const_zero_i32_as2
32   %x = ptrtoint ptr addrspace(2) @const_zero_i32_as2 to i16
33   %y = inttoptr i16 %x to ptr addrspace(2)
34   ret ptr addrspace(2) %y
37 ; Different address spaces that are the same size, but they are
38 ; different so nothing should happen
39 define ptr addrspace(4) @test_constant_fold_inttoptr_as_pointer_smaller_different_as() {
40 ; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_smaller_different_as(
41 ; CHECK-NEXT:    ret ptr addrspace(4) inttoptr (i16 ptrtoint (ptr addrspace(3) @const_zero_i32_as3 to i16) to ptr addrspace(4))
43   %x = ptrtoint ptr addrspace(3) @const_zero_i32_as3 to i16
44   %y = inttoptr i16 %x to ptr addrspace(4)
45   ret ptr addrspace(4) %y
48 ; Make sure we don't introduce a bitcast between different sized
49 ; address spaces when folding this
50 define ptr addrspace(2) @test_constant_fold_inttoptr_as_pointer_smaller_different_size_as() {
51 ; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_smaller_different_size_as(
52 ; CHECK-NEXT:    ret ptr addrspace(2) inttoptr (i32 ptrtoint (ptr addrspace(3) @const_zero_i32_as3 to i32) to ptr addrspace(2))
54   %x = ptrtoint ptr addrspace(3) @const_zero_i32_as3 to i32
55   %y = inttoptr i32 %x to ptr addrspace(2)
56   ret ptr addrspace(2) %y
59 ; The intermediate integer size is too small, nothing should happen
60 define ptr addrspace(3) @test_constant_fold_inttoptr_as_pointer_larger() {
61 ; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_larger(
62 ; CHECK-NEXT:    ret ptr addrspace(3) inttoptr (i8 ptrtoint (ptr addrspace(3) @const_zero_i32_as3 to i8) to ptr addrspace(3))
64   %x = ptrtoint ptr addrspace(3) @const_zero_i32_as3 to i8
65   %y = inttoptr i8 %x to ptr addrspace(3)
66   ret ptr addrspace(3) %y
69 define i8 @const_fold_ptrtoint() {
70 ; CHECK-LABEL: @const_fold_ptrtoint(
71 ; CHECK-NEXT:    ret i8 4
73   ret i8 ptrtoint (ptr addrspace(2) inttoptr (i4 4 to ptr addrspace(2)) to i8)
76 ; Test that mask happens when the destination pointer is smaller than
77 ; the original
78 define i8 @const_fold_ptrtoint_mask() {
79 ; CHECK-LABEL: @const_fold_ptrtoint_mask(
80 ; CHECK-NEXT:    ret i8 1
82   ret i8 ptrtoint (ptr addrspace(3) inttoptr (i32 257 to ptr addrspace(3)) to i8)
85 ; Address space 0 is too small for the correct mask, should mask with
86 ; 64-bits instead of 32
87 define i64 @const_fold_ptrtoint_mask_small_as0() {
88 ; CHECK-LABEL: @const_fold_ptrtoint_mask_small_as0(
89 ; CHECK-NEXT:    ret i64 -1
91   ret i64 ptrtoint (ptr addrspace(1) inttoptr (i128 -1 to ptr addrspace(1)) to i64)
94 define ptr addrspace(3) @const_inttoptr() {
95 ; CHECK-LABEL: @const_inttoptr(
96 ; CHECK-NEXT:    ret ptr addrspace(3) inttoptr (i16 4 to ptr addrspace(3))
98   %p = inttoptr i16 4 to ptr addrspace(3)
99   ret ptr addrspace(3) %p
102 define i16 @const_ptrtoint() {
103 ; CHECK-LABEL: @const_ptrtoint(
104 ; CHECK-NEXT:    ret i16 ptrtoint (ptr addrspace(3) @g to i16)
106   %i = ptrtoint ptr addrspace(3) @g to i16
107   ret i16 %i
110 define i16 @const_inttoptr_ptrtoint() {
111 ; CHECK-LABEL: @const_inttoptr_ptrtoint(
112 ; CHECK-NEXT:    ret i16 9
114   ret i16 ptrtoint (ptr addrspace(3) inttoptr (i16 9 to ptr addrspace(3)) to i16)
117 define i1 @constant_fold_cmp_constantexpr_inttoptr() {
118 ; CHECK-LABEL: @constant_fold_cmp_constantexpr_inttoptr(
119 ; CHECK-NEXT:    ret i1 true
121   %x = icmp eq ptr addrspace(3) inttoptr (i16 0 to ptr addrspace(3)), null
122   ret i1 %x
125 define i1 @constant_fold_inttoptr_null(i16 %i) {
126 ; CHECK-LABEL: @constant_fold_inttoptr_null(
127 ; CHECK-NEXT:    ret i1 false
129   %x = icmp eq ptr addrspace(3) inttoptr (i16 99 to ptr addrspace(3)), inttoptr (i16 0 to ptr addrspace(3))
130   ret i1 %x
133 define i1 @constant_fold_ptrtoint_null() {
134 ; CHECK-LABEL: @constant_fold_ptrtoint_null(
135 ; CHECK-NEXT:    [[X:%.*]] = icmp eq i16 ptrtoint (ptr addrspace(3) @g to i16), 0
136 ; CHECK-NEXT:    ret i1 [[X]]
138   %x = icmp eq i16 ptrtoint (ptr addrspace(3) @g to i16), ptrtoint (ptr addrspace(3) null to i16)
139   ret i1 %x
142 define i1 @constant_fold_ptrtoint_null_2() {
143 ; CHECK-LABEL: @constant_fold_ptrtoint_null_2(
144 ; CHECK-NEXT:    [[X:%.*]] = icmp eq i16 0, ptrtoint (ptr addrspace(3) @g to i16)
145 ; CHECK-NEXT:    ret i1 [[X]]
147   %x = icmp eq i16 ptrtoint (ptr addrspace(3) null to i16), ptrtoint (ptr addrspace(3) @g to i16)
148   ret i1 %x
151 define i1 @constant_fold_ptrtoint() {
152 ; CHECK-LABEL: @constant_fold_ptrtoint(
153 ; CHECK-NEXT:    ret i1 true
155   %x = icmp eq i16 ptrtoint (ptr addrspace(3) @g to i16), ptrtoint (ptr addrspace(3) @g to i16)
156   ret i1 %x
159 define i1 @constant_fold_inttoptr() {
160 ; CHECK-LABEL: @constant_fold_inttoptr(
161 ; CHECK-NEXT:    ret i1 false
163   %x = icmp eq ptr addrspace(3) inttoptr (i16 99 to ptr addrspace(3)), inttoptr (i16 27 to ptr addrspace(3))
164   ret i1 %x
167 @g_float_as3 = addrspace(3) global float zeroinitializer
168 @g_v4f_as3 = addrspace(3) global <4 x float> zeroinitializer
170 define float @constant_fold_bitcast_ftoi_load() {
171 ; CHECK-LABEL: @constant_fold_bitcast_ftoi_load(
172 ; CHECK-NEXT:    [[A:%.*]] = load float, ptr addrspace(3) @g, align 4
173 ; CHECK-NEXT:    ret float [[A]]
175   %a = load float, ptr addrspace(3) @g, align 4
176   ret float %a
179 define i32 @constant_fold_bitcast_itof_load() {
180 ; CHECK-LABEL: @constant_fold_bitcast_itof_load(
181 ; CHECK-NEXT:    [[A:%.*]] = load i32, ptr addrspace(3) @g_float_as3, align 4
182 ; CHECK-NEXT:    ret i32 [[A]]
184   %a = load i32, ptr addrspace(3) @g_float_as3, align 4
185   ret i32 %a
188 define <4 x float> @constant_fold_bitcast_vector_as() {
189 ; CHECK-LABEL: @constant_fold_bitcast_vector_as(
190 ; CHECK-NEXT:    [[A:%.*]] = load <4 x float>, ptr addrspace(3) @g_v4f_as3, align 4
191 ; CHECK-NEXT:    ret <4 x float> [[A]]
193   %a = load <4 x float>, ptr addrspace(3) @g_v4f_as3, align 4
194   ret <4 x float> %a
197 @i32_array_as3 = addrspace(3) global [10 x i32] zeroinitializer
199 define i32 @test_cast_gep_small_indices_as() {
200 ; CHECK-LABEL: @test_cast_gep_small_indices_as(
201 ; CHECK-NEXT:    [[X:%.*]] = load i32, ptr addrspace(3) @i32_array_as3, align 4
202 ; CHECK-NEXT:    ret i32 [[X]]
204   %x = load i32, ptr addrspace(3) @i32_array_as3, align 4
205   ret i32 %x
208 %struct.foo = type { float, float, [4 x i32], ptr addrspace(3) }
210 @constant_fold_global_ptr = addrspace(3) global %struct.foo {
211   float 0.0,
212   float 0.0,
213   [4 x i32] zeroinitializer,
214   ptr addrspace(3) @i32_array_as3
217 define i32 @test_cast_gep_large_indices_as() {
218 ; CHECK-LABEL: @test_cast_gep_large_indices_as(
219 ; CHECK-NEXT:    [[X:%.*]] = load i32, ptr addrspace(3) @i32_array_as3, align 4
220 ; CHECK-NEXT:    ret i32 [[X]]
222   %x = load i32, ptr addrspace(3) @i32_array_as3, align 4
223   ret i32 %x
226 define i32 @test_constant_cast_gep_struct_indices_as() {
227 ; CHECK-LABEL: @test_constant_cast_gep_struct_indices_as(
228 ; CHECK-NEXT:    [[Y:%.*]] = load i32, ptr addrspace(3) getelementptr inbounds (i8, ptr addrspace(3) @constant_fold_global_ptr, i16 16), align 4
229 ; CHECK-NEXT:    ret i32 [[Y]]
231   %x = getelementptr %struct.foo, ptr addrspace(3) @constant_fold_global_ptr, i18 0, i32 2, i12 2
232   %y = load i32, ptr addrspace(3) %x, align 4
233   ret i32 %y
236 @constant_data_as3 = addrspace(3) constant [5 x i32] [i32 1, i32 2, i32 3, i32 4, i32 5]
238 define i32 @test_read_data_from_global_as3() {
239 ; CHECK-LABEL: @test_read_data_from_global_as3(
240 ; CHECK-NEXT:    ret i32 2
242   %x = getelementptr [5 x i32], ptr addrspace(3) @constant_data_as3, i32 0, i32 1
243   %y = load i32, ptr addrspace(3) %x, align 4
244   ret i32 %y
247 @a = addrspace(1) constant i32 9
248 @b = addrspace(1) constant i32 23
249 @c = addrspace(1) constant i32 34
250 @d = addrspace(1) constant i32 99
252 @ptr_array = addrspace(2) constant [4 x ptr addrspace(1)] [ ptr addrspace(1) @a, ptr addrspace(1) @b, ptr addrspace(1) @c, ptr addrspace(1) @d]
253 @indirect = addrspace(0) constant ptr addrspace(2) getelementptr inbounds ([4 x ptr addrspace(1)], ptr addrspace(2) @ptr_array, i1 0, i32 2)
255 define i32 @constant_through_array_as_ptrs() {
256 ; CHECK-LABEL: @constant_through_array_as_ptrs(
257 ; CHECK-NEXT:    ret i32 34
259   %p = load ptr addrspace(2), ptr addrspace(0) @indirect, align 4
260   %a = load ptr addrspace(1), ptr addrspace(2) %p, align 4
261   %b = load i32, ptr addrspace(1) %a, align 4
262   ret i32 %b
265 @shared_mem = external addrspace(3) global [0 x i8]
267 define float @canonicalize_addrspacecast(i32 %i) {
268 ; CHECK-LABEL: @canonicalize_addrspacecast(
269 ; CHECK-NEXT:    [[P:%.*]] = getelementptr inbounds float, ptr addrspacecast (ptr addrspace(3) @shared_mem to ptr), i32 [[I:%.*]]
270 ; CHECK-NEXT:    [[V:%.*]] = load float, ptr [[P]], align 4
271 ; CHECK-NEXT:    ret float [[V]]
273   %p = getelementptr inbounds float, ptr addrspacecast (ptr addrspace(3) @shared_mem to ptr), i32 %i
274   %v = load float, ptr %p
275   ret float %v