[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / addrspacecast.ll
blob20627a60da269df915cba7d6db562836f78f563c
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*
19   ret i32* %z
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*>
29   ret <4 x i32*> %z
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*
40   ret float* %z
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*>
51   ret <4 x float*> %z
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
136   ret i32 %v
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(
150 ; CHECK-NEXT:  entry:
151 ; CHECK-NEXT:    br label [[LOOP_BODY:%.*]]
152 ; CHECK:       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]]
163 ; CHECK:       end:
164 ; CHECK-NEXT:    ret i32 [[SUM_INC]]
166 entry:
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
169   br label %loop.body
171 loop.body:
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
182 end:
183   ret i32 %sum.inc
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
193   ret void
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
219   ret void
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
231   ret void