[GMR] Teach the conservative path of GMR to catch even more easy cases.
[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 define i32 @test4(i32* %param, i32 %n, i1 %c1, i1 %c2) {
65 ; Ensure that we can fold a store to a load of a global across a store to
66 ; the pointer loaded from that global even when the load is behind PHIs and
67 ; selects, and there is a mixture of a load and another global or argument.
68 ; Note that we can't eliminate the load here because it is used in a PHI and
69 ; GVN doesn't try to do real DCE. The store is still forwarded by GVN though.
70 ;
71 ; CHECK-LABEL: @test4(
72 ; CHECK: store i32 42, i32* @g1
73 ; CHECK: store i32 7, i32*
74 ; CHECK: ret i32 42
75 entry:
76   %call = call i32* @f()
77   store i32 42, i32* @g1
78   %ptr1 = load i32*, i32** @g2
79   %ptr2 = select i1 %c1, i32* %ptr1, i32* %param
80   br label %loop
81
82 loop:
83   %iv = phi i32 [ 0, %entry ], [ %inc, %loop ]
84   %ptr = phi i32* [ %ptr2, %entry ], [ %ptr4, %loop ]
85   store i32 7, i32* %ptr
86   %ptr3 = load i32*, i32** @g2
87   %ptr4 = select i1 %c2, i32* %ptr3, i32* %call
88   %inc = add i32 %iv, 1
89   %test = icmp slt i32 %inc, %n
90   br i1 %test, label %loop, label %exit
91
92 exit:
93   %v = load i32, i32* @g1
94   ret i32 %v
95 }