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