1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
6 ; When we promote two arguments in a single function with different types,
7 ; before the fix, we used the same tag for the newly-created two loads.
8 ; This testing case makes sure that we correctly transfer the tbaa tags from the
9 ; original loads to the newly-created loads when promoting pointer arguments.
11 @a = global ptr null, align 8
12 @e = global ptr @a, align 8
13 @g = global i32 0, align 4
14 @c = global i64 0, align 8
15 @d = global i8 0, align 1
18 ; CHECK: @a = global ptr null, align 8
19 ; CHECK: @e = global ptr @a, align 8
20 ; CHECK: @g = global i32 0, align 4
21 ; CHECK: @c = global i64 0, align 8
22 ; CHECK: @d = global i8 0, align 1
24 define internal fastcc void @fn(ptr nocapture readonly %p1, ptr nocapture readonly %p2) {
25 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: none)
26 ; CHECK-LABEL: define {{[^@]+}}@fn
27 ; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
29 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @g, align 4, !tbaa [[TBAA0:![0-9]+]]
30 ; CHECK-NEXT: [[CONV1:%.*]] = trunc i32 [[TMP0]] to i8
31 ; CHECK-NEXT: store i8 [[CONV1]], ptr @d, align 1, !tbaa [[TBAA4:![0-9]+]]
32 ; CHECK-NEXT: ret void
35 %0 = load i64, ptr %p2, align 8, !tbaa !1
36 %conv = trunc i64 %0 to i32
37 %1 = load i32, ptr %p1, align 4, !tbaa !5
38 %conv1 = trunc i32 %1 to i8
39 store i8 %conv1, ptr @d, align 1, !tbaa !7
44 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
45 ; TUNIT-LABEL: define {{[^@]+}}@main
46 ; TUNIT-SAME: () #[[ATTR1:[0-9]+]] {
48 ; TUNIT-NEXT: [[TMP0:%.*]] = load ptr, ptr @e, align 8, !tbaa [[TBAA5:![0-9]+]]
49 ; TUNIT-NEXT: store ptr @g, ptr [[TMP0]], align 8, !tbaa [[TBAA5]]
50 ; TUNIT-NEXT: [[TMP1:%.*]] = load ptr, ptr @a, align 8, !tbaa [[TBAA5]]
51 ; TUNIT-NEXT: store i32 1, ptr [[TMP1]], align 4, !tbaa [[TBAA0]]
52 ; TUNIT-NEXT: call fastcc void @fn() #[[ATTR2:[0-9]+]]
53 ; TUNIT-NEXT: ret i32 0
55 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
56 ; CGSCC-LABEL: define {{[^@]+}}@main
57 ; CGSCC-SAME: () #[[ATTR1:[0-9]+]] {
59 ; CGSCC-NEXT: [[TMP0:%.*]] = load ptr, ptr @e, align 8, !tbaa [[TBAA5:![0-9]+]]
60 ; CGSCC-NEXT: store ptr @g, ptr [[TMP0]], align 8, !tbaa [[TBAA5]]
61 ; CGSCC-NEXT: [[TMP1:%.*]] = load ptr, ptr @a, align 8, !tbaa [[TBAA5]]
62 ; CGSCC-NEXT: store i32 1, ptr [[TMP1]], align 4, !tbaa [[TBAA0]]
63 ; CGSCC-NEXT: call fastcc void @fn() #[[ATTR2:[0-9]+]]
64 ; CGSCC-NEXT: ret i32 0
67 %0 = load ptr, ptr @e, align 8, !tbaa !8
68 store ptr @g, ptr %0, align 8, !tbaa !8
69 %1 = load ptr, ptr @a, align 8, !tbaa !8
70 store i32 1, ptr %1, align 4, !tbaa !5
71 call fastcc void @fn(ptr @g, ptr @c)
77 !2 = !{!"long", !3, i64 0}
78 !3 = !{!"omnipotent char", !4, i64 0}
79 !4 = !{!"Simple C/C++ TBAA"}
81 !6 = !{!"int", !3, i64 0}
84 !9 = !{!"any pointer", !3, i64 0}
87 ; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: none) }
88 ; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn }
89 ; TUNIT: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn }
91 ; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: none) }
92 ; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn }
93 ; CGSCC: attributes #[[ATTR2]] = { nofree nounwind willreturn }
95 ; TUNIT: [[TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}
96 ; TUNIT: [[META1]] = !{!"int", [[META2:![0-9]+]], i64 0}
97 ; TUNIT: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0}
98 ; TUNIT: [[META3]] = !{!"Simple C/C++ TBAA"}
99 ; TUNIT: [[TBAA4]] = !{[[META2]], [[META2]], i64 0}
100 ; TUNIT: [[TBAA5]] = !{[[META6:![0-9]+]], [[META6]], i64 0}
101 ; TUNIT: [[META6]] = !{!"any pointer", [[META2]], i64 0}
103 ; CGSCC: [[TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}
104 ; CGSCC: [[META1]] = !{!"int", [[META2:![0-9]+]], i64 0}
105 ; CGSCC: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0}
106 ; CGSCC: [[META3]] = !{!"Simple C/C++ TBAA"}
107 ; CGSCC: [[TBAA4]] = !{[[META2]], [[META2]], i64 0}
108 ; CGSCC: [[TBAA5]] = !{[[META6:![0-9]+]], [[META6]], i64 0}
109 ; CGSCC: [[META6]] = !{!"any pointer", [[META2]], i64 0}