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
4 ; Test that we only promote arguments when the caller/callee have compatible
7 target triple = "x86_64-unknown-linux-gnu"
9 define internal fastcc void @no_promote_avx2(ptr %arg, ptr readonly %arg1) #0 {
10 ; CHECK: Function Attrs: inlinehint mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable
11 ; CHECK-LABEL: define {{[^@]+}}@no_promote_avx2
12 ; CHECK-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], ptr noalias nocapture nofree noundef nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]]) #[[ATTR0:[0-9]+]] {
14 ; CHECK-NEXT: [[TMP:%.*]] = load <4 x i64>, ptr [[ARG1]], align 32
15 ; CHECK-NEXT: store <4 x i64> [[TMP]], ptr [[ARG]], align 32
16 ; CHECK-NEXT: ret void
19 %tmp = load <4 x i64>, ptr %arg1
20 store <4 x i64> %tmp, ptr %arg
24 define void @no_promote(ptr %arg) #1 {
25 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable
26 ; TUNIT-LABEL: define {{[^@]+}}@no_promote
27 ; TUNIT-SAME: (ptr nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR1:[0-9]+]] {
29 ; TUNIT-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
30 ; TUNIT-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
31 ; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR3:[0-9]+]]
32 ; TUNIT-NEXT: call fastcc void @no_promote_avx2(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP2]], ptr noalias nocapture nofree noundef nonnull readonly align 32 dereferenceable(32) [[TMP]]) #[[ATTR4:[0-9]+]]
33 ; TUNIT-NEXT: [[TMP4:%.*]] = load <4 x i64>, ptr [[TMP2]], align 32
34 ; TUNIT-NEXT: store <4 x i64> [[TMP4]], ptr [[ARG]], align 2
35 ; TUNIT-NEXT: ret void
37 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) uwtable
38 ; CGSCC-LABEL: define {{[^@]+}}@no_promote
39 ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 2 dereferenceable(32) [[ARG:%.*]]) #[[ATTR1:[0-9]+]] {
41 ; CGSCC-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
42 ; CGSCC-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
43 ; CGSCC-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR3:[0-9]+]]
44 ; CGSCC-NEXT: call fastcc void @no_promote_avx2(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP2]], ptr noalias nocapture nofree noundef nonnull readonly align 32 dereferenceable(32) [[TMP]]) #[[ATTR4:[0-9]+]]
45 ; CGSCC-NEXT: [[TMP4:%.*]] = load <4 x i64>, ptr [[TMP2]], align 32
46 ; CGSCC-NEXT: store <4 x i64> [[TMP4]], ptr [[ARG]], align 2
47 ; CGSCC-NEXT: ret void
50 %tmp = alloca <4 x i64>, align 32
51 %tmp2 = alloca <4 x i64>, align 32
52 call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
53 call fastcc void @no_promote_avx2(ptr %tmp2, ptr %tmp)
54 %tmp4 = load <4 x i64>, ptr %tmp2, align 32
55 store <4 x i64> %tmp4, ptr %arg, align 2
59 define internal fastcc void @promote_avx2(ptr %arg, ptr readonly %arg1) #0 {
60 ; CHECK: Function Attrs: inlinehint mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable
61 ; CHECK-LABEL: define {{[^@]+}}@promote_avx2
62 ; CHECK-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64> [[TMP0:%.*]]) #[[ATTR0]] {
64 ; CHECK-NEXT: [[ARG1_PRIV:%.*]] = alloca <4 x i64>, align 32
65 ; CHECK-NEXT: store <4 x i64> [[TMP0]], ptr [[ARG1_PRIV]], align 32
66 ; CHECK-NEXT: [[TMP:%.*]] = load <4 x i64>, ptr [[ARG1_PRIV]], align 32
67 ; CHECK-NEXT: store <4 x i64> [[TMP]], ptr [[ARG]], align 32
68 ; CHECK-NEXT: ret void
71 %tmp = load <4 x i64>, ptr %arg1
72 store <4 x i64> %tmp, ptr %arg
76 define void @promote(ptr %arg) #0 {
77 ; TUNIT: Function Attrs: inlinehint mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable
78 ; TUNIT-LABEL: define {{[^@]+}}@promote
79 ; TUNIT-SAME: (ptr nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR0]] {
81 ; TUNIT-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
82 ; TUNIT-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
83 ; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR3]]
84 ; TUNIT-NEXT: [[TMP0:%.*]] = load <4 x i64>, ptr [[TMP]], align 32
85 ; TUNIT-NEXT: call fastcc void @promote_avx2(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64> [[TMP0]]) #[[ATTR4]]
86 ; TUNIT-NEXT: [[TMP4:%.*]] = load <4 x i64>, ptr [[TMP2]], align 32
87 ; TUNIT-NEXT: store <4 x i64> [[TMP4]], ptr [[ARG]], align 2
88 ; TUNIT-NEXT: ret void
90 ; CGSCC: Function Attrs: inlinehint mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable
91 ; CGSCC-LABEL: define {{[^@]+}}@promote
92 ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 2 dereferenceable(32) [[ARG:%.*]]) #[[ATTR0]] {
94 ; CGSCC-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
95 ; CGSCC-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
96 ; CGSCC-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR3]]
97 ; CGSCC-NEXT: [[TMP0:%.*]] = load <4 x i64>, ptr [[TMP]], align 32
98 ; CGSCC-NEXT: call fastcc void @promote_avx2(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64> [[TMP0]]) #[[ATTR4]]
99 ; CGSCC-NEXT: [[TMP4:%.*]] = load <4 x i64>, ptr [[TMP2]], align 32
100 ; CGSCC-NEXT: store <4 x i64> [[TMP4]], ptr [[ARG]], align 2
101 ; CGSCC-NEXT: ret void
104 %tmp = alloca <4 x i64>, align 32
105 %tmp2 = alloca <4 x i64>, align 32
106 call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
107 call fastcc void @promote_avx2(ptr %tmp2, ptr %tmp)
108 %tmp4 = load <4 x i64>, ptr %tmp2, align 32
109 store <4 x i64> %tmp4, ptr %arg, align 2
113 ; Function Attrs: argmemonly nounwind
114 declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1) #2
116 attributes #0 = { inlinehint norecurse nounwind uwtable "target-features"="+avx2" }
117 attributes #1 = { nounwind uwtable }
118 attributes #2 = { argmemonly nounwind }
120 ; TUNIT: attributes #[[ATTR0]] = { inlinehint mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable "target-features"="+avx2" }
121 ; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable }
122 ; TUNIT: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
123 ; TUNIT: attributes #[[ATTR3]] = { nofree willreturn memory(write) }
124 ; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn }
126 ; CGSCC: attributes #[[ATTR0]] = { inlinehint mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable "target-features"="+avx2" }
127 ; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) uwtable }
128 ; CGSCC: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
129 ; CGSCC: attributes #[[ATTR3]] = { nofree willreturn memory(write) }
130 ; CGSCC: attributes #[[ATTR4]] = { nofree nounwind willreturn }