[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / Transforms / SROA / addrspacecast.ll
blobd60f92b8ed01f482384930dfa1f5dd127e7a7410
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -sroa -S | FileCheck %s
3 ; RUN: opt < %s -passes=sroa -S | FileCheck %s
5 target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
7 declare void @llvm.memcpy.p0i8.p1i8.i32(i8* nocapture writeonly, i8 addrspace(1)* nocapture readonly, i32, i1 immarg) #0
8 declare void @llvm.memcpy.p1i8.p0i8.i32(i8 addrspace(1)* nocapture writeonly, i8* nocapture readonly, i32, i1 immarg) #0
10 define i64 @alloca_addrspacecast_bitcast(i64 %X) {
11 ; CHECK-LABEL: @alloca_addrspacecast_bitcast(
12 ; CHECK-NEXT:  entry:
13 ; CHECK-NEXT:    ret i64 [[X:%.*]]
15 entry:
16   %A = alloca [8 x i8]
17   %A.cast = addrspacecast [8 x i8]* %A to [8 x i8] addrspace(1)*
18   %B = bitcast [8 x i8] addrspace(1)* %A.cast to i64 addrspace(1)*
19   store i64 %X, i64 addrspace(1)* %B
20   %Z = load i64, i64 addrspace(1)* %B
21   ret i64 %Z
24 define i64 @alloca_bitcast_addrspacecast(i64 %X) {
25 ; CHECK-LABEL: @alloca_bitcast_addrspacecast(
26 ; CHECK-NEXT:  entry:
27 ; CHECK-NEXT:    ret i64 [[X:%.*]]
29 entry:
30   %A = alloca [8 x i8]
31   %A.cast = bitcast [8 x i8]* %A to i64*
32   %B = addrspacecast i64* %A.cast to i64 addrspace(1)*
33   store i64 %X, i64 addrspace(1)* %B
34   %Z = load i64, i64 addrspace(1)* %B
35   ret i64 %Z
38 define i64 @alloca_addrspacecast_gep(i64 %X) {
39 ; CHECK-LABEL: @alloca_addrspacecast_gep(
40 ; CHECK-NEXT:  entry:
41 ; CHECK-NEXT:    ret i64 [[X:%.*]]
43 entry:
44   %A.as0 = alloca [256 x i8], align 4
46   %gepA.as0 = getelementptr [256 x i8], [256 x i8]* %A.as0, i16 0, i16 32
47   %gepA.as0.bc = bitcast i8* %gepA.as0 to i64*
48   store i64 %X, i64* %gepA.as0.bc, align 4
50   %A.as1 = addrspacecast [256 x i8]* %A.as0 to [256 x i8] addrspace(1)*
51   %gepA.as1 = getelementptr [256 x i8], [256 x i8] addrspace(1)* %A.as1, i16 0, i16 32
52   %gepA.as1.bc = bitcast i8 addrspace(1)* %gepA.as1 to i64 addrspace(1)*
53   %Z = load i64, i64 addrspace(1)* %gepA.as1.bc, align 4
55   ret i64 %Z
58 define i64 @alloca_gep_addrspacecast(i64 %X) {
59 ; CHECK-LABEL: @alloca_gep_addrspacecast(
60 ; CHECK-NEXT:  entry:
61 ; CHECK-NEXT:    ret i64 [[X:%.*]]
63 entry:
64   %A.as0 = alloca [256 x i8], align 4
66   %gepA.as0 = getelementptr [256 x i8], [256 x i8]* %A.as0, i16 0, i16 32
67   %gepA.as0.bc = bitcast i8* %gepA.as0 to i64*
68   store i64 %X, i64* %gepA.as0.bc, align 4
70   %gepA.as1.bc = addrspacecast i64* %gepA.as0.bc to i64 addrspace(1)*
71   %Z = load i64, i64 addrspace(1)* %gepA.as1.bc, align 4
72   ret i64 %Z
75 define i64 @alloca_gep_addrspacecast_gep(i64 %X) {
76 ; CHECK-LABEL: @alloca_gep_addrspacecast_gep(
77 ; CHECK-NEXT:  entry:
78 ; CHECK-NEXT:    ret i64 [[X:%.*]]
80 entry:
81   %A.as0 = alloca [256 x i8], align 4
83   %gepA.as0 = getelementptr [256 x i8], [256 x i8]* %A.as0, i16 0, i16 32
84   %gepA.as0.bc = bitcast i8* %gepA.as0 to i64*
85   store i64 %X, i64* %gepA.as0.bc, align 4
88   %gepB.as0 = getelementptr [256 x i8], [256 x i8]* %A.as0, i16 0, i16 16
89   %gepB.as1 = addrspacecast i8* %gepB.as0 to i8 addrspace(1)*
90   %gepC.as1 = getelementptr i8, i8 addrspace(1)* %gepB.as1, i16 16
91   %gepC.as1.bc = bitcast i8 addrspace(1)* %gepC.as1 to i64 addrspace(1)*
92   %Z = load i64, i64 addrspace(1)* %gepC.as1.bc, align 4
94   ret i64 %Z
97 define i64 @getAdjustedPtr_addrspacecast_gep([32 x i8]* %x) {
98 ; CHECK-LABEL: @getAdjustedPtr_addrspacecast_gep(
99 ; CHECK-NEXT:  entry:
100 ; CHECK-NEXT:    [[CAST1:%.*]] = addrspacecast [32 x i8]* [[X:%.*]] to i8 addrspace(1)*
101 ; CHECK-NEXT:    [[A_SROA_0_0_CAST1_SROA_CAST:%.*]] = bitcast i8 addrspace(1)* [[CAST1]] to i64 addrspace(1)*
102 ; CHECK-NEXT:    [[A_SROA_0_0_COPYLOAD:%.*]] = load i64, i64 addrspace(1)* [[A_SROA_0_0_CAST1_SROA_CAST]], align 1
103 ; CHECK-NEXT:    [[A_SROA_2_0_CAST1_SROA_IDX:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[CAST1]], i16 8
104 ; CHECK-NEXT:    [[A_SROA_2_0_CAST1_SROA_CAST:%.*]] = bitcast i8 addrspace(1)* [[A_SROA_2_0_CAST1_SROA_IDX]] to i64 addrspace(1)*
105 ; CHECK-NEXT:    [[A_SROA_2_0_COPYLOAD:%.*]] = load i64, i64 addrspace(1)* [[A_SROA_2_0_CAST1_SROA_CAST]], align 1
106 ; CHECK-NEXT:    ret i64 [[A_SROA_0_0_COPYLOAD]]
108 entry:
109   %a = alloca [32 x i8], align 8
110   %cast1 = addrspacecast [32 x i8]* %x to i8 addrspace(1)*
111   %cast2 = bitcast [32 x i8]* %a to i8*
112   call void @llvm.memcpy.p0i8.p1i8.i32(i8* %cast2, i8 addrspace(1)* %cast1, i32 16, i1 false)
113   %gep = getelementptr [32 x i8], [32 x i8]* %a, i32 0
114   %gep.bitcast = bitcast [32 x i8]* %gep to i64*
115   %val = load i64, i64* %gep.bitcast
116   ret i64 %val
119 define i64 @getAdjustedPtr_gep_addrspacecast([32 x i8]* %x) {
120 ; CHECK-LABEL: @getAdjustedPtr_gep_addrspacecast(
121 ; CHECK-NEXT:  entry:
122 ; CHECK-NEXT:    [[GEP_X:%.*]] = getelementptr [32 x i8], [32 x i8]* [[X:%.*]], i32 0, i32 16
123 ; CHECK-NEXT:    [[CAST1:%.*]] = addrspacecast i8* [[GEP_X]] to i8 addrspace(1)*
124 ; CHECK-NEXT:    [[A_SROA_0_0_CAST1_SROA_CAST:%.*]] = bitcast i8 addrspace(1)* [[CAST1]] to i64 addrspace(1)*
125 ; CHECK-NEXT:    [[A_SROA_0_0_COPYLOAD:%.*]] = load i64, i64 addrspace(1)* [[A_SROA_0_0_CAST1_SROA_CAST]], align 1
126 ; CHECK-NEXT:    [[A_SROA_2_0_CAST1_SROA_IDX:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[CAST1]], i16 8
127 ; CHECK-NEXT:    [[A_SROA_2_0_CAST1_SROA_CAST:%.*]] = bitcast i8 addrspace(1)* [[A_SROA_2_0_CAST1_SROA_IDX]] to i64 addrspace(1)*
128 ; CHECK-NEXT:    [[A_SROA_2_0_COPYLOAD:%.*]] = load i64, i64 addrspace(1)* [[A_SROA_2_0_CAST1_SROA_CAST]], align 1
129 ; CHECK-NEXT:    ret i64 [[A_SROA_0_0_COPYLOAD]]
131 entry:
132   %a = alloca [32 x i8], align 8
133   %gep.x = getelementptr [32 x i8], [32 x i8]* %x, i32 0, i32 16
134   %cast1 = addrspacecast i8* %gep.x to i8 addrspace(1)*
136   %cast2 = bitcast [32 x i8]* %a to i8*
137   call void @llvm.memcpy.p0i8.p1i8.i32(i8* %cast2, i8 addrspace(1)* %cast1, i32 16, i1 false)
138   %gep = getelementptr [32 x i8], [32 x i8]* %a, i32 0
139   %gep.bitcast = bitcast [32 x i8]* %gep to i64*
140   %val = load i64, i64* %gep.bitcast
141   ret i64 %val
144 define i64 @getAdjustedPtr_gep_addrspacecast_gep([32 x i8]* %x) {
145 ; CHECK-LABEL: @getAdjustedPtr_gep_addrspacecast_gep(
146 ; CHECK-NEXT:  entry:
147 ; CHECK-NEXT:    [[GEP0_X:%.*]] = getelementptr [32 x i8], [32 x i8]* [[X:%.*]], i32 0, i32 8
148 ; CHECK-NEXT:    [[CAST1:%.*]] = addrspacecast i8* [[GEP0_X]] to i8 addrspace(1)*
149 ; CHECK-NEXT:    [[A_SROA_0_0_GEP1_X_SROA_IDX:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[CAST1]], i16 8
150 ; CHECK-NEXT:    [[A_SROA_0_0_GEP1_X_SROA_CAST:%.*]] = bitcast i8 addrspace(1)* [[A_SROA_0_0_GEP1_X_SROA_IDX]] to i64 addrspace(1)*
151 ; CHECK-NEXT:    [[A_SROA_0_0_COPYLOAD:%.*]] = load i64, i64 addrspace(1)* [[A_SROA_0_0_GEP1_X_SROA_CAST]], align 1
152 ; CHECK-NEXT:    [[A_SROA_2_0_GEP1_X_SROA_IDX:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[CAST1]], i16 16
153 ; CHECK-NEXT:    [[A_SROA_2_0_GEP1_X_SROA_CAST:%.*]] = bitcast i8 addrspace(1)* [[A_SROA_2_0_GEP1_X_SROA_IDX]] to i64 addrspace(1)*
154 ; CHECK-NEXT:    [[A_SROA_2_0_COPYLOAD:%.*]] = load i64, i64 addrspace(1)* [[A_SROA_2_0_GEP1_X_SROA_CAST]], align 1
155 ; CHECK-NEXT:    ret i64 [[A_SROA_0_0_COPYLOAD]]
157 entry:
158   %a = alloca [32 x i8], align 8
159   %gep0.x = getelementptr [32 x i8], [32 x i8]* %x, i32 0, i32 8
160   %cast1 = addrspacecast i8* %gep0.x to i8 addrspace(1)*
161   %gep1.x = getelementptr i8, i8 addrspace(1)* %cast1, i32 8
163   %cast2 = bitcast [32 x i8]* %a to i8*
164   call void @llvm.memcpy.p0i8.p1i8.i32(i8* %cast2, i8 addrspace(1)* %gep1.x, i32 16, i1 false)
165   %gep = getelementptr [32 x i8], [32 x i8]* %a, i32 0
166   %gep.bitcast = bitcast [32 x i8]* %gep to i64*
167   %val = load i64, i64* %gep.bitcast
168   ret i64 %val
171 ; Don't change the address space of a volatile operation
172 define i64 @alloca_addrspacecast_bitcast_volatile_store(i64 %X) {
173 ; CHECK-LABEL: @alloca_addrspacecast_bitcast_volatile_store(
174 ; CHECK-NEXT:  entry:
175 ; CHECK-NEXT:    [[A:%.*]] = alloca [8 x i8]
176 ; CHECK-NEXT:    [[A_CAST:%.*]] = addrspacecast [8 x i8]* [[A]] to [8 x i8] addrspace(1)*
177 ; CHECK-NEXT:    [[B:%.*]] = bitcast [8 x i8] addrspace(1)* [[A_CAST]] to i64 addrspace(1)*
178 ; CHECK-NEXT:    store volatile i64 [[X:%.*]], i64 addrspace(1)* [[B]]
179 ; CHECK-NEXT:    [[Z:%.*]] = load i64, i64 addrspace(1)* [[B]]
180 ; CHECK-NEXT:    ret i64 [[Z]]
182 entry:
183   %A = alloca [8 x i8]
184   %A.cast = addrspacecast [8 x i8]* %A to [8 x i8] addrspace(1)*
185   %B = bitcast [8 x i8] addrspace(1)* %A.cast to i64 addrspace(1)*
186   store volatile i64 %X, i64 addrspace(1)* %B
187   %Z = load i64, i64 addrspace(1)* %B
188   ret i64 %Z
191 ; Don't change the address space of a volatile operation
192 define i64 @alloca_addrspacecast_bitcast_volatile_load(i64 %X) {
193 ; CHECK-LABEL: @alloca_addrspacecast_bitcast_volatile_load(
194 ; CHECK-NEXT:  entry:
195 ; CHECK-NEXT:    [[A:%.*]] = alloca [8 x i8]
196 ; CHECK-NEXT:    [[A_CAST:%.*]] = addrspacecast [8 x i8]* [[A]] to [8 x i8] addrspace(1)*
197 ; CHECK-NEXT:    [[B:%.*]] = bitcast [8 x i8] addrspace(1)* [[A_CAST]] to i64 addrspace(1)*
198 ; CHECK-NEXT:    store i64 [[X:%.*]], i64 addrspace(1)* [[B]]
199 ; CHECK-NEXT:    [[Z:%.*]] = load volatile i64, i64 addrspace(1)* [[B]]
200 ; CHECK-NEXT:    ret i64 [[Z]]
202 entry:
203   %A = alloca [8 x i8]
204   %A.cast = addrspacecast [8 x i8]* %A to [8 x i8] addrspace(1)*
205   %B = bitcast [8 x i8] addrspace(1)* %A.cast to i64 addrspace(1)*
206   store i64 %X, i64 addrspace(1)* %B
207   %Z = load volatile i64, i64 addrspace(1)* %B
208   ret i64 %Z
211 declare void @llvm.memset.p1i8.i32(i8 addrspace(1)* nocapture, i8, i32, i1) nounwind
213 ; Don't change the address space of a volatile operation
214 define i32 @volatile_memset() {
215 ; CHECK-LABEL: @volatile_memset(
216 ; CHECK-NEXT:  entry:
217 ; CHECK-NEXT:    [[A:%.*]] = alloca [4 x i8]
218 ; CHECK-NEXT:    [[PTR:%.*]] = getelementptr [4 x i8], [4 x i8]* [[A]], i32 0, i32 0
219 ; CHECK-NEXT:    [[ASC:%.*]] = addrspacecast i8* [[PTR]] to i8 addrspace(1)*
220 ; CHECK-NEXT:    call void @llvm.memset.p1i8.i32(i8 addrspace(1)* [[ASC]], i8 42, i32 4, i1 true)
221 ; CHECK-NEXT:    [[IPTR:%.*]] = bitcast i8* [[PTR]] to i32*
222 ; CHECK-NEXT:    [[VAL:%.*]] = load i32, i32* [[IPTR]]
223 ; CHECK-NEXT:    ret i32 [[VAL]]
225 entry:
226   %a = alloca [4 x i8]
227   %ptr = getelementptr [4 x i8], [4 x i8]* %a, i32 0, i32 0
228   %asc = addrspacecast i8* %ptr to i8 addrspace(1)*
229   call void @llvm.memset.p1i8.i32(i8 addrspace(1)* %asc, i8 42, i32 4, i1 true)
230   %iptr = bitcast i8* %ptr to i32*
231   %val = load i32, i32* %iptr
232   ret i32 %val
235 ; Don't change the address space of a volatile operation
236 define void @volatile_memcpy(i8* %src, i8* %dst) {
237 ; CHECK-LABEL: @volatile_memcpy(
238 ; CHECK-NEXT:  entry:
239 ; CHECK-NEXT:    [[A:%.*]] = alloca [4 x i8]
240 ; CHECK-NEXT:    [[PTR:%.*]] = getelementptr [4 x i8], [4 x i8]* [[A]], i32 0, i32 0
241 ; CHECK-NEXT:    [[ASC:%.*]] = addrspacecast i8* [[PTR]] to i8 addrspace(1)*
242 ; CHECK-NEXT:    call void @llvm.memcpy.p1i8.p0i8.i32(i8 addrspace(1)* [[ASC]], i8* [[SRC:%.*]], i32 4, i1 true), !tbaa !0
243 ; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p1i8.i32(i8* [[DST:%.*]], i8 addrspace(1)* [[ASC]], i32 4, i1 true), !tbaa !3
244 ; CHECK-NEXT:    ret void
246 entry:
247   %a = alloca [4 x i8]
248   %ptr = getelementptr [4 x i8], [4 x i8]* %a, i32 0, i32 0
249   %asc = addrspacecast i8* %ptr to i8 addrspace(1)*
250   call void @llvm.memcpy.p1i8.p0i8.i32(i8 addrspace(1)* %asc, i8* %src, i32 4, i1 true), !tbaa !0
251   call void @llvm.memcpy.p0i8.p1i8.i32(i8* %dst, i8 addrspace(1)* %asc, i32 4, i1 true), !tbaa !3
252   ret void
255 define void @select_addrspacecast(i1 %a, i1 %b) {
256 ; CHECK-LABEL: @select_addrspacecast(
257 ; CHECK-NEXT:    ret void
259   %c = alloca i64, align 8
260   %p.0.c = select i1 undef, i64* %c, i64* %c
261   %asc = addrspacecast i64* %p.0.c to i64 addrspace(1)*
263   %cond.in = select i1 undef, i64 addrspace(1)* %asc, i64 addrspace(1)* %asc
264   %cond = load i64, i64 addrspace(1)* %cond.in, align 8
265   ret void
268 define void @select_addrspacecast_const_op(i1 %a, i1 %b) {
269 ; CHECK-LABEL: @select_addrspacecast_const_op(
270 ; CHECK-NEXT:    [[C:%.*]] = alloca i64, align 8
271 ; CHECK-NEXT:    [[C_0_ASC_SROA_CAST:%.*]] = addrspacecast i64* [[C]] to i64 addrspace(1)*
272 ; CHECK-NEXT:    [[COND_IN:%.*]] = select i1 undef, i64 addrspace(1)* [[C_0_ASC_SROA_CAST]], i64 addrspace(1)* null
273 ; CHECK-NEXT:    [[COND:%.*]] = load i64, i64 addrspace(1)* [[COND_IN]], align 8
274 ; CHECK-NEXT:    ret void
276   %c = alloca i64, align 8
277   %p.0.c = select i1 undef, i64* %c, i64* %c
278   %asc = addrspacecast i64* %p.0.c to i64 addrspace(1)*
280   %cond.in = select i1 undef, i64 addrspace(1)* %asc, i64 addrspace(1)* null
281   %cond = load i64, i64 addrspace(1)* %cond.in, align 8
282   ret void
285 ;; If this was external, we wouldn't be able to prove dereferenceability
286 ;; of the location.
287 @gv = addrspace(1) global i64 zeroinitializer
289 define void @select_addrspacecast_gv(i1 %a, i1 %b) {
290 ; CHECK-LABEL: @select_addrspacecast_gv(
291 ; CHECK-NEXT:    [[COND_SROA_SPECULATE_LOAD_FALSE:%.*]] = load i64, i64 addrspace(1)* @gv, align 8
292 ; CHECK-NEXT:    [[COND_SROA_SPECULATED:%.*]] = select i1 undef, i64 undef, i64 [[COND_SROA_SPECULATE_LOAD_FALSE]]
293 ; CHECK-NEXT:    ret void
295   %c = alloca i64, align 8
296   %p.0.c = select i1 undef, i64* %c, i64* %c
297   %asc = addrspacecast i64* %p.0.c to i64 addrspace(1)*
299   %cond.in = select i1 undef, i64 addrspace(1)* %asc, i64 addrspace(1)* @gv
300   %cond = load i64, i64 addrspace(1)* %cond.in, align 8
301   ret void
304 define i8 @select_addrspacecast_i8() {
305 ; CHECK-LABEL: @select_addrspacecast_i8(
306 ; CHECK-NEXT:    [[RET_SROA_SPECULATED:%.*]] = select i1 undef, i8 undef, i8 undef
307 ; CHECK-NEXT:    ret i8 [[RET_SROA_SPECULATED]]
309   %a = alloca i8
310   %b = alloca i8
312   %a.ptr = addrspacecast i8* %a to i8 addrspace(1)*
313   %b.ptr = addrspacecast i8* %b to i8 addrspace(1)*
315   %ptr = select i1 undef, i8 addrspace(1)* %a.ptr, i8 addrspace(1)* %b.ptr
316   %ret = load i8, i8 addrspace(1)* %ptr
317   ret i8 %ret
320 !0 = !{!1, !1, i64 0, i64 1}
321 !1 = !{!2, i64 1, !"type_0"}
322 !2 = !{!"root"}
323 !3 = !{!4, !4, i64 0, i64 1}
324 !4 = !{!2, i64 1, !"type_3"}