Home | History | Annotate | Download | only in GlobalsModRef
      1 ; RUN: opt < %s -globals-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 @g4 = internal global [10 x i32*] zeroinitializer
     66 
     67 define i32 @test4(i32* %param, i32 %n, i1 %c1, i1 %c2, i1 %c3) {
     68 ; Ensure that we can fold a store to a load of a global across a store to
     69 ; the pointer loaded from that global even when the load is behind PHIs and
     70 ; selects, and there is a mixture of a load and another global or argument.
     71 ; Note that we can't eliminate the load here because it is used in a PHI and
     72 ; GVN doesn't try to do real DCE. The store is still forwarded by GVN though.
     73 ;
     74 ; CHECK-LABEL: @test4(
     75 ; CHECK: store i32 42, i32* @g1
     76 ; CHECK: store i32 7, i32*
     77 ; CHECK: ret i32 42
     78 entry:
     79   %call = call i32* @f()
     80   store i32 42, i32* @g1
     81   %ptr1 = load i32*, i32** @g2
     82   %ptr2 = select i1 %c1, i32* %ptr1, i32* %param
     83   %ptr3 = select i1 %c3, i32* %ptr2, i32* @g3
     84   br label %loop
     85 
     86 loop:
     87   %iv = phi i32 [ 0, %entry ], [ %inc, %loop ]
     88   %ptr = phi i32* [ %ptr3, %entry ], [ %ptr5, %loop ]
     89   store i32 7, i32* %ptr
     90   %ptr4 = load i32*, i32** getelementptr ([10 x i32*], [10 x i32*]* @g4, i32 0, i32 1)
     91   %ptr5 = select i1 %c2, i32* %ptr4, i32* %call
     92   %inc = add i32 %iv, 1
     93   %test = icmp slt i32 %inc, %n
     94   br i1 %test, label %loop, label %exit
     95 
     96 exit:
     97   %v = load i32, i32* @g1
     98   ret i32 %v
     99 }
    100 
    101 define i32 @test5(i32** %param) {
    102 ; Ensure that we can fold a store to a load of a global across a store to
    103 ; a parameter that has been dereferenced when the global is non-escaping.
    104 ;
    105 ; CHECK-LABEL: @test5(
    106 ; CHECK: %p = load i32*
    107 ; CHECK: store i32 42, i32* @g1
    108 ; CHECK-NOT: load i32
    109 ; CHECK: ret i32 42
    110 entry:
    111   %p = load i32*, i32** %param
    112   store i32 42, i32* @g1
    113   store i32 7, i32* %p
    114   %v = load i32, i32* @g1
    115   ret i32 %v
    116 }
    117