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 14 define i32 @foo(i1 %z) { 15 %l = load 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* @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