1 ; RUN: opt -instcombine -S < %s | FileCheck %s
3 target datalayout = "e-p:64:64:64-p1:32:32:32-p2:16:16:16-n8:16:32:64"
6 declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1) nounwind
7 declare void @llvm.memcpy.p0i8.p1i8.i32(i8*, i8 addrspace(1)*, i32, i1) nounwind
8 declare void @llvm.memcpy.p0i8.p2i8.i32(i8*, i8 addrspace(2)*, i32, i1) nounwind
11 define i32* @combine_redundant_addrspacecast(i32 addrspace(1)* %x) nounwind {
12 ; CHECK-LABEL: @combine_redundant_addrspacecast(
13 ; CHECK: addrspacecast i32 addrspace(1)* %x to i32*
15 %y = addrspacecast i32 addrspace(1)* %x to i32 addrspace(3)*
16 %z = addrspacecast i32 addrspace(3)* %y to i32*
20 define <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*>
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*>
29 define 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*
34 %y = addrspacecast i32 addrspace(1)* %x to i32 addrspace(3)*
35 %z = addrspacecast i32 addrspace(3)* %y to float*
39 define <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*>
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*>
49 define 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)*
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
59 define 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)*
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
68 define 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)*
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
77 define 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)*
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
87 define 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)*
92 %y = addrspacecast i32 addrspace(1)* %x to float addrspace(2)*
93 ret float addrspace(2)* %y
96 define <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)*>
101 %y = addrspacecast <4 x i32 addrspace(1)*> %x to <4 x float addrspace(2)*>
102 ret <4 x float addrspace(2)*> %y
105 define 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
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 ]
122 declare void @foo(i8*) nounwind
124 ; A copy from a constant addrspacecast'ed global
125 ; CHECK-LABEL: @memcpy_addrspacecast(
126 ; CHECK-NOT: call void @llvm.memcpy
127 define i32 @memcpy_addrspacecast() nounwind {
129 %alloca = alloca i8, i32 48
130 call void @llvm.memcpy.p0i8.p1i8.i32(i8* align 4 %alloca, i8 addrspace(1)* align 4 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, i1 false) nounwind
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
148 ; CHECK-LABEL: @constant_fold_null(
149 ; CHECK: i32 addrspace(3)* null to i32 addrspace(4)*
150 define void @constant_fold_null() #0 {
151 %cast = addrspacecast i32 addrspace(3)* null to i32 addrspace(4)*
152 store i32 7, i32 addrspace(4)* %cast
156 ; CHECK-LABEL: @constant_fold_undef(
157 ; CHECK: ret i32 addrspace(4)* undef
158 define i32 addrspace(4)* @constant_fold_undef() #0 {
159 %cast = addrspacecast i32 addrspace(3)* undef to i32 addrspace(4)*
160 ret i32 addrspace(4)* %cast
163 ; CHECK-LABEL: @constant_fold_null_vector(
164 ; CHECK: addrspacecast (<4 x i32 addrspace(3)*> zeroinitializer to <4 x i32 addrspace(4)*>)
165 define <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
170 ; CHECK-LABEL: @constant_fold_inttoptr(
171 ; CHECK: addrspacecast (i32 addrspace(3)* inttoptr (i32 -1 to i32 addrspace(3)*) to i32 addrspace(4)*)
172 define 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
178 ; CHECK-LABEL: @constant_fold_gep_inttoptr(
179 ; CHECK: addrspacecast (i32 addrspace(3)* inttoptr (i64 1274 to i32 addrspace(3)*) to i32 addrspace(4)*)
180 define 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