1; RUN: opt < %s -mem2reg -S | FileCheck %s
2
3; This tests that mem2reg preserves the !nonnull metadata on loads
4; from allocas that get optimized out.
5
6; Check the case where the alloca in question has a single store.
7define float* @single_store(float** %arg) {
8; CHECK-LABEL: define float* @single_store
9; CHECK: %arg.load = load float*, float** %arg, align 8
10; CHECK: [[ASSUME:%(.*)]] = icmp ne float* %arg.load, null
11; CHECK: call void @llvm.assume(i1 {{.*}}[[ASSUME]])
12; CHECK: ret float* %arg.load
13entry:
14  %buf = alloca float*
15  %arg.load = load float*, float** %arg, align 8
16  store float* %arg.load, float** %buf, align 8
17  %buf.load = load float*, float **%buf, !nonnull !0
18  ret float* %buf.load
19}
20
21; Check the case where the alloca in question has more than one
22; store but still within one basic block.
23define float* @single_block(float** %arg) {
24; CHECK-LABEL: define float* @single_block
25; CHECK: %arg.load = load float*, float** %arg, align 8
26; CHECK: [[ASSUME:%(.*)]] = icmp ne float* %arg.load, null
27; CHECK: call void @llvm.assume(i1 {{.*}}[[ASSUME]])
28; CHECK: ret float* %arg.load
29entry:
30  %buf = alloca float*
31  %arg.load = load float*, float** %arg, align 8
32  store float* null, float** %buf, align 8
33  store float* %arg.load, float** %buf, align 8
34  %buf.load = load float*, float **%buf, !nonnull !0
35  ret float* %buf.load
36}
37
38; Check the case where the alloca in question has more than one
39; store and also reads ands writes in multiple blocks.
40define float* @multi_block(float** %arg) {
41; CHECK-LABEL: define float* @multi_block
42; CHECK-LABEL: entry:
43; CHECK: %arg.load = load float*, float** %arg, align 8
44; CHECK: br label %next
45; CHECK-LABEL: next:
46; CHECK: [[ASSUME:%(.*)]] = icmp ne float* %arg.load, null
47; CHECK: call void @llvm.assume(i1 {{.*}}[[ASSUME]])
48; CHECK: ret float* %arg.load
49entry:
50  %buf = alloca float*
51  %arg.load = load float*, float** %arg, align 8
52  store float* null, float** %buf, align 8
53  br label %next
54next:
55  store float* %arg.load, float** %buf, align 8
56  %buf.load = load float*, float** %buf, !nonnull !0
57  ret float* %buf.load
58}
59
60; Check that we don't add an assume if it's not
61; necessary i.e. the value is already implied to be nonnull
62define float* @no_assume(float** %arg) {
63; CHECK-LABEL: define float* @no_assume
64; CHECK-LABEL: entry:
65; CHECK: %arg.load = load float*, float** %arg, align 8
66; CHECK: %cn = icmp ne float* %arg.load, null
67; CHECK: br i1 %cn, label %next, label %fin
68; CHECK-LABEL: next:
69; CHECK-NOT: call void @llvm.assume
70; CHECK: ret float* %arg.load
71; CHECK-LABEL: fin:
72; CHECK: ret float* null
73entry:
74  %buf = alloca float*
75  %arg.load = load float*, float** %arg, align 8
76  %cn = icmp ne float* %arg.load, null
77  br i1 %cn, label %next, label %fin
78next:
79; At this point the above nonnull check ensures that
80; the value %arg.load is nonnull in this block and thus
81; we need not add the assume.
82  store float* %arg.load, float** %buf, align 8
83  %buf.load = load float*, float** %buf, !nonnull !0
84  ret float* %buf.load
85fin:
86  ret float* null
87}
88
89!0 = !{}
90