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