1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=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.p0.p0.i32(ptr, ptr, i32, i1) nounwind
8 declare void @llvm.memcpy.p0.p1.i32(ptr, ptr addrspace(1), i32, i1) nounwind
9 declare void @llvm.memcpy.p0.p2.i32(ptr, ptr addrspace(2), i32, i1) nounwind
12 define ptr @combine_redundant_addrspacecast(ptr addrspace(1) %x) nounwind {
13 ; CHECK-LABEL: @combine_redundant_addrspacecast(
14 ; CHECK-NEXT: [[Z:%.*]] = addrspacecast ptr addrspace(1) [[X:%.*]] to ptr
15 ; CHECK-NEXT: ret ptr [[Z]]
17 %y = addrspacecast ptr addrspace(1) %x to ptr addrspace(3)
18 %z = addrspacecast ptr addrspace(3) %y to ptr
22 define <4 x ptr> @combine_redundant_addrspacecast_vector(<4 x ptr addrspace(1)> %x) nounwind {
23 ; CHECK-LABEL: @combine_redundant_addrspacecast_vector(
24 ; CHECK-NEXT: [[Z:%.*]] = addrspacecast <4 x ptr addrspace(1)> [[X:%.*]] to <4 x ptr>
25 ; CHECK-NEXT: ret <4 x ptr> [[Z]]
27 %y = addrspacecast <4 x ptr addrspace(1)> %x to <4 x ptr addrspace(3)>
28 %z = addrspacecast <4 x ptr addrspace(3)> %y to <4 x ptr>
32 define ptr @combine_redundant_addrspacecast_types(ptr addrspace(1) %x) nounwind {
33 ; CHECK-LABEL: @combine_redundant_addrspacecast_types(
34 ; CHECK-NEXT: [[Z:%.*]] = addrspacecast ptr addrspace(1) [[X:%.*]] to ptr
35 ; CHECK-NEXT: ret ptr [[Z]]
37 %y = addrspacecast ptr addrspace(1) %x to ptr addrspace(3)
38 %z = addrspacecast ptr addrspace(3) %y to ptr
42 define <4 x ptr> @combine_redundant_addrspacecast_types_vector(<4 x ptr addrspace(1)> %x) nounwind {
43 ; CHECK-LABEL: @combine_redundant_addrspacecast_types_vector(
44 ; CHECK-NEXT: [[Z:%.*]] = addrspacecast <4 x ptr addrspace(1)> [[X:%.*]] to <4 x ptr>
45 ; CHECK-NEXT: ret <4 x ptr> [[Z]]
47 %y = addrspacecast <4 x ptr addrspace(1)> %x to <4 x ptr addrspace(3)>
48 %z = addrspacecast <4 x ptr addrspace(3)> %y to <4 x ptr>
52 define ptr addrspace(2) @combine_addrspacecast_bitcast_1(ptr addrspace(1) %x) nounwind {
53 ; CHECK-LABEL: @combine_addrspacecast_bitcast_1(
54 ; CHECK-NEXT: [[Y:%.*]] = addrspacecast ptr addrspace(1) [[X:%.*]] to ptr addrspace(2)
55 ; CHECK-NEXT: ret ptr addrspace(2) [[Y]]
57 %y = addrspacecast ptr addrspace(1) %x to ptr addrspace(2)
58 ret ptr addrspace(2) %y
61 define ptr addrspace(2) @combine_addrspacecast_bitcast_2(ptr addrspace(1) %x) nounwind {
62 ; CHECK-LABEL: @combine_addrspacecast_bitcast_2(
63 ; CHECK-NEXT: [[Y:%.*]] = addrspacecast ptr addrspace(1) [[X:%.*]] to ptr addrspace(2)
64 ; CHECK-NEXT: ret ptr addrspace(2) [[Y]]
66 %y = addrspacecast ptr addrspace(1) %x to ptr addrspace(2)
67 ret ptr addrspace(2) %y
70 define ptr addrspace(2) @combine_bitcast_addrspacecast_1(ptr addrspace(1) %x) nounwind {
71 ; CHECK-LABEL: @combine_bitcast_addrspacecast_1(
72 ; CHECK-NEXT: [[Z:%.*]] = addrspacecast ptr addrspace(1) [[X:%.*]] to ptr addrspace(2)
73 ; CHECK-NEXT: ret ptr addrspace(2) [[Z]]
75 %z = addrspacecast ptr addrspace(1) %x to ptr addrspace(2)
76 ret ptr addrspace(2) %z
79 define ptr addrspace(2) @combine_bitcast_addrspacecast_2(ptr addrspace(1) %x) nounwind {
80 ; CHECK-LABEL: @combine_bitcast_addrspacecast_2(
81 ; CHECK-NEXT: [[Z:%.*]] = addrspacecast ptr addrspace(1) [[X:%.*]] to ptr addrspace(2)
82 ; CHECK-NEXT: ret ptr addrspace(2) [[Z]]
84 %z = addrspacecast ptr addrspace(1) %x to ptr addrspace(2)
85 ret ptr addrspace(2) %z
88 define ptr addrspace(2) @combine_addrspacecast_types(ptr addrspace(1) %x) nounwind {
89 ; CHECK-LABEL: @combine_addrspacecast_types(
90 ; CHECK-NEXT: [[Y:%.*]] = addrspacecast ptr addrspace(1) [[X:%.*]] to ptr addrspace(2)
91 ; CHECK-NEXT: ret ptr addrspace(2) [[Y]]
93 %y = addrspacecast ptr addrspace(1) %x to ptr addrspace(2)
94 ret ptr addrspace(2) %y
97 define <4 x ptr addrspace(2)> @combine_addrspacecast_types_vector(<4 x ptr addrspace(1)> %x) nounwind {
98 ; CHECK-LABEL: @combine_addrspacecast_types_vector(
99 ; CHECK-NEXT: [[Y:%.*]] = addrspacecast <4 x ptr addrspace(1)> [[X:%.*]] to <4 x ptr addrspace(2)>
100 ; CHECK-NEXT: ret <4 x ptr addrspace(2)> [[Y]]
102 %y = addrspacecast <4 x ptr addrspace(1)> %x to <4 x ptr addrspace(2)>
103 ret <4 x ptr addrspace(2)> %y
106 define <vscale x 4 x ptr addrspace(2)> @combine_addrspacecast_types_scalevector(<vscale x 4 x ptr addrspace(1)> %x) nounwind {
107 ; CHECK-LABEL: @combine_addrspacecast_types_scalevector(
108 ; CHECK-NEXT: [[Y:%.*]] = addrspacecast <vscale x 4 x ptr addrspace(1)> [[X:%.*]] to <vscale x 4 x ptr addrspace(2)>
109 ; CHECK-NEXT: ret <vscale x 4 x ptr addrspace(2)> [[Y]]
111 %y = addrspacecast <vscale x 4 x ptr addrspace(1)> %x to <vscale x 4 x ptr addrspace(2)>
112 ret <vscale x 4 x ptr addrspace(2)> %y
116 define i32 @canonicalize_addrspacecast(ptr addrspace(1) %arr) {
117 ; CHECK-LABEL: @canonicalize_addrspacecast(
118 ; CHECK-NEXT: [[P:%.*]] = addrspacecast ptr addrspace(1) [[ARR:%.*]] to ptr
119 ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P]], align 4
120 ; CHECK-NEXT: ret i32 [[V]]
122 %p = addrspacecast ptr addrspace(1) %arr to ptr
123 %v = load i32, ptr %p
127 @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,
128 i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22,
129 i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22,
130 i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22,
131 i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22 ]
133 declare void @foo(ptr) nounwind
135 ; A copy from a constant addrspacecast'ed global
136 define i32 @memcpy_addrspacecast() nounwind {
137 ; CHECK-LABEL: @memcpy_addrspacecast(
139 ; CHECK-NEXT: br label [[LOOP_BODY:%.*]]
141 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[LOOP_BODY]] ]
142 ; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_INC:%.*]], [[LOOP_BODY]] ]
143 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[I]] to i16
144 ; CHECK-NEXT: [[PTR:%.*]] = getelementptr i8, ptr addrspace(2) getelementptr inbounds ([60 x i8], ptr addrspace(2) @const_array, i16 0, i16 4), i16 [[TMP0]]
145 ; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr addrspace(2) [[PTR]], align 1
146 ; CHECK-NEXT: [[EXT:%.*]] = zext i8 [[LOAD]] to i32
147 ; CHECK-NEXT: [[SUM_INC]] = add i32 [[SUM]], [[EXT]]
148 ; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1
149 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[I]], 48
150 ; CHECK-NEXT: br i1 [[CMP_NOT]], label [[END:%.*]], label [[LOOP_BODY]]
152 ; CHECK-NEXT: ret i32 [[SUM_INC]]
155 %alloca = alloca i8, i32 48
156 call void @llvm.memcpy.p0.p1.i32(ptr align 4 %alloca, ptr addrspace(1) align 4 addrspacecast (ptr addrspace(2) getelementptr inbounds ([60 x i8], ptr addrspace(2) @const_array, i16 0, i16 4) to ptr addrspace(1)), i32 48, i1 false) nounwind
160 %i = phi i32 [ 0, %entry ], [ %i.inc, %loop.body ]
161 %sum = phi i32 [ 0, %entry ], [ %sum.inc, %loop.body]
162 %ptr = getelementptr i8, ptr %alloca, i32 %i
163 %load = load i8, ptr %ptr
164 %ext = zext i8 %load to i32
165 %sum.inc = add i32 %sum, %ext
166 %i.inc = add i32 %i, 1
167 %cmp = icmp ne i32 %i, 48
168 br i1 %cmp, label %loop.body, label %end
174 define void @constant_fold_null() #0 {
175 ; CHECK-LABEL: @constant_fold_null(
176 ; CHECK-NEXT: store i32 7, ptr addrspace(4) addrspacecast (ptr addrspace(3) null to ptr addrspace(4)), align 4
177 ; CHECK-NEXT: ret void
179 %cast = addrspacecast ptr addrspace(3) null to ptr addrspace(4)
180 store i32 7, ptr addrspace(4) %cast
184 define ptr addrspace(4) @constant_fold_undef() #0 {
185 ; CHECK-LABEL: @constant_fold_undef(
186 ; CHECK-NEXT: ret ptr addrspace(4) undef
188 %cast = addrspacecast ptr addrspace(3) undef to ptr addrspace(4)
189 ret ptr addrspace(4) %cast
192 define <4 x ptr addrspace(4)> @constant_fold_null_vector() #0 {
193 ; CHECK-LABEL: @constant_fold_null_vector(
194 ; CHECK-NEXT: ret <4 x ptr addrspace(4)> addrspacecast (<4 x ptr addrspace(3)> zeroinitializer to <4 x ptr addrspace(4)>)
196 %cast = addrspacecast <4 x ptr addrspace(3)> zeroinitializer to <4 x ptr addrspace(4)>
197 ret <4 x ptr addrspace(4)> %cast
200 define void @constant_fold_inttoptr() #0 {
201 ; CHECK-LABEL: @constant_fold_inttoptr(
202 ; CHECK-NEXT: store i32 7, ptr addrspace(4) addrspacecast (ptr addrspace(3) inttoptr (i32 -1 to ptr addrspace(3)) to ptr addrspace(4)), align 4
203 ; CHECK-NEXT: ret void
205 %cast = addrspacecast ptr addrspace(3) inttoptr (i32 -1 to ptr addrspace(3)) to ptr addrspace(4)
206 store i32 7, ptr addrspace(4) %cast
210 define void @constant_fold_gep_inttoptr() #0 {
211 ; CHECK-LABEL: @constant_fold_gep_inttoptr(
212 ; CHECK-NEXT: store i32 7, ptr addrspace(4) addrspacecast (ptr addrspace(3) inttoptr (i64 1274 to ptr addrspace(3)) to ptr addrspace(4)), align 4
213 ; CHECK-NEXT: ret void
215 %k = inttoptr i32 1234 to ptr addrspace(3)
216 %gep = getelementptr i32, ptr addrspace(3) %k, i32 10
217 %cast = addrspacecast ptr addrspace(3) %gep to ptr addrspace(4)
218 store i32 7, ptr addrspace(4) %cast