1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -instcombine -S < %s | FileCheck %s
4 target datalayout = "e-p:64:64:64-p1:32:32:32-p2:16:16:16-n8:16:32:64"
7 declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1) nounwind
8 declare void @llvm.memcpy.p0i8.p1i8.i32(i8*, i8 addrspace(1)*, i32, i1) nounwind
9 declare void @llvm.memcpy.p0i8.p2i8.i32(i8*, i8 addrspace(2)*, i32, i1) nounwind
12 define i32* @combine_redundant_addrspacecast(i32 addrspace(1)* %x) nounwind {
13 ; CHECK-LABEL: @combine_redundant_addrspacecast(
14 ; CHECK-NEXT: [[Z:%.*]] = addrspacecast i32 addrspace(1)* [[X:%.*]] to i32*
15 ; CHECK-NEXT: ret i32* [[Z]]
17 %y = addrspacecast i32 addrspace(1)* %x to i32 addrspace(3)*
18 %z = addrspacecast i32 addrspace(3)* %y to i32*
22 define <4 x i32*> @combine_redundant_addrspacecast_vector(<4 x i32 addrspace(1)*> %x) nounwind {
23 ; CHECK-LABEL: @combine_redundant_addrspacecast_vector(
24 ; CHECK-NEXT: [[Z:%.*]] = addrspacecast <4 x i32 addrspace(1)*> [[X:%.*]] to <4 x i32*>
25 ; CHECK-NEXT: ret <4 x i32*> [[Z]]
27 %y = addrspacecast <4 x i32 addrspace(1)*> %x to <4 x i32 addrspace(3)*>
28 %z = addrspacecast <4 x i32 addrspace(3)*> %y to <4 x i32*>
32 define float* @combine_redundant_addrspacecast_types(i32 addrspace(1)* %x) nounwind {
33 ; CHECK-LABEL: @combine_redundant_addrspacecast_types(
34 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 addrspace(1)* [[X:%.*]] to float addrspace(1)*
35 ; CHECK-NEXT: [[Z:%.*]] = addrspacecast float addrspace(1)* [[TMP1]] to float*
36 ; CHECK-NEXT: ret float* [[Z]]
38 %y = addrspacecast i32 addrspace(1)* %x to i32 addrspace(3)*
39 %z = addrspacecast i32 addrspace(3)* %y to float*
43 define <4 x float*> @combine_redundant_addrspacecast_types_vector(<4 x i32 addrspace(1)*> %x) nounwind {
44 ; CHECK-LABEL: @combine_redundant_addrspacecast_types_vector(
45 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32 addrspace(1)*> [[X:%.*]] to <4 x float addrspace(1)*>
46 ; CHECK-NEXT: [[Z:%.*]] = addrspacecast <4 x float addrspace(1)*> [[TMP1]] to <4 x float*>
47 ; CHECK-NEXT: ret <4 x float*> [[Z]]
49 %y = addrspacecast <4 x i32 addrspace(1)*> %x to <4 x i32 addrspace(3)*>
50 %z = addrspacecast <4 x i32 addrspace(3)*> %y to <4 x float*>
54 define float addrspace(2)* @combine_addrspacecast_bitcast_1(i32 addrspace(1)* %x) nounwind {
55 ; CHECK-LABEL: @combine_addrspacecast_bitcast_1(
56 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 addrspace(1)* [[X:%.*]] to float addrspace(1)*
57 ; CHECK-NEXT: [[Z:%.*]] = addrspacecast float addrspace(1)* [[TMP1]] to float addrspace(2)*
58 ; CHECK-NEXT: ret float addrspace(2)* [[Z]]
60 %y = addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)*
61 %z = bitcast i32 addrspace(2)* %y to float addrspace(2)*
62 ret float addrspace(2)* %z
65 define i32 addrspace(2)* @combine_addrspacecast_bitcast_2(i32 addrspace(1)* %x) nounwind {
66 ; CHECK-LABEL: @combine_addrspacecast_bitcast_2(
67 ; CHECK-NEXT: [[Z:%.*]] = addrspacecast i32 addrspace(1)* [[X:%.*]] to i32 addrspace(2)*
68 ; CHECK-NEXT: ret i32 addrspace(2)* [[Z]]
70 %y = addrspacecast i32 addrspace(1)* %x to float addrspace(2)*
71 %z = bitcast float addrspace(2)* %y to i32 addrspace(2)*
72 ret i32 addrspace(2)* %z
75 define i32 addrspace(2)* @combine_bitcast_addrspacecast_1(i32 addrspace(1)* %x) nounwind {
76 ; CHECK-LABEL: @combine_bitcast_addrspacecast_1(
77 ; CHECK-NEXT: [[Z:%.*]] = addrspacecast i32 addrspace(1)* [[X:%.*]] to i32 addrspace(2)*
78 ; CHECK-NEXT: ret i32 addrspace(2)* [[Z]]
80 %y = bitcast i32 addrspace(1)* %x to i8 addrspace(1)*
81 %z = addrspacecast i8 addrspace(1)* %y to i32 addrspace(2)*
82 ret i32 addrspace(2)* %z
85 define float addrspace(2)* @combine_bitcast_addrspacecast_2(i32 addrspace(1)* %x) nounwind {
86 ; CHECK-LABEL: @combine_bitcast_addrspacecast_2(
87 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 addrspace(1)* [[X:%.*]] to float addrspace(1)*
88 ; CHECK-NEXT: [[Z:%.*]] = addrspacecast float addrspace(1)* [[TMP1]] to float addrspace(2)*
89 ; CHECK-NEXT: ret float addrspace(2)* [[Z]]
91 %y = bitcast i32 addrspace(1)* %x to i8 addrspace(1)*
92 %z = addrspacecast i8 addrspace(1)* %y to float addrspace(2)*
93 ret float addrspace(2)* %z
96 define float addrspace(2)* @combine_addrspacecast_types(i32 addrspace(1)* %x) nounwind {
97 ; CHECK-LABEL: @combine_addrspacecast_types(
98 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 addrspace(1)* [[X:%.*]] to float addrspace(1)*
99 ; CHECK-NEXT: [[Y:%.*]] = addrspacecast float addrspace(1)* [[TMP1]] to float addrspace(2)*
100 ; CHECK-NEXT: ret float addrspace(2)* [[Y]]
102 %y = addrspacecast i32 addrspace(1)* %x to float addrspace(2)*
103 ret float addrspace(2)* %y
106 define <4 x float addrspace(2)*> @combine_addrspacecast_types_vector(<4 x i32 addrspace(1)*> %x) nounwind {
107 ; CHECK-LABEL: @combine_addrspacecast_types_vector(
108 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32 addrspace(1)*> [[X:%.*]] to <4 x float addrspace(1)*>
109 ; CHECK-NEXT: [[Y:%.*]] = addrspacecast <4 x float addrspace(1)*> [[TMP1]] to <4 x float addrspace(2)*>
110 ; CHECK-NEXT: ret <4 x float addrspace(2)*> [[Y]]
112 %y = addrspacecast <4 x i32 addrspace(1)*> %x to <4 x float addrspace(2)*>
113 ret <4 x float addrspace(2)*> %y
116 define <vscale x 4 x float addrspace(2)*> @combine_addrspacecast_types_scalevector(<vscale x 4 x i32 addrspace(1)*> %x) nounwind {
117 ; CHECK-LABEL: @combine_addrspacecast_types_scalevector(
118 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <vscale x 4 x i32 addrspace(1)*> [[X:%.*]] to <vscale x 4 x float addrspace(1)*>
119 ; CHECK-NEXT: [[Y:%.*]] = addrspacecast <vscale x 4 x float addrspace(1)*> [[TMP1]] to <vscale x 4 x float addrspace(2)*>
120 ; CHECK-NEXT: ret <vscale x 4 x float addrspace(2)*> [[Y]]
122 %y = addrspacecast <vscale x 4 x i32 addrspace(1)*> %x to <vscale x 4 x float addrspace(2)*>
123 ret <vscale x 4 x float addrspace(2)*> %y
127 define i32 @canonicalize_addrspacecast([16 x i32] addrspace(1)* %arr) {
128 ; CHECK-LABEL: @canonicalize_addrspacecast(
129 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr [16 x i32], [16 x i32] addrspace(1)* [[ARR:%.*]], i32 0, i32 0
130 ; CHECK-NEXT: [[P:%.*]] = addrspacecast i32 addrspace(1)* [[TMP1]] to i32*
131 ; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 4
132 ; CHECK-NEXT: ret i32 [[V]]
134 %p = addrspacecast [16 x i32] addrspace(1)* %arr to i32*
135 %v = load i32, i32* %p
139 @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,
140 i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22,
141 i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22,
142 i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22,
143 i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22 ]
145 declare void @foo(i8*) nounwind
147 ; A copy from a constant addrspacecast'ed global
148 define i32 @memcpy_addrspacecast() nounwind {
149 ; CHECK-LABEL: @memcpy_addrspacecast(
151 ; CHECK-NEXT: br label [[LOOP_BODY:%.*]]
153 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[LOOP_BODY]] ]
154 ; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_INC:%.*]], [[LOOP_BODY]] ]
155 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[I]] to i16
156 ; CHECK-NEXT: [[PTR:%.*]] = getelementptr i8, i8 addrspace(2)* getelementptr inbounds ([60 x i8], [60 x i8] addrspace(2)* @const_array, i16 0, i16 4), i16 [[TMP0]]
157 ; CHECK-NEXT: [[LOAD:%.*]] = load i8, i8 addrspace(2)* [[PTR]], align 1
158 ; CHECK-NEXT: [[EXT:%.*]] = zext i8 [[LOAD]] to i32
159 ; CHECK-NEXT: [[SUM_INC]] = add i32 [[SUM]], [[EXT]]
160 ; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
161 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[I]], 48
162 ; CHECK-NEXT: br i1 [[CMP_NOT]], label [[END:%.*]], label [[LOOP_BODY]]
164 ; CHECK-NEXT: ret i32 [[SUM_INC]]
167 %alloca = alloca i8, i32 48
168 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
172 %i = phi i32 [ 0, %entry ], [ %i.inc, %loop.body ]
173 %sum = phi i32 [ 0, %entry ], [ %sum.inc, %loop.body]
174 %ptr = getelementptr i8, i8* %alloca, i32 %i
175 %load = load i8, i8* %ptr
176 %ext = zext i8 %load to i32
177 %sum.inc = add i32 %sum, %ext
178 %i.inc = add i32 %i, 1
179 %cmp = icmp ne i32 %i, 48
180 br i1 %cmp, label %loop.body, label %end
186 define void @constant_fold_null() #0 {
187 ; CHECK-LABEL: @constant_fold_null(
188 ; CHECK-NEXT: store i32 7, i32 addrspace(4)* addrspacecast (i32 addrspace(3)* null to i32 addrspace(4)*), align 4
189 ; CHECK-NEXT: ret void
191 %cast = addrspacecast i32 addrspace(3)* null to i32 addrspace(4)*
192 store i32 7, i32 addrspace(4)* %cast
196 define i32 addrspace(4)* @constant_fold_undef() #0 {
197 ; CHECK-LABEL: @constant_fold_undef(
198 ; CHECK-NEXT: ret i32 addrspace(4)* undef
200 %cast = addrspacecast i32 addrspace(3)* undef to i32 addrspace(4)*
201 ret i32 addrspace(4)* %cast
204 define <4 x i32 addrspace(4)*> @constant_fold_null_vector() #0 {
205 ; CHECK-LABEL: @constant_fold_null_vector(
206 ; CHECK-NEXT: ret <4 x i32 addrspace(4)*> addrspacecast (<4 x i32 addrspace(3)*> zeroinitializer to <4 x i32 addrspace(4)*>)
208 %cast = addrspacecast <4 x i32 addrspace(3)*> zeroinitializer to <4 x i32 addrspace(4)*>
209 ret <4 x i32 addrspace(4)*> %cast
212 define void @constant_fold_inttoptr() #0 {
213 ; CHECK-LABEL: @constant_fold_inttoptr(
214 ; CHECK-NEXT: store i32 7, i32 addrspace(4)* addrspacecast (i32 addrspace(3)* inttoptr (i32 -1 to i32 addrspace(3)*) to i32 addrspace(4)*), align 4
215 ; CHECK-NEXT: ret void
217 %cast = addrspacecast i32 addrspace(3)* inttoptr (i32 -1 to i32 addrspace(3)*) to i32 addrspace(4)*
218 store i32 7, i32 addrspace(4)* %cast
222 define void @constant_fold_gep_inttoptr() #0 {
223 ; CHECK-LABEL: @constant_fold_gep_inttoptr(
224 ; CHECK-NEXT: store i32 7, i32 addrspace(4)* addrspacecast (i32 addrspace(3)* inttoptr (i64 1274 to i32 addrspace(3)*) to i32 addrspace(4)*), align 4
225 ; CHECK-NEXT: ret void
227 %k = inttoptr i32 1234 to i32 addrspace(3)*
228 %gep = getelementptr i32, i32 addrspace(3)* %k, i32 10
229 %cast = addrspacecast i32 addrspace(3)* %gep to i32 addrspace(4)*
230 store i32 7, i32 addrspace(4)* %cast