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. 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 13 entry: 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. 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 29 entry: 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. 40 define 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 49 entry: 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 54 next: 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 62 define 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 73 entry: 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 78 next: 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 85 fin: 86 ret float* null 87 } 88 89 !0 = !{} 90