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