Home | History | Annotate | Download | only in Mem2Reg
      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