1 ; RUN: opt < %s -mem2reg -S | FileCheck %s
3 ; This tests that mem2reg preserves the !nonnull metadata on loads
4 ; from allocas that get optimized out.
6 ; Check the case where the alloca in question has a single store.
7 define 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
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
21 ; Check the case where the alloca in question has more than one
22 ; store but still within one basic block.
23 define 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
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
38 ; Check the case where the alloca in question has more than one
39 ; store and also reads ands writes in multiple blocks.
40 define float* @multi_block(float** %arg) {
41 ; CHECK-LABEL: define float* @multi_block
43 ; CHECK: %arg.load = load float*, float** %arg, align 8
44 ; CHECK: br 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
51 %arg.load = load float*, float** %arg, align 8
52 store float* null, float** %buf, align 8
55 store float* %arg.load, float** %buf, align 8
56 %buf.load = load float*, float** %buf, !nonnull !0
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
62 define float* @no_assume(float** %arg) {
63 ; CHECK-LABEL: define float* @no_assume
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
69 ; CHECK-NOT: call void @llvm.assume
70 ; CHECK: ret float* %arg.load
72 ; CHECK: ret float* null
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
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