• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5
6declare void @use(...)
7
8@int = global i32 zeroinitializer
9
10; Zero byte allocas should be merged if they can't be deleted.
11define 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
20;
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
29;
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
38;
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
49}
50
51; Zero byte allocas should be deleted.
52define void @test2() {
53; ALL-LABEL: @test2(
54; ALL-NEXT:    ret void
55;
56  %A = alloca i32         ; <i32*> [#uses=1]
57  store i32 123, i32* %A
58  ret void
59}
60
61; Zero byte allocas should be deleted.
62define void @test3() {
63; ALL-LABEL: @test3(
64; ALL-NEXT:    ret void
65;
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
70}
71
72define 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]]
77;
78; P32-LABEL: @test4(
79; P32-NEXT:    [[A:%.*]] = alloca i32, i32 [[N:%.*]], align 4
80; P32-NEXT:    ret i32* [[A]]
81;
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]]
86;
87  %A = alloca i32, i32 %n
88  ret i32* %A
89}
90
91; Allocas which are only used by GEPs, bitcasts, addrspacecasts, and stores
92; (transitively) should be deleted.
93define void @test5() {
94; ALL-LABEL: @test5(
95; ALL-NEXT:  entry:
96; ALL-NEXT:    ret void
97;
98
99entry:
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
117}
118
119declare void @f(i32* %p)
120
121; Check that we don't delete allocas in some erroneous cases.
122define 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
131;
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
140;
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
149;
150
151entry:
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
158}
159
160; PR14371
161%opaque_type = type opaque
162%real_type = type { { i32, i32* } }
163
164@opaque_global = external constant %opaque_type, align 4
165
166define void @test7() {
167; ALL-LABEL: @test7(
168; ALL-NEXT:  entry:
169; ALL-NEXT:    ret void
170;
171entry:
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
176}
177
178declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind
179
180
181; Check that the GEP indices use the pointer size, or 64 if unknown
182define 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
188;
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
194;
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
200;
201
202
203  %x = alloca i32, i32 100
204  call void (...) @use(i32* %x)
205  ret void
206}
207
208; PR19569
209%struct_type = type { i32, i32 }
210declare void @test9_aux(<{ %struct_type }>* inalloca)
211declare i8* @llvm.stacksave()
212declare void @llvm.stackrestore(i8*)
213
214define 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]] }>* inalloca nonnull [[TMPCAST]])
223; ALL-NEXT:    ret void
224;
225entry:
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 %argmem)
233  call void @llvm.stackrestore(i8* %inalloca.save)
234  ret void
235}
236
237define 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
245;
246entry:
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
252}
253
254define 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
260;
261entry:
262  %y = alloca i32
263  call void (...) @use(i32* nonnull @int) [ "blah"(i32* %y) ]
264  ret void
265}
266