[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / alloca.ll
blobfee8e0ef70f14bf19c3f03d7616b8cfdd9a3d7f8
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S -data-layout="E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" | FileCheck %s -check-prefixes=ALL,CHECK
3 ; RUN: opt < %s -instcombine -S -data-layout="E-p:32:32:32-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" | FileCheck %s -check-prefixes=ALL,P32
4 ; RUN: opt < %s -instcombine -S | FileCheck %s -check-prefixes=ALL,NODL
6 declare void @use(...)
8 @int = global i32 zeroinitializer
10 ; Zero byte allocas should be merged if they can't be deleted.
11 define void @test() {
12 ; CHECK-LABEL: @test(
13 ; CHECK-NEXT:    [[X:%.*]] = alloca [0 x i32], align 4
14 ; CHECK-NEXT:    call void (...) @use([0 x i32]* nonnull [[X]])
15 ; CHECK-NEXT:    [[Y1_SUB:%.*]] = getelementptr inbounds [0 x i32], [0 x i32]* [[X]], i64 0, i64 0
16 ; CHECK-NEXT:    call void (...) @use(i32* nonnull [[Y1_SUB]])
17 ; CHECK-NEXT:    call void (...) @use([0 x i32]* nonnull [[X]])
18 ; CHECK-NEXT:    call void (...) @use([0 x i32]* nonnull [[X]])
19 ; CHECK-NEXT:    ret void
21 ; P32-LABEL: @test(
22 ; P32-NEXT:    [[X:%.*]] = alloca [0 x i32], align 4
23 ; P32-NEXT:    call void (...) @use([0 x i32]* nonnull [[X]])
24 ; P32-NEXT:    [[Y1_SUB:%.*]] = getelementptr inbounds [0 x i32], [0 x i32]* [[X]], i32 0, i32 0
25 ; P32-NEXT:    call void (...) @use(i32* nonnull [[Y1_SUB]])
26 ; P32-NEXT:    call void (...) @use([0 x i32]* nonnull [[X]])
27 ; P32-NEXT:    call void (...) @use([0 x i32]* nonnull [[X]])
28 ; P32-NEXT:    ret void
30 ; NODL-LABEL: @test(
31 ; NODL-NEXT:    [[X:%.*]] = alloca [0 x i32], align 8
32 ; NODL-NEXT:    call void (...) @use([0 x i32]* nonnull [[X]])
33 ; NODL-NEXT:    [[Y1_SUB:%.*]] = getelementptr inbounds [0 x i32], [0 x i32]* [[X]], i64 0, i64 0
34 ; NODL-NEXT:    call void (...) @use(i32* nonnull [[Y1_SUB]])
35 ; NODL-NEXT:    call void (...) @use([0 x i32]* nonnull [[X]])
36 ; NODL-NEXT:    call void (...) @use([0 x i32]* nonnull [[X]])
37 ; NODL-NEXT:    ret void
39   %X = alloca [0 x i32]           ; <[0 x i32]*> [#uses=1]
40   call void (...) @use( [0 x i32]* %X )
41   %Y = alloca i32, i32 0          ; <i32*> [#uses=1]
42   call void (...) @use( i32* %Y )
43   %Z = alloca {  }                ; <{  }*> [#uses=1]
44   call void (...) @use( {  }* %Z )
45   %size = load i32, i32* @int
46   %A = alloca {{}}, i32 %size
47   call void (...) @use( {{}}* %A )
48   ret void
51 ; Zero byte allocas should be deleted.
52 define void @test2() {
53 ; ALL-LABEL: @test2(
54 ; ALL-NEXT:    ret void
56   %A = alloca i32         ; <i32*> [#uses=1]
57   store i32 123, i32* %A
58   ret void
61 ; Zero byte allocas should be deleted.
62 define void @test3() {
63 ; ALL-LABEL: @test3(
64 ; ALL-NEXT:    ret void
66   %A = alloca { i32 }             ; <{ i32 }*> [#uses=1]
67   %B = getelementptr { i32 }, { i32 }* %A, i32 0, i32 0            ; <i32*> [#uses=1]
68   store i32 123, i32* %B
69   ret void
72 define i32* @test4(i32 %n) {
73 ; CHECK-LABEL: @test4(
74 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[N:%.*]] to i64
75 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, i64 [[TMP1]], align 4
76 ; CHECK-NEXT:    ret i32* [[A]]
78 ; P32-LABEL: @test4(
79 ; P32-NEXT:    [[A:%.*]] = alloca i32, i32 [[N:%.*]], align 4
80 ; P32-NEXT:    ret i32* [[A]]
82 ; NODL-LABEL: @test4(
83 ; NODL-NEXT:    [[TMP1:%.*]] = zext i32 [[N:%.*]] to i64
84 ; NODL-NEXT:    [[A:%.*]] = alloca i32, i64 [[TMP1]], align 4
85 ; NODL-NEXT:    ret i32* [[A]]
87   %A = alloca i32, i32 %n
88   ret i32* %A
91 ; Allocas which are only used by GEPs, bitcasts, addrspacecasts, and stores
92 ; (transitively) should be deleted.
93 define void @test5() {
94 ; ALL-LABEL: @test5(
95 ; ALL-NEXT:  entry:
96 ; ALL-NEXT:    ret void
99 entry:
100   %a = alloca { i32 }
101   %b = alloca i32*
102   %c = alloca i32
103   %a.1 = getelementptr { i32 }, { i32 }* %a, i32 0, i32 0
104   store i32 123, i32* %a.1
105   store i32* %a.1, i32** %b
106   %b.1 = bitcast i32** %b to i32*
107   store i32 123, i32* %b.1
108   %a.2 = getelementptr { i32 }, { i32 }* %a, i32 0, i32 0
109   store atomic i32 2, i32* %a.2 unordered, align 4
110   %a.3 = getelementptr { i32 }, { i32 }* %a, i32 0, i32 0
111   store atomic i32 3, i32* %a.3 release, align 4
112   %a.4 = getelementptr { i32 }, { i32 }* %a, i32 0, i32 0
113   store atomic i32 4, i32* %a.4 seq_cst, align 4
114   %c.1 = addrspacecast i32* %c to i32 addrspace(1)*
115   store i32 123, i32 addrspace(1)* %c.1
116   ret void
119 declare void @f(i32* %p)
121 ; Check that we don't delete allocas in some erroneous cases.
122 define void @test6() {
123 ; CHECK-LABEL: @test6(
124 ; CHECK-NEXT:  entry:
125 ; CHECK-NEXT:    [[A:%.*]] = alloca { i32 }, align 4
126 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
127 ; CHECK-NEXT:    [[A_1:%.*]] = getelementptr inbounds { i32 }, { i32 }* [[A]], i64 0, i32 0
128 ; CHECK-NEXT:    store volatile i32 123, i32* [[A_1]], align 4
129 ; CHECK-NEXT:    tail call void @f(i32* nonnull [[B]])
130 ; CHECK-NEXT:    ret void
132 ; P32-LABEL: @test6(
133 ; P32-NEXT:  entry:
134 ; P32-NEXT:    [[A:%.*]] = alloca { i32 }, align 4
135 ; P32-NEXT:    [[B:%.*]] = alloca i32, align 4
136 ; P32-NEXT:    [[A_1:%.*]] = getelementptr inbounds { i32 }, { i32 }* [[A]], i32 0, i32 0
137 ; P32-NEXT:    store volatile i32 123, i32* [[A_1]], align 4
138 ; P32-NEXT:    tail call void @f(i32* nonnull [[B]])
139 ; P32-NEXT:    ret void
141 ; NODL-LABEL: @test6(
142 ; NODL-NEXT:  entry:
143 ; NODL-NEXT:    [[A:%.*]] = alloca { i32 }, align 8
144 ; NODL-NEXT:    [[B:%.*]] = alloca i32, align 4
145 ; NODL-NEXT:    [[A_1:%.*]] = getelementptr inbounds { i32 }, { i32 }* [[A]], i64 0, i32 0
146 ; NODL-NEXT:    store volatile i32 123, i32* [[A_1]], align 8
147 ; NODL-NEXT:    tail call void @f(i32* nonnull [[B]])
148 ; NODL-NEXT:    ret void
151 entry:
152   %a = alloca { i32 }
153   %b = alloca i32
154   %a.1 = getelementptr { i32 }, { i32 }* %a, i32 0, i32 0
155   store volatile i32 123, i32* %a.1
156   tail call void @f(i32* %b)
157   ret void
160 ; PR14371
161 %opaque_type = type opaque
162 %real_type = type { { i32, i32* } }
164 @opaque_global = external constant %opaque_type, align 4
166 define void @test7() {
167 ; ALL-LABEL: @test7(
168 ; ALL-NEXT:  entry:
169 ; ALL-NEXT:    ret void
171 entry:
172   %0 = alloca %real_type, align 4
173   %1 = bitcast %real_type* %0 to i8*
174   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %1, i8* bitcast (%opaque_type* @opaque_global to i8*), i32 8, i1 false)
175   ret void
178 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind
181 ; Check that the GEP indices use the pointer size, or 64 if unknown
182 define void @test8() {
183 ; CHECK-LABEL: @test8(
184 ; CHECK-NEXT:    [[X1:%.*]] = alloca [100 x i32], align 4
185 ; CHECK-NEXT:    [[X1_SUB:%.*]] = getelementptr inbounds [100 x i32], [100 x i32]* [[X1]], i64 0, i64 0
186 ; CHECK-NEXT:    call void (...) @use(i32* nonnull [[X1_SUB]])
187 ; CHECK-NEXT:    ret void
189 ; P32-LABEL: @test8(
190 ; P32-NEXT:    [[X1:%.*]] = alloca [100 x i32], align 4
191 ; P32-NEXT:    [[X1_SUB:%.*]] = getelementptr inbounds [100 x i32], [100 x i32]* [[X1]], i32 0, i32 0
192 ; P32-NEXT:    call void (...) @use(i32* nonnull [[X1_SUB]])
193 ; P32-NEXT:    ret void
195 ; NODL-LABEL: @test8(
196 ; NODL-NEXT:    [[X1:%.*]] = alloca [100 x i32], align 4
197 ; NODL-NEXT:    [[X1_SUB:%.*]] = getelementptr inbounds [100 x i32], [100 x i32]* [[X1]], i64 0, i64 0
198 ; NODL-NEXT:    call void (...) @use(i32* nonnull [[X1_SUB]])
199 ; NODL-NEXT:    ret void
203   %x = alloca i32, i32 100
204   call void (...) @use(i32* %x)
205   ret void
208 ; PR19569
209 %struct_type = type { i32, i32 }
210 declare void @test9_aux(<{ %struct_type }>* inalloca(<{ %struct_type }>))
211 declare i8* @llvm.stacksave()
212 declare void @llvm.stackrestore(i8*)
214 define void @test9(%struct_type* %a) {
215 ; ALL-LABEL: @test9(
216 ; ALL-NEXT:  entry:
217 ; ALL-NEXT:    [[ARGMEM:%.*]] = alloca inalloca i64, align 8
218 ; ALL-NEXT:    [[TMPCAST:%.*]] = bitcast i64* [[ARGMEM]] to <{ [[STRUCT_TYPE:%.*]] }>*
219 ; ALL-NEXT:    [[TMP0:%.*]] = bitcast %struct_type* [[A:%.*]] to i64*
220 ; ALL-NEXT:    [[TMP1:%.*]] = load i64, i64* [[TMP0]], align 4
221 ; ALL-NEXT:    store i64 [[TMP1]], i64* [[ARGMEM]], align 8
222 ; ALL-NEXT:    call void @test9_aux(<{ [[STRUCT_TYPE]] }>* nonnull inalloca(<{ [[STRUCT_TYPE]] }>) [[TMPCAST]])
223 ; ALL-NEXT:    ret void
225 entry:
226   %inalloca.save = call i8* @llvm.stacksave()
227   %argmem = alloca inalloca <{ %struct_type }>
228   %0 = getelementptr inbounds <{ %struct_type }>, <{ %struct_type }>* %argmem, i32 0, i32 0
229   %1 = bitcast %struct_type* %0 to i8*
230   %2 = bitcast %struct_type* %a to i8*
231   call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %1, i8* align 4 %2, i32 8, i1 false)
232   call void @test9_aux(<{ %struct_type }>* inalloca(<{ %struct_type }>) %argmem)
233   call void @llvm.stackrestore(i8* %inalloca.save)
234   ret void
237 define void @test10() {
238 ; ALL-LABEL: @test10(
239 ; ALL-NEXT:  entry:
240 ; ALL-NEXT:    [[V32:%.*]] = alloca i1, align 8
241 ; ALL-NEXT:    [[V64:%.*]] = alloca i1, align 8
242 ; ALL-NEXT:    [[V33:%.*]] = alloca i1, align 8
243 ; ALL-NEXT:    call void (...) @use(i1* nonnull [[V32]], i1* nonnull [[V64]], i1* nonnull [[V33]])
244 ; ALL-NEXT:    ret void
246 entry:
247   %v32 = alloca i1, align 8
248   %v64 = alloca i1, i64 1, align 8
249   %v33 = alloca i1, i33 1, align 8
250   call void (...) @use(i1* %v32, i1* %v64, i1* %v33)
251   ret void
254 define void @test11() {
255 ; ALL-LABEL: @test11(
256 ; ALL-NEXT:  entry:
257 ; ALL-NEXT:    [[Y:%.*]] = alloca i32, align 4
258 ; ALL-NEXT:    call void (...) @use(i32* nonnull @int) [ "blah"(i32* [[Y]]) ]
259 ; ALL-NEXT:    ret void
261 entry:
262   %y = alloca i32
263   call void (...) @use(i32* nonnull @int) [ "blah"(i32* %y) ]
264   ret void