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, i32* @A 12 ; CHECK-NEXT: ret i32 %l 13 14 define i32 @foo(i1 %z) { 15 %l = load i32, i32* @A 16 store i32 0, i32* @B 17 br i1 %z, label %true, label %false 18 true: 19 ret i32 %l 20 false: 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 30 define i32 @foo2(i1 %z) { 31 %l = load volatile i32, i32* @A 32 store i32 0, i32* @B 33 br i1 %z, label %true, label %false 34 true: 35 ret i32 %l 36 false: 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 48 define 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 53 B0: ; preds = %0 54 br label %X 55 56 B1: ; preds = %0 57 br label %X 58 59 X: ; 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 71 define i32 @alloca_nosink(i32 %a, i32 %b) { 72 entry: 73 %0 = alloca i32 74 %1 = icmp ne i32 %a, 0 75 br i1 %1, label %if, label %endif 76 77 if: 78 %2 = getelementptr i32, i32* %0, i32 1 79 store i32 0, i32* %0 80 store i32 1, i32* %2 81 %3 = getelementptr i32, i32* %0, i32 %b 82 %4 = load i32, i32* %3 83 ret i32 %4 84 85 endif: 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 96 define i32 @alloca_sink_dynamic(i32 %a, i32 %b, i32 %size) { 97 entry: 98 %0 = alloca i32, i32 %size 99 %1 = icmp ne i32 %a, 0 100 br i1 %1, label %if, label %endif 101 102 if: 103 %2 = getelementptr i32, i32* %0, i32 1 104 store i32 0, i32* %0 105 store i32 1, i32* %2 106 %3 = getelementptr i32, i32* %0, i32 %b 107 %4 = load i32, i32* %3 108 ret i32 %4 109 110 endif: 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 123 define i32 @alloca_sink_nonentry(i32 %a, i32 %b, i32 %c) { 124 entry: 125 %cmp = icmp ne i32 %c, 0 126 br i1 %cmp, label %endif, label %if0 127 128 if0: 129 %0 = alloca i32 130 %1 = icmp ne i32 %a, 0 131 br i1 %1, label %if, label %endif 132 133 if: 134 %2 = getelementptr i32, i32* %0, i32 1 135 store i32 0, i32* %0 136 store i32 1, i32* %2 137 %3 = getelementptr i32, i32* %0, i32 %b 138 %4 = load i32, i32* %3 139 ret i32 %4 140 141 endif: 142 ret i32 0 143 } 144