a3f5083720831727a20c5e90dd7ec0ac4a27ac75
[oota-llvm.git] / test / Analysis / GlobalsModRef / nonescaping-noalias.ll
1 ; RUN: opt < %s -globalsmodref-aa -gvn -S | FileCheck %s
2 ;
3 ; This tests the safe no-alias conclusions of GMR -- when there is
4 ; a non-escaping global as one indentified underlying object and some pointer
5 ; that would inherently have escaped any other function as the other underlying
6 ; pointer of an alias query.
7
8 @g1 = internal global i32 0
9
10 define i32 @test1(i32* %param) {
11 ; Ensure that we can fold a store to a load of a global across a store to
12 ; a parameter when the global is non-escaping.
13 ;
14 ; CHECK-LABEL: @test1(
15 ; CHECK: store i32 42, i32* @g1
16 ; CHECK-NOT: load i32
17 ; CHECK: ret i32 42
18 entry:
19   store i32 42, i32* @g1
20   store i32 7, i32* %param
21   %v = load i32, i32* @g1
22   ret i32 %v
23 }
24
25 declare i32* @f()
26
27 define i32 @test2() {
28 ; Ensure that we can fold a store to a load of a global across a store to
29 ; the pointer returned by a function call. Since the global could not escape,
30 ; this function cannot be returning its address.
31 ;
32 ; CHECK-LABEL: @test2(
33 ; CHECK: store i32 42, i32* @g1
34 ; CHECK-NOT: load i32
35 ; CHECK: ret i32 42
36 entry:
37   %ptr = call i32* @f() readnone
38   store i32 42, i32* @g1
39   store i32 7, i32* %ptr
40   %v = load i32, i32* @g1
41   ret i32 %v
42 }
43
44 @g2 = external global i32*
45
46 define i32 @test3() {
47 ; Ensure that we can fold a store to a load of a global across a store to
48 ; the pointer loaded from that global. Because the global does not escape, it
49 ; cannot alias a pointer loaded out of a global.
50 ;
51 ; CHECK-LABEL: @test3(
52 ; CHECK: store i32 42, i32* @g1
53 ; CHECK: store i32 7, i32*
54 ; CHECK-NOT: load i32
55 ; CHECK: ret i32 42
56 entry:
57   store i32 42, i32* @g1
58   %ptr1 = load i32*, i32** @g2
59   store i32 7, i32* %ptr1
60   %v = load i32, i32* @g1
61   ret i32 %v
62 }
63
64 @g3 = internal global i32 1
65
66 define i32 @test4(i32* %param, i32 %n, i1 %c1, i1 %c2, i1 %c3) {
67 ; Ensure that we can fold a store to a load of a global across a store to
68 ; the pointer loaded from that global even when the load is behind PHIs and
69 ; selects, and there is a mixture of a load and another global or argument.
70 ; Note that we can't eliminate the load here because it is used in a PHI and
71 ; GVN doesn't try to do real DCE. The store is still forwarded by GVN though.
72 ;
73 ; CHECK-LABEL: @test4(
74 ; CHECK: store i32 42, i32* @g1
75 ; CHECK: store i32 7, i32*
76 ; CHECK: ret i32 42
77 entry:
78   %call = call i32* @f()
79   store i32 42, i32* @g1
80   %ptr1 = load i32*, i32** @g2
81   %ptr2 = select i1 %c1, i32* %ptr1, i32* %param
82   %ptr3 = select i1 %c3, i32* %ptr2, i32* @g3
83   br label %loop
84
85 loop:
86   %iv = phi i32 [ 0, %entry ], [ %inc, %loop ]
87   %ptr = phi i32* [ %ptr3, %entry ], [ %ptr5, %loop ]
88   store i32 7, i32* %ptr
89   %ptr4 = load i32*, i32** @g2
90   %ptr5 = select i1 %c2, i32* %ptr4, i32* %call
91   %inc = add i32 %iv, 1
92   %test = icmp slt i32 %inc, %n
93   br i1 %test, label %loop, label %exit
94
95 exit:
96   %v = load i32, i32* @g1
97   ret i32 %v
98 }