1; RUN: opt -instcombine -S < %s | FileCheck %s
2
3target datalayout = "e-p:64:64:64-p1:32:32:32-p2:16:16:16-n8:16:32:64"
4
5
6declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) nounwind
7declare void @llvm.memcpy.p0i8.p1i8.i32(i8*, i8 addrspace(1)*, i32, i32, i1) nounwind
8declare void @llvm.memcpy.p0i8.p2i8.i32(i8*, i8 addrspace(2)*, i32, i32, i1) nounwind
9
10
11define i32* @combine_redundant_addrspacecast(i32 addrspace(1)* %x) nounwind {
12; CHECK-LABEL: @combine_redundant_addrspacecast(
13; CHECK: addrspacecast i32 addrspace(1)* %x to i32*
14; CHECK-NEXT: ret
15  %y = addrspacecast i32 addrspace(1)* %x to i32 addrspace(3)*
16  %z = addrspacecast i32 addrspace(3)* %y to i32*
17  ret i32* %z
18}
19
20define <4 x i32*> @combine_redundant_addrspacecast_vector(<4 x i32 addrspace(1)*> %x) nounwind {
21; CHECK-LABEL: @combine_redundant_addrspacecast_vector(
22; CHECK: addrspacecast <4 x i32 addrspace(1)*> %x to <4 x i32*>
23; CHECK-NEXT: ret
24  %y = addrspacecast <4 x i32 addrspace(1)*> %x to <4 x i32 addrspace(3)*>
25  %z = addrspacecast <4 x i32 addrspace(3)*> %y to <4 x i32*>
26  ret <4 x i32*> %z
27}
28
29define float* @combine_redundant_addrspacecast_types(i32 addrspace(1)* %x) nounwind {
30; CHECK-LABEL: @combine_redundant_addrspacecast_types(
31; CHECK-NEXT: bitcast i32 addrspace(1)* %x to float addrspace(1)*
32; CHECK-NEXT: addrspacecast float addrspace(1)* %1 to float*
33; CHECK-NEXT: ret
34  %y = addrspacecast i32 addrspace(1)* %x to i32 addrspace(3)*
35  %z = addrspacecast i32 addrspace(3)* %y to float*
36  ret float* %z
37}
38
39define <4 x float*> @combine_redundant_addrspacecast_types_vector(<4 x i32 addrspace(1)*> %x) nounwind {
40; CHECK-LABEL: @combine_redundant_addrspacecast_types_vector(
41; CHECK-NEXT: bitcast <4 x i32 addrspace(1)*> %x to <4 x float addrspace(1)*>
42; CHECK-NEXT: addrspacecast <4 x float addrspace(1)*> %1 to <4 x float*>
43; CHECK-NEXT: ret
44  %y = addrspacecast <4 x i32 addrspace(1)*> %x to <4 x i32 addrspace(3)*>
45  %z = addrspacecast <4 x i32 addrspace(3)*> %y to <4 x float*>
46  ret <4 x float*> %z
47}
48
49define float addrspace(2)* @combine_addrspacecast_bitcast_1(i32 addrspace(1)* %x) nounwind {
50; CHECK-LABEL: @combine_addrspacecast_bitcast_1(
51; CHECK-NEXT: bitcast i32 addrspace(1)* %x to float addrspace(1)*
52; CHECK-NEXT: addrspacecast float addrspace(1)* %1 to float addrspace(2)*
53; CHECK-NEXT: ret
54  %y = addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)*
55  %z = bitcast i32 addrspace(2)* %y to float addrspace(2)*
56  ret float addrspace(2)* %z
57}
58
59define i32 addrspace(2)* @combine_addrspacecast_bitcast_2(i32 addrspace(1)* %x) nounwind {
60; CHECK-LABEL: @combine_addrspacecast_bitcast_2(
61; CHECK: addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)*
62; CHECK-NEXT: ret
63  %y = addrspacecast i32 addrspace(1)* %x to float addrspace(2)*
64  %z = bitcast float addrspace(2)* %y to i32 addrspace(2)*
65  ret i32 addrspace(2)* %z
66}
67
68define i32 addrspace(2)* @combine_bitcast_addrspacecast_1(i32 addrspace(1)* %x) nounwind {
69; CHECK-LABEL: @combine_bitcast_addrspacecast_1(
70; CHECK: addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)*
71; CHECK-NEXT: ret
72  %y = bitcast i32 addrspace(1)* %x to i8 addrspace(1)*
73  %z = addrspacecast i8 addrspace(1)* %y to i32 addrspace(2)*
74  ret i32 addrspace(2)* %z
75}
76
77define float addrspace(2)* @combine_bitcast_addrspacecast_2(i32 addrspace(1)* %x) nounwind {
78; CHECK-LABEL: @combine_bitcast_addrspacecast_2(
79; CHECK: bitcast i32 addrspace(1)* %x to float addrspace(1)*
80; CHECK: addrspacecast float addrspace(1)* %1 to float addrspace(2)*
81; CHECK-NEXT: ret
82  %y = bitcast i32 addrspace(1)* %x to i8 addrspace(1)*
83  %z = addrspacecast i8 addrspace(1)* %y to float addrspace(2)*
84  ret float addrspace(2)* %z
85}
86
87define float addrspace(2)* @combine_addrspacecast_types(i32 addrspace(1)* %x) nounwind {
88; CHECK-LABEL: @combine_addrspacecast_types(
89; CHECK-NEXT: bitcast i32 addrspace(1)* %x to float addrspace(1)*
90; CHECK-NEXT: addrspacecast float addrspace(1)* %1 to float addrspace(2)*
91; CHECK-NEXT: ret
92  %y = addrspacecast i32 addrspace(1)* %x to float addrspace(2)*
93  ret float addrspace(2)* %y
94}
95
96define <4 x float addrspace(2)*> @combine_addrspacecast_types_vector(<4 x i32 addrspace(1)*> %x) nounwind {
97; CHECK-LABEL: @combine_addrspacecast_types_vector(
98; CHECK-NEXT: bitcast <4 x i32 addrspace(1)*> %x to <4 x float addrspace(1)*>
99; CHECK-NEXT: addrspacecast <4 x float addrspace(1)*> %1 to <4 x float addrspace(2)*>
100; CHECK-NEXT: ret
101  %y = addrspacecast <4 x i32 addrspace(1)*> %x to <4 x float addrspace(2)*>
102  ret <4 x float addrspace(2)*> %y
103}
104
105define i32 @canonicalize_addrspacecast([16 x i32] addrspace(1)* %arr) {
106; CHECK-LABEL: @canonicalize_addrspacecast(
107; CHECK-NEXT: getelementptr inbounds [16 x i32], [16 x i32] addrspace(1)* %arr, i32 0, i32 0
108; CHECK-NEXT: addrspacecast i32 addrspace(1)* %{{[a-zA-Z0-9]+}} to i32*
109; CHECK-NEXT: load i32, i32*
110; CHECK-NEXT: ret i32
111  %p = addrspacecast [16 x i32] addrspace(1)* %arr to i32*
112  %v = load i32, i32* %p
113  ret i32 %v
114}
115
116@const_array = addrspace(2) constant [60 x i8] [i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22,
117                                                i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22,
118                                                i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22,
119                                                i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22,
120                                                i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22 ]
121
122declare void @foo(i8*) nounwind
123
124; A copy from a constant addrspacecast'ed global
125; CHECK-LABEL: @memcpy_addrspacecast(
126; CHECK-NOT:  call void @llvm.memcpy
127define i32 @memcpy_addrspacecast() nounwind {
128entry:
129  %alloca = alloca i8, i32 48
130  call void @llvm.memcpy.p0i8.p1i8.i32(i8* %alloca, i8 addrspace(1)* addrspacecast (i8 addrspace(2)* getelementptr inbounds ([60 x i8], [60 x i8] addrspace(2)* @const_array, i16 0, i16 4) to i8 addrspace(1)*), i32 48, i32 4, i1 false) nounwind
131  br label %loop.body
132
133loop.body:
134  %i = phi i32 [ 0, %entry ], [ %i.inc, %loop.body ]
135  %sum = phi i32 [ 0, %entry ], [ %sum.inc, %loop.body]
136  %ptr = getelementptr i8, i8* %alloca, i32 %i
137  %load = load i8, i8* %ptr
138  %ext = zext i8 %load to i32
139  %sum.inc = add i32 %sum, %ext
140  %i.inc = add i32 %i, 1
141  %cmp = icmp ne i32 %i, 48
142  br i1 %cmp, label %loop.body, label %end
143
144end:
145  ret i32 %sum.inc
146}
147
148; CHECK-LABEL: @constant_fold_null(
149; CHECK: i32 addrspace(3)* null to i32 addrspace(4)*
150define void @constant_fold_null() #0 {
151  %cast = addrspacecast i32 addrspace(3)* null to i32 addrspace(4)*
152  store i32 7, i32 addrspace(4)* %cast
153  ret void
154}
155
156; CHECK-LABEL: @constant_fold_undef(
157; CHECK: ret i32 addrspace(4)* undef
158define i32 addrspace(4)* @constant_fold_undef() #0 {
159  %cast = addrspacecast i32 addrspace(3)* undef to i32 addrspace(4)*
160  ret i32 addrspace(4)* %cast
161}
162
163; CHECK-LABEL: @constant_fold_null_vector(
164; CHECK: addrspacecast (<4 x i32 addrspace(3)*> zeroinitializer to <4 x i32 addrspace(4)*>)
165define <4 x i32 addrspace(4)*> @constant_fold_null_vector() #0 {
166  %cast = addrspacecast <4 x i32 addrspace(3)*> zeroinitializer to <4 x i32 addrspace(4)*>
167  ret <4 x i32 addrspace(4)*> %cast
168}
169
170; CHECK-LABEL: @constant_fold_inttoptr(
171; CHECK: addrspacecast (i32 addrspace(3)* inttoptr (i32 -1 to i32 addrspace(3)*) to i32 addrspace(4)*)
172define void @constant_fold_inttoptr() #0 {
173  %cast = addrspacecast i32 addrspace(3)* inttoptr (i32 -1 to i32 addrspace(3)*) to i32 addrspace(4)*
174  store i32 7, i32 addrspace(4)* %cast
175  ret void
176}
177
178; CHECK-LABEL: @constant_fold_gep_inttoptr(
179; CHECK: addrspacecast (i32 addrspace(3)* inttoptr (i64 1274 to i32 addrspace(3)*) to i32 addrspace(4)*)
180define void @constant_fold_gep_inttoptr() #0 {
181  %k = inttoptr i32 1234 to i32 addrspace(3)*
182  %gep = getelementptr i32, i32 addrspace(3)* %k, i32 10
183  %cast = addrspacecast i32 addrspace(3)* %gep to i32 addrspace(4)*
184  store i32 7, i32 addrspace(4)* %cast
185  ret void
186}
187