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 15define i32 @foo(i1 %z) { 16 %l = load i32, i32* @A 17 store i32 0, i32* @B 18 br i1 %z, label %true, label %false 19true: 20 ret i32 %l 21false: 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 31define 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 35true: 36 ret i32 %l 37false: 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 49define 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 54B0: ; preds = %0 55 br label %X 56 57B1: ; preds = %0 58 br label %X 59 60X: ; 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 72define i32 @alloca_nosink(i32 %a, i32 %b) { 73entry: 74 %0 = alloca i32 75 %1 = icmp ne i32 %a, 0 76 br i1 %1, label %if, label %endif 77 78if: 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 86endif: 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 97define i32 @alloca_sink_dynamic(i32 %a, i32 %b, i32 %size) { 98entry: 99 %0 = alloca i32, i32 %size 100 %1 = icmp ne i32 %a, 0 101 br i1 %1, label %if, label %endif 102 103if: 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 111endif: 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 124define i32 @alloca_sink_nonentry(i32 %a, i32 %b, i32 %c) { 125entry: 126 %cmp = icmp ne i32 %c, 0 127 br i1 %cmp, label %endif, label %if0 128 129if0: 130 %0 = alloca i32 131 %1 = icmp ne i32 %a, 0 132 br i1 %1, label %if, label %endif 133 134if: 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 142endif: 143 ret i32 0 144} 145