Home | History | Annotate | Download | only in Sink
      1 ; RUN: opt < %s -basicaa -sink -S | FileCheck %s
      2 ; RUN: opt < %s -aa-pipeline='basic-aa' -passes='sink' -S | FileCheck %s
      3 
      4 @A = external global i32
      5 @B = external global i32
      6 
      7 ; Sink should sink the load past the store (which doesn't overlap) into
      8 ; the block that uses it.
      9 
     10 ;      CHECK-LABEL: @foo(
     11 ;      CHECK: true:
     12 ; CHECK-NEXT: %l = load i32, i32* @A
     13 ; CHECK-NEXT: ret i32 %l
     14 
     15 define i32 @foo(i1 %z) {
     16   %l = load i32, i32* @A
     17   store i32 0, i32* @B
     18   br i1 %z, label %true, label %false
     19 true:
     20   ret i32 %l
     21 false:
     22   ret i32 0
     23 }
     24 
     25 ; But don't sink load volatiles...
     26 
     27 ;      CHECK-LABEL: @foo2(
     28 ;      CHECK: load volatile
     29 ; CHECK-NEXT: store i32
     30 
     31 define i32 @foo2(i1 %z) {
     32   %l = load volatile i32, i32* @A
     33   store i32 0, i32* @B
     34   br i1 %z, label %true, label %false
     35 true:
     36   ret i32 %l
     37 false:
     38   ret i32 0
     39 }
     40 
     41 ; Sink to the nearest post-dominator
     42 
     43 ;      CHECK-LABEL: @diamond(
     44 ;      CHECK: X:
     45 ; CHECK-NEXT: phi
     46 ; CHECK-NEXT: mul nsw
     47 ; CHECK-NEXT: sub
     48 
     49 define i32 @diamond(i32 %a, i32 %b, i32 %c) {
     50   %1 = mul nsw i32 %c, %b
     51   %2 = icmp sgt i32 %a, 0
     52   br i1 %2, label %B0, label %B1
     53 
     54 B0:                                       ; preds = %0
     55   br label %X
     56 
     57 B1:                                      ; preds = %0
     58   br label %X
     59 
     60 X:                                     ; preds = %5, %3
     61   %.01 = phi i32 [ %c, %B0 ], [ %a, %B1 ]
     62   %R = sub i32 %1, %.01
     63   ret i32 %R
     64 }
     65 
     66 ; We shouldn't sink constant sized allocas from the entry block, since CodeGen
     67 ; interprets allocas outside the entry block as dynamically sized stack objects.
     68 
     69 ; CHECK-LABEL: @alloca_nosink
     70 ; CHECK: entry:
     71 ; CHECK-NEXT: alloca
     72 define i32 @alloca_nosink(i32 %a, i32 %b) {
     73 entry:
     74   %0 = alloca i32
     75   %1 = icmp ne i32 %a, 0
     76   br i1 %1, label %if, label %endif
     77 
     78 if:
     79   %2 = getelementptr i32, i32* %0, i32 1
     80   store i32 0, i32* %0
     81   store i32 1, i32* %2
     82   %3 = getelementptr i32, i32* %0, i32 %b
     83   %4 = load i32, i32* %3
     84   ret i32 %4
     85 
     86 endif:
     87   ret i32 0
     88 }
     89 
     90 ; Make sure we sink dynamic sized allocas
     91 
     92 ; CHECK-LABEL: @alloca_sink_dynamic
     93 ; CHECK: entry:
     94 ; CHECK-NOT: alloca
     95 ; CHECK: if:
     96 ; CHECK-NEXT: alloca
     97 define i32 @alloca_sink_dynamic(i32 %a, i32 %b, i32 %size) {
     98 entry:
     99   %0 = alloca i32, i32 %size
    100   %1 = icmp ne i32 %a, 0
    101   br i1 %1, label %if, label %endif
    102 
    103 if:
    104   %2 = getelementptr i32, i32* %0, i32 1
    105   store i32 0, i32* %0
    106   store i32 1, i32* %2
    107   %3 = getelementptr i32, i32* %0, i32 %b
    108   %4 = load i32, i32* %3
    109   ret i32 %4
    110 
    111 endif:
    112   ret i32 0
    113 }
    114 
    115 ; We also want to sink allocas that are not in the entry block.  These
    116 ; will already be considered as dynamically sized stack objects, so sinking
    117 ; them does no further damage.
    118 
    119 ; CHECK-LABEL: @alloca_sink_nonentry
    120 ; CHECK: if0:
    121 ; CHECK-NOT: alloca
    122 ; CHECK: if:
    123 ; CHECK-NEXT: alloca
    124 define i32 @alloca_sink_nonentry(i32 %a, i32 %b, i32 %c) {
    125 entry:
    126   %cmp = icmp ne i32 %c, 0
    127   br i1 %cmp, label %endif, label %if0
    128 
    129 if0:
    130   %0 = alloca i32
    131   %1 = icmp ne i32 %a, 0
    132   br i1 %1, label %if, label %endif
    133 
    134 if:
    135   %2 = getelementptr i32, i32* %0, i32 1
    136   store i32 0, i32* %0
    137   store i32 1, i32* %2
    138   %3 = getelementptr i32, i32* %0, i32 %b
    139   %4 = load i32, i32* %3
    140   ret i32 %4
    141 
    142 endif:
    143   ret i32 0
    144 }
    145