Home | History | Annotate | Download | only in TypeBasedAliasAnalysis
      1 ; RUN: opt < %s -tbaa -basicaa -aa-eval -evaluate-aa-metadata \
      2 ; RUN:     -print-no-aliases -print-may-aliases -disable-output 2>&1 | \
      3 ; RUN:     FileCheck %s
      4 ; RUN: opt < %s -tbaa -basicaa -gvn -S | FileCheck %s --check-prefix=OPT
      5 ;
      6 ; Check that TBAA handles access tags with aggregate final access types
      7 ; correctly.
      8 
      9 %A = type { i32 }  ; struct A { int i; };
     10 %B = type { %A }   ; struct B { A a; };
     11 %C = type { %B }   ; struct C { B b; };
     12 %D = type { i16 }  ; struct D { short s; };
     13 
     14 ; int vs. A::i  =>  MayAlias.
     15 define i32 @f1(i32* %i, %A* %a) {
     16 entry:
     17 ; CHECK-LABEL: f1
     18 ; CHECK: MayAlias: store i32 7, {{.*}} <-> store i32 5,
     19 ; OPT-LABEL: f1
     20 ; OPT: store i32 5,
     21 ; OPT: store i32 7,
     22 ; OPT: %[[RET:.*]] = load i32,
     23 ; OPT: ret i32 %[[RET]]
     24   store i32 5, i32* %i, align 4, !tbaa !3  ; TAG_int
     25   %A_i = getelementptr inbounds %A, %A* %a, i64 0, i32 0
     26   store i32 7, i32* %A_i, align 4, !tbaa !5  ; TAG_A_i
     27   %0 = load i32, i32* %i, align 4, !tbaa !3  ; TAG_int
     28   ret i32 %0
     29 }
     30 
     31 ; int vs. B::a  =>  MayAlias.
     32 define i32 @f2(i32* %i, %B* %b) {
     33 entry:
     34 ; CHECK-LABEL: f2
     35 ; CHECK: MayAlias: store i32 7, {{.*}} <-> store i32 5,
     36 ; OPT-LABEL: f2
     37 ; OPT: store i32 5,
     38 ; OPT: store i32 7,
     39 ; OPT: %[[RET:.*]] = load i32,
     40 ; OPT: ret i32 %[[RET]]
     41   store i32 5, i32* %i, align 4, !tbaa !3  ; TAG_int
     42   %B_a = getelementptr inbounds %B, %B* %b, i64 0, i32 0, i32 0
     43   store i32 7, i32* %B_a, align 4, !tbaa !7  ; TAG_B_a
     44   %0 = load i32, i32* %i, align 4, !tbaa !3  ; TAG_int
     45   ret i32 %0
     46 }
     47 
     48 ; int vs. C::b  =>  MayAlias.
     49 define i32 @f3(i32* %i, %C* %c) {
     50 entry:
     51 ; CHECK-LABEL: f3
     52 ; CHECK: MayAlias: store i32 7, {{.*}} <-> store i32 5,
     53 ; OPT-LABEL: f3
     54 ; OPT: store i32 5,
     55 ; OPT: store i32 7,
     56 ; OPT: %[[RET:.*]] = load i32,
     57 ; OPT: ret i32 %[[RET]]
     58   store i32 5, i32* %i, align 4, !tbaa !3  ; TAG_int
     59   %C_b = getelementptr inbounds %C, %C* %c, i64 0, i32 0, i32 0, i32 0
     60   store i32 7, i32* %C_b, align 4, !tbaa !9  ; TAG_C_b
     61   %0 = load i32, i32* %i, align 4, !tbaa !3  ; TAG_int
     62   ret i32 %0
     63 }
     64 
     65 ; A vs. C::b  =>  MayAlias.
     66 define i32 @f4(%A* %a, %C* %c) {
     67 entry:
     68 ; CHECK-LABEL: f4
     69 ; CHECK: MayAlias: store i32 7, {{.*}} <-> store i32 5,
     70 ; OPT-LABEL: f4
     71 ; OPT: store i32 5,
     72 ; OPT: store i32 7,
     73 ; OPT: %[[RET:.*]] = load i32,
     74 ; OPT: ret i32 %[[RET]]
     75   %ap = getelementptr inbounds %A, %A* %a, i64 0, i32 0
     76   store i32 5, i32* %ap, align 4, !tbaa !10   ; TAG_A
     77   %C_b = getelementptr inbounds %C, %C* %c, i64 0, i32 0, i32 0, i32 0
     78   store i32 7, i32* %C_b, align 4, !tbaa !9   ; TAG_C_b
     79   %0 = load i32, i32* %ap, align 4, !tbaa !10  ; TAG_A
     80   ret i32 %0
     81 }
     82 
     83 ; short vs. C::b  =>  NoAlias.
     84 define i32 @f5(i32* %i, %C* %c) {
     85 entry:
     86 ; CHECK-LABEL: f5
     87 ; CHECK: NoAlias: store i32 7, {{.*}} <-> store i32 5,
     88 ; OPT-LABEL: f5
     89 ; OPT: store i32 5,
     90 ; OPT: store i32 7,
     91 ; OPT: ret i32 5
     92   store i32 5, i32* %i, align 4, !tbaa !12  ; TAG_short
     93   %C_b = getelementptr inbounds %C, %C* %c, i64 0, i32 0, i32 0, i32 0
     94   store i32 7, i32* %C_b, align 4, !tbaa !9  ; TAG_C_b
     95   %0 = load i32, i32* %i, align 4, !tbaa !12  ; TAG_short
     96   ret i32 %0
     97 }
     98 
     99 ; C vs. D  =>  NoAlias.
    100 define i32 @f6(%C* %c, %D* %d) {
    101 entry:
    102 ; CHECK-LABEL: f6
    103 ; CHECK: NoAlias: store i16 7, {{.*}} <-> store i32 5,
    104 ; OPT-LABEL: f6
    105 ; OPT: store i32 5,
    106 ; OPT: store i16 7,
    107 ; OPT: ret i32 5
    108   %cp = getelementptr inbounds %C, %C* %c, i64 0, i32 0, i32 0, i32 0
    109   store i32 5, i32* %cp, align 4, !tbaa !13  ; TAG_C
    110   %dp = getelementptr inbounds %D, %D* %d, i64 0, i32 0
    111   store i16 7, i16* %dp, align 4, !tbaa !15  ; TAG_D
    112   %0 = load i32, i32* %cp, align 4, !tbaa !13  ; TAG_C
    113   ret i32 %0
    114 }
    115 
    116 !0 = !{!"root"}
    117 !1 = !{!0, i64 1, !"char"}
    118 !2 = !{!1, i64 4, !"int"}
    119 !3 = !{!2, !2, i64 0, i64 4}  ; TAG_int
    120 
    121 !4 = !{!1, i64 4, !"A", !2, i64 0, i64 4}
    122 !5 = !{!4, !2, i64 0, i64 4}  ; TAG_A_i
    123 
    124 !6 = !{!1, i64 4, !"B", !4, i64 0, i64 4}
    125 !7 = !{!6, !4, i64 0, i64 4}  ; TAG_B_a
    126 
    127 !8 = !{!1, i64 4, !"C", !6, i64 0, i64 4}
    128 !9 = !{!8, !6, i64 0, i64 4}  ; TAG_C_b
    129 
    130 !10 = !{!4, !4, i64 0, i64 4}  ; TAG_A
    131 
    132 !11 = !{!1, i64 2, !"short"}
    133 !12 = !{!11, !11, i64 0, i64 2}  ; TAG_short
    134 
    135 !13 = !{!8, !8, i64 0, i64 4}  ; TAG_C
    136 
    137 !14 = !{!4, i64 2, !"D", !11, i64 0, i64 2}
    138 !15 = !{!14, !14, i64 0, i64 2}  ; TAG_D
    139