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