llvm.org GIT mirror llvm / dc77158
[Attributor] Deduce "nonnull" attribute Summary: Porting nonnull attribute to attributor. Reviewers: jdoerfert, sstefan1 Reviewed By: jdoerfert Subscribers: xbolva00, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D63604 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366043 91177308-0d34-0410-b5e6-96231b3b80d8 Hideto Ueno a month ago
4 changed file(s) with 573 addition(s) and 66 deletion(s). Raw diff Collapse all Expand all
262262 Function &F, InformationCache &InfoCache,
263263 DenseSet *Whitelist = nullptr);
264264
265 /// Check \p Pred on all function call sites.
266 ///
267 /// This method will evaluate \p Pred on call sites and return
268 /// true if \p Pred holds in every call sites. However, this is only possible
269 /// all call sites are known, hence the function has internal linkage.
270 bool checkForAllCallSites(Function &F, std::function &Pred,
271 bool RequireAllCallSites);
272
265273 private:
266274 /// The set of all abstract attributes.
267275 ///{
707715 virtual bool isKnownNoSync() const = 0;
708716 };
709717
718 /// An abstract interface for all nonnull attributes.
719 struct AANonNull : public AbstractAttribute {
720
721 /// See AbstractAttribute::AbstractAttribute(...).
722 AANonNull(Value &V, InformationCache &InfoCache)
723 : AbstractAttribute(V, InfoCache) {}
724
725 /// See AbstractAttribute::AbstractAttribute(...).
726 AANonNull(Value *AssociatedVal, Value &AnchoredValue,
727 InformationCache &InfoCache)
728 : AbstractAttribute(AssociatedVal, AnchoredValue, InfoCache) {}
729
730 /// Return true if we assume that the underlying value is nonnull.
731 virtual bool isAssumedNonNull() const = 0;
732
733 /// Return true if we know that underlying value is nonnull.
734 virtual bool isKnownNonNull() const = 0;
735
736 /// See AbastractState::getAttrKind().
737 Attribute::AttrKind getAttrKind() const override { return ID; }
738
739 /// The identifier used by the Attributor for this class of attributes.
740 static constexpr Attribute::AttrKind ID = Attribute::NonNull;
741 };
710742 } // end namespace llvm
711743
712744 #endif // LLVM_TRANSFORMS_IPO_FUNCTIONATTRS_H
1919 #include "llvm/ADT/SmallVector.h"
2020 #include "llvm/ADT/Statistic.h"
2121 #include "llvm/Analysis/GlobalsModRef.h"
22 #include "llvm/Analysis/ValueTracking.h"
2223 #include "llvm/IR/Argument.h"
2324 #include "llvm/IR/Attributes.h"
2425 #include "llvm/IR/InstIterator.h"
5051 "Number of function arguments marked returned");
5152 STATISTIC(NumFnNoSync, "Number of functions marked nosync");
5253 STATISTIC(NumFnNoFree, "Number of functions marked nofree");
54 STATISTIC(NumFnReturnedNonNull,
55 "Number of function return values marked nonnull");
56 STATISTIC(NumFnArgumentNonNull, "Number of function arguments marked nonnull");
57 STATISTIC(NumCSArgumentNonNull, "Number of call site arguments marked nonnull");
5358
5459 // TODO: Determine a good default value.
5560 //
106111 break;
107112 case Attribute::NoFree:
108113 NumFnNoFree++;
114 break;
115 case Attribute::NonNull:
116 switch (MP) {
117 case AbstractAttribute::MP_RETURNED:
118 NumFnReturnedNonNull++;
119 break;
120 case AbstractAttribute::MP_ARGUMENT:
121 NumFnArgumentNonNull++;
122 break;
123 case AbstractAttribute::MP_CALL_SITE_ARGUMENT:
124 NumCSArgumentNonNull++;
125 break;
126 default:
127 break;
128 }
109129 break;
110130 default:
111131 return;
969989 return ChangeStatus::UNCHANGED;
970990 }
971991
992 /// ------------------------ NonNull Argument Attribute ------------------------
993 struct AANonNullImpl : AANonNull, BooleanState {
994
995 AANonNullImpl(Value &V, InformationCache &InfoCache)
996 : AANonNull(V, InfoCache) {}
997
998 AANonNullImpl(Value *AssociatedVal, Value &AnchoredValue,
999 InformationCache &InfoCache)
1000 : AANonNull(AssociatedVal, AnchoredValue, InfoCache) {}
1001
1002 /// See AbstractAttribute::getState()
1003 /// {
1004 AbstractState &getState() override { return *this; }
1005 const AbstractState &getState() const override { return *this; }
1006 /// }
1007
1008 /// See AbstractAttribute::getAsStr().
1009 const std::string getAsStr() const override {
1010 return getAssumed() ? "nonnull" : "may-null";
1011 }
1012
1013 /// See AANonNull::isAssumedNonNull().
1014 bool isAssumedNonNull() const override { return getAssumed(); }
1015
1016 /// See AANonNull::isKnownNonNull().
1017 bool isKnownNonNull() const override { return getKnown(); }
1018
1019 /// Generate a predicate that checks if a given value is assumed nonnull.
1020 /// The generated function returns true if a value satisfies any of
1021 /// following conditions.
1022 /// (i) A value is known nonZero(=nonnull).
1023 /// (ii) A value is associated with AANonNull and its isAssumedNonNull() is
1024 /// true.
1025 std::function generatePredicate(Attributor &);
1026 };
1027
1028 std::function AANonNullImpl::generatePredicate(Attributor &A) {
1029 // FIXME: The `AAReturnedValues` should provide the predicate with the
1030 // `ReturnInst` vector as well such that we can use the control flow sensitive
1031 // version of `isKnownNonZero`. This should fix `test11` in
1032 // `test/Transforms/FunctionAttrs/nonnull.ll`
1033
1034 std::function Pred = [&](Value &RV) -> bool {
1035 if (isKnownNonZero(&RV, getAnchorScope().getParent()->getDataLayout()))
1036 return true;
1037
1038 auto *NonNullAA = A.getAAFor(*this, RV);
1039
1040 ImmutableCallSite ICS(&RV);
1041
1042 if ((!NonNullAA || !NonNullAA->isAssumedNonNull()) &&
1043 (!ICS || !ICS.hasRetAttr(Attribute::NonNull)))
1044 return false;
1045
1046 return true;
1047 };
1048
1049 return Pred;
1050 }
1051
1052 /// NonNull attribute for function return value.
1053 struct AANonNullReturned : AANonNullImpl {
1054
1055 AANonNullReturned(Function &F, InformationCache &InfoCache)
1056 : AANonNullImpl(F, InfoCache) {}
1057
1058 /// See AbstractAttribute::getManifestPosition().
1059 ManifestPosition getManifestPosition() const override { return MP_RETURNED; }
1060
1061 /// See AbstractAttriubute::initialize(...).
1062 void initialize(Attributor &A) override {
1063 Function &F = getAnchorScope();
1064
1065 // Already nonnull.
1066 if (F.getAttributes().hasAttribute(AttributeList::ReturnIndex,
1067 Attribute::NonNull))
1068 indicateOptimisticFixpoint();
1069 }
1070
1071 /// See AbstractAttribute::updateImpl(...).
1072 ChangeStatus updateImpl(Attributor &A) override;
1073 };
1074
1075 ChangeStatus AANonNullReturned::updateImpl(Attributor &A) {
1076 Function &F = getAnchorScope();
1077
1078 auto *AARetVal = A.getAAFor(*this, F);
1079 if (!AARetVal) {
1080 indicatePessimisticFixpoint();
1081 return ChangeStatus::CHANGED;
1082 }
1083
1084 std::function Pred = this->generatePredicate(A);
1085 if (!AARetVal->checkForallReturnedValues(Pred)) {
1086 indicatePessimisticFixpoint();
1087 return ChangeStatus::CHANGED;
1088 }
1089 return ChangeStatus::UNCHANGED;
1090 }
1091
1092 /// NonNull attribute for function argument.
1093 struct AANonNullArgument : AANonNullImpl {
1094
1095 AANonNullArgument(Argument &A, InformationCache &InfoCache)
1096 : AANonNullImpl(A, InfoCache) {}
1097
1098 /// See AbstractAttribute::getManifestPosition().
1099 ManifestPosition getManifestPosition() const override { return MP_ARGUMENT; }
1100
1101 /// See AbstractAttriubute::initialize(...).
1102 void initialize(Attributor &A) override {
1103 Argument *Arg = cast(getAssociatedValue());
1104 if (Arg->hasNonNullAttr())
1105 indicateOptimisticFixpoint();
1106 }
1107
1108 /// See AbstractAttribute::updateImpl(...).
1109 ChangeStatus updateImpl(Attributor &A) override;
1110 };
1111
1112 /// NonNull attribute for a call site argument.
1113 struct AANonNullCallSiteArgument : AANonNullImpl {
1114
1115 /// See AANonNullImpl::AANonNullImpl(...).
1116 AANonNullCallSiteArgument(CallSite CS, unsigned ArgNo,
1117 InformationCache &InfoCache)
1118 : AANonNullImpl(CS.getArgOperand(ArgNo), *CS.getInstruction(), InfoCache),
1119 ArgNo(ArgNo) {}
1120
1121 /// See AbstractAttribute::initialize(...).
1122 void initialize(Attributor &A) override {
1123 CallSite CS(&getAnchoredValue());
1124 if (isKnownNonZero(getAssociatedValue(),
1125 getAnchorScope().getParent()->getDataLayout()) ||
1126 CS.paramHasAttr(ArgNo, getAttrKind()))
1127 indicateOptimisticFixpoint();
1128 }
1129
1130 /// See AbstractAttribute::updateImpl(Attributor &A).
1131 ChangeStatus updateImpl(Attributor &A) override;
1132
1133 /// See AbstractAttribute::getManifestPosition().
1134 ManifestPosition getManifestPosition() const override {
1135 return MP_CALL_SITE_ARGUMENT;
1136 };
1137
1138 // Return argument index of associated value.
1139 int getArgNo() const { return ArgNo; }
1140
1141 private:
1142 unsigned ArgNo;
1143 };
1144 ChangeStatus AANonNullArgument::updateImpl(Attributor &A) {
1145 Function &F = getAnchorScope();
1146 Argument &Arg = cast(getAnchoredValue());
1147
1148 unsigned ArgNo = Arg.getArgNo();
1149
1150 // Callback function
1151 std::function CallSiteCheck = [&](CallSite CS) {
1152 assert(CS && "Sanity check: Call site was not initialized properly!");
1153
1154 auto *NonNullAA = A.getAAFor(*this, *CS.getInstruction(), ArgNo);
1155
1156 // Check that NonNullAA is AANonNullCallSiteArgument.
1157 if (NonNullAA) {
1158 ImmutableCallSite ICS(&NonNullAA->getAnchoredValue());
1159 if (ICS && CS.getInstruction() == ICS.getInstruction())
1160 return NonNullAA->isAssumedNonNull();
1161 return false;
1162 }
1163
1164 if (CS.paramHasAttr(ArgNo, Attribute::NonNull))
1165 return true;
1166
1167 Value *V = CS.getArgOperand(ArgNo);
1168 if (isKnownNonZero(V, getAnchorScope().getParent()->getDataLayout()))
1169 return true;
1170
1171 return false;
1172 };
1173 if (!A.checkForAllCallSites(F, CallSiteCheck, true)) {
1174 indicatePessimisticFixpoint();
1175 return ChangeStatus::CHANGED;
1176 }
1177 return ChangeStatus::UNCHANGED;
1178 }
1179
1180 ChangeStatus AANonNullCallSiteArgument::updateImpl(Attributor &A) {
1181 // NOTE: Never look at the argument of the callee in this method.
1182 // If we do this, "nonnull" is always deduced because of the assumption.
1183
1184 Value &V = *getAssociatedValue();
1185
1186 auto *NonNullAA = A.getAAFor(*this, V);
1187
1188 if (!NonNullAA || !NonNullAA->isAssumedNonNull()) {
1189 indicatePessimisticFixpoint();
1190 return ChangeStatus::CHANGED;
1191 }
1192
1193 return ChangeStatus::UNCHANGED;
1194 }
1195
9721196 /// ----------------------------------------------------------------------------
9731197 /// Attributor
9741198 /// ----------------------------------------------------------------------------
1199
1200 bool Attributor::checkForAllCallSites(Function &F,
1201 std::function &Pred,
1202 bool RequireAllCallSites) {
1203 // We can try to determine information from
1204 // the call sites. However, this is only possible all call sites are known,
1205 // hence the function has internal linkage.
1206 if (RequireAllCallSites && !F.hasInternalLinkage()) {
1207 LLVM_DEBUG(
1208 dbgs()
1209 << "Attributor: Function " << F.getName()
1210 << " has no internal linkage, hence not all call sites are known\n");
1211 return false;
1212 }
1213
1214 for (const Use &U : F.uses()) {
1215
1216 CallSite CS(U.getUser());
1217 dbgs() << *CS.getInstruction() << "\n";
1218 if (!CS || !CS.isCallee(&U) || !CS.getCaller()->hasExactDefinition()) {
1219 if (!RequireAllCallSites)
1220 continue;
1221
1222 LLVM_DEBUG(dbgs() << "Attributor: User " << *U.getUser()
1223 << " is an invalid use of " << F.getName() << "\n");
1224 return false;
1225 }
1226
1227 if (Pred(CS))
1228 continue;
1229
1230 LLVM_DEBUG(dbgs() << "Attributor: Call site callback failed for "
1231 << *CS.getInstruction() << "\n");
1232 return false;
1233 }
1234
1235 return true;
1236 }
9751237
9761238 ChangeStatus Attributor::run() {
9771239 // Initialize all abstract attributes.
11271389 // though it is an argument attribute.
11281390 if (!Whitelist || Whitelist->count(AAReturnedValues::ID))
11291391 registerAA(*new AAReturnedValuesImpl(F, InfoCache));
1392
1393 // Every function with pointer return type might be marked nonnull.
1394 if (ReturnType->isPointerTy() &&
1395 (!Whitelist || Whitelist->count(AANonNullReturned::ID)))
1396 registerAA(*new AANonNullReturned(F, InfoCache));
1397 }
1398
1399 // Every argument with pointer type might be marked nonnull.
1400 for (Argument &Arg : F.args()) {
1401 if (Arg.getType()->isPointerTy())
1402 registerAA(*new AANonNullArgument(Arg, InfoCache));
11301403 }
11311404
11321405 // Walk all instructions to find more attribute opportunities and also
11621435 InstOpcodeMap[I.getOpcode()].push_back(&I);
11631436 if (I.mayReadOrWriteMemory())
11641437 ReadOrWriteInsts.push_back(&I);
1438
1439 CallSite CS(&I);
1440 if (CS && CS.getCalledFunction()) {
1441 for (int i = 0, e = CS.getCalledFunction()->arg_size(); i < e; i++) {
1442 if (!CS.getArgument(i)->getType()->isPointerTy())
1443 continue;
1444
1445 // Call site argument attribute "non-null".
1446 registerAA(*new AANonNullCallSiteArgument(CS, i, InfoCache), i);
1447 }
1448 }
11651449 }
11661450 }
11671451
None ; RUN: opt -S -functionattrs -enable-nonnull-arg-prop %s | FileCheck %s
1 ; RUN: opt -S -passes=function-attrs -enable-nonnull-arg-prop %s | FileCheck %s
0 ; RUN: opt -S -functionattrs -enable-nonnull-arg-prop %s | FileCheck %s --check-prefixes=BOTH,FNATTR
1 ; RUN: opt -S -passes=function-attrs -enable-nonnull-arg-prop %s | FileCheck %s --check-prefixes=BOTH,FNATTR
2 ; RUN: opt -attributor --attributor-disable=false -S < %s | FileCheck %s --check-prefixes=BOTH,ATTRIBUTOR
3
4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
25
36 declare nonnull i8* @ret_nonnull()
47
58 ; Return a pointer trivially nonnull (call return attribute)
69 define i8* @test1() {
7 ; CHECK: define nonnull i8* @test1
10 ; BOTH: define nonnull i8* @test1
811 %ret = call i8* @ret_nonnull()
912 ret i8* %ret
1013 }
1114
1215 ; Return a pointer trivially nonnull (argument attribute)
1316 define i8* @test2(i8* nonnull %p) {
14 ; CHECK: define nonnull i8* @test2
17 ; BOTH: define nonnull i8* @test2
1518 ret i8* %p
1619 }
1720
1821 ; Given an SCC where one of the functions can not be marked nonnull,
1922 ; can we still mark the other one which is trivially nonnull
2023 define i8* @scc_binder() {
21 ; CHECK: define i8* @scc_binder
24 ; BOTH: define i8* @scc_binder
2225 call i8* @test3()
2326 ret i8* null
2427 }
2528
2629 define i8* @test3() {
27 ; CHECK: define nonnull i8* @test3
30 ; BOTH: define nonnull i8* @test3
2831 call i8* @scc_binder()
2932 %ret = call i8* @ret_nonnull()
3033 ret i8* %ret
3437 ; nonnull if neither can ever return null. (In this case, they
3538 ; just never return period.)
3639 define i8* @test4_helper() {
37 ; CHECK: define noalias nonnull i8* @test4_helper
40 ; FNATTR: define noalias nonnull i8* @test4_helper
41 ; ATTRIBUTOR: define nonnull i8* @test4_helper
3842 %ret = call i8* @test4()
3943 ret i8* %ret
4044 }
4145
4246 define i8* @test4() {
43 ; CHECK: define noalias nonnull i8* @test4
47 ; FNATTR: define noalias nonnull i8* @test4
48 ; ATTRIBUTOR: define nonnull i8* @test4
4449 %ret = call i8* @test4_helper()
4550 ret i8* %ret
4651 }
4853 ; Given a mutual recursive set of functions which *can* return null
4954 ; make sure we haven't marked them as nonnull.
5055 define i8* @test5_helper() {
51 ; CHECK: define noalias i8* @test5_helper
56 ; FNATTR: define noalias i8* @test5_helper
57 ; ATTRIBUTOR: define i8* @test5_helper
5258 %ret = call i8* @test5()
5359 ret i8* null
5460 }
5561
5662 define i8* @test5() {
57 ; CHECK: define noalias i8* @test5
63 ; FNATTR: define noalias i8* @test5
64 ; ATTRIBUTOR: define i8* @test5
5865 %ret = call i8* @test5_helper()
5966 ret i8* %ret
6067 }
6269 ; Local analysis, but going through a self recursive phi
6370 define i8* @test6() {
6471 entry:
65 ; CHECK: define nonnull i8* @test6
72 ; BOTH: define nonnull i8* @test6
6673 %ret = call i8* @ret_nonnull()
6774 br label %loop
6875 loop:
7279 ret i8* %phi
7380 }
7481
82 ; BOTH: define i8* @test7
83 define i8* @test7(i8* %a) {
84 %b = getelementptr inbounds i8, i8* %a, i64 0
85 ret i8* %b
86 }
87
88 ; BOTH: define nonnull i8* @test8
89 define i8* @test8(i8* %a) {
90 %b = getelementptr inbounds i8, i8* %a, i64 1
91 ret i8* %b
92 }
93
94 ; BOTH: define i8* @test9
95 define i8* @test9(i8* %a, i64 %n) {
96 %b = getelementptr inbounds i8, i8* %a, i64 %n
97 ret i8* %b
98 }
99
100 declare void @llvm.assume(i1)
101 ; FNATTR: define i8* @test10
102 ; FIXME: missing nonnull
103 ; ATTRIBUTOR: define i8* @test10
104 define i8* @test10(i8* %a, i64 %n) {
105 %cmp = icmp ne i64 %n, 0
106 call void @llvm.assume(i1 %cmp)
107 %b = getelementptr inbounds i8, i8* %a, i64 %n
108 ret i8* %b
109 }
110
111 ; TEST 11
112 ; char* test11(char *p) {
113 ; return p? p: nonnull();
114 ; }
115 ; FNATTR: define i8* @test11
116 ; FIXME: missing nonnull
117 ; ATTRIBUTOR: define i8* @test11
118 define i8* @test11(i8*) local_unnamed_addr {
119 %2 = icmp eq i8* %0, null
120 br i1 %2, label %3, label %5
121
122 ;
123 %4 = tail call i8* @ret_nonnull()
124 br label %5
125
126 ;
127 %6 = phi i8* [ %4, %3 ], [ %0, %1 ]
128 ret i8* %6
129 }
130
131 ; TEST 12
132 ; Simple CallSite Test
133 declare void @test12_helper(i8*)
134 define void @test12(i8* nonnull %a) {
135 ; ATTRIBUTOR: define void @test12(i8* nonnull %a)
136 ; ATTRIBUTOR-NEXT: tail call void @test12_helper(i8* nonnull %a)
137 tail call void @test12_helper(i8* %a)
138 ret void
139 }
140
141 ; TEST 13
142 ; Simple Argument Tests
143 declare i8* @unknown()
144 define void @test13_helper() {
145 %nonnullptr = tail call i8* @ret_nonnull()
146 %maybenullptr = tail call i8* @unknown()
147 tail call void @test13(i8* %nonnullptr, i8* %nonnullptr, i8* %maybenullptr)
148 tail call void @test13(i8* %nonnullptr, i8* %maybenullptr, i8* %nonnullptr)
149 ret void
150 }
151 define internal void @test13(i8* %a, i8* %b, i8* %c) {
152 ; ATTRIBUTOR: define internal void @test13(i8* nonnull %a, i8* %b, i8* %c)
153 ret void
154 }
155
156 declare nonnull i8* @nonnull()
157
158 ; TEST 14
159 ; Complex propagation
160 ; Argument of f1, f2, f3 can be marked with nonnull.
161
162 ; * Argument
163 ; 1. In f1:bb6, %arg can be marked with nonnull because of the comparison in bb1
164 ; 2. Because f2 is internal function, f2(i32* %arg) -> @f2(i32* nonnull %arg)
165 ; 3. In f1:bb4 %tmp5 is nonnull and f3 is internal function.
166 ; Then, f3(i32* %arg) -> @f3(i32* nonnull %arg)
167 ; 4. We get nonnull in whole f1 call sites so f1(i32* %arg) -> @f1(i32* nonnull %arg)
168
169
170 define internal i32* @f1(i32* %arg) {
171 ; FIXME: missing nonnull It should be nonnull @f1(i32* nonnull %arg)
172 ; ATTRIBUTOR: define internal nonnull i32* @f1(i32* %arg)
173
174 bb:
175 %tmp = icmp eq i32* %arg, null
176 br i1 %tmp, label %bb9, label %bb1
177
178 bb1: ; preds = %bb
179 %tmp2 = load i32, i32* %arg, align 4
180 %tmp3 = icmp eq i32 %tmp2, 0
181 br i1 %tmp3, label %bb6, label %bb4
182
183 bb4: ; preds = %bb1
184 %tmp5 = getelementptr inbounds i32, i32* %arg, i64 1
185 ; ATTRIBUTOR: %tmp5b = tail call i32* @f3(i32* nonnull %tmp5)
186 %tmp5b = tail call i32* @f3(i32* %tmp5)
187 br label %bb9
188
189 bb6: ; preds = %bb1
190 ; FIXME: missing nonnull. It should be @f2(i32* nonnull %arg)
191 ; ATTRIBUTOR: %tmp7 = tail call i32* @f2(i32* %arg)
192 %tmp7 = tail call i32* @f2(i32* %arg)
193 ret i32* %tmp7
194
195 bb9: ; preds = %bb4, %bb
196 %tmp10 = phi i32* [ %tmp5, %bb4 ], [ inttoptr (i64 4 to i32*), %bb ]
197 ret i32* %tmp10
198 }
199
200 define internal i32* @f2(i32* %arg) {
201 ; FIXME: missing nonnull. It should be nonnull @f2(i32* nonnull %arg)
202 ; ATTRIBUTOR: define internal nonnull i32* @f2(i32* %arg)
203 bb:
204
205 ; FIXME: missing nonnull. It should be @f1(i32* nonnull %arg)
206 ; ATTRIBUTOR: %tmp = tail call i32* @f1(i32* %arg)
207 %tmp = tail call i32* @f1(i32* %arg)
208 ret i32* %tmp
209 }
210
211 define dso_local noalias i32* @f3(i32* %arg) {
212 ; FIXME: missing nonnull. It should be nonnull @f3(i32* nonnull %arg)
213 ; ATTRIBUTOR: define dso_local noalias i32* @f3(i32* %arg)
214 bb:
215 ; FIXME: missing nonnull. It should be @f1(i32* nonnull %arg)
216 ; ATTRIBUTOR: %tmp = call i32* @f1(i32* %arg)
217 %tmp = call i32* @f1(i32* %arg)
218 ret i32* null
219 }
75220 ; Test propagation of nonnull callsite args back to caller.
76221
77222 declare void @use1(i8* %x)
87232 ; Can't extend non-null to parent for any argument because the 2nd call is not guaranteed to execute.
88233
89234 define void @parent1(i8* %a, i8* %b, i8* %c) {
90 ; CHECK-LABEL: @parent1(i8* %a, i8* %b, i8* %c)
91 ; CHECK-NEXT: call void @use3(i8* %c, i8* %a, i8* %b)
92 ; CHECK-NEXT: call void @use3nonnull(i8* %b, i8* %c, i8* %a)
93 ; CHECK-NEXT: ret void
94 ;
235 ; BOTH-LABEL: @parent1(i8* %a, i8* %b, i8* %c)
236 ; BOTH-NEXT: call void @use3(i8* %c, i8* %a, i8* %b)
237 ; FNATTR-NEXT: call void @use3nonnull(i8* %b, i8* %c, i8* %a)
238 ; ATTRIBUTOR-NEXT: call void @use3nonnull(i8* nonnull %b, i8* nonnull %c, i8* nonnull %a)
239 ; BOTH-NEXT: ret void
95240 call void @use3(i8* %c, i8* %a, i8* %b)
96241 call void @use3nonnull(i8* %b, i8* %c, i8* %a)
97242 ret void
100245 ; Extend non-null to parent for all arguments.
101246
102247 define void @parent2(i8* %a, i8* %b, i8* %c) {
103 ; CHECK-LABEL: @parent2(i8* nonnull %a, i8* nonnull %b, i8* nonnull %c)
104 ; CHECK-NEXT: call void @use3nonnull(i8* %b, i8* %c, i8* %a)
105 ; CHECK-NEXT: call void @use3(i8* %c, i8* %a, i8* %b)
106 ; CHECK-NEXT: ret void
107 ;
248 ; FNATTR-LABEL: @parent2(i8* nonnull %a, i8* nonnull %b, i8* nonnull %c)
249 ; FNATTR-NEXT: call void @use3nonnull(i8* %b, i8* %c, i8* %a)
250 ; FNATTR-NEXT: call void @use3(i8* %c, i8* %a, i8* %b)
251
252 ; FIXME: missing "nonnull", it should be
253 ; @parent2(i8* nonnull %a, i8* nonnull %b, i8* nonnull %c)
254 ; call void @use3nonnull(i8* nonnull %b, i8* nonnull %c, i8* nonnull %a)
255 ; call void @use3(i8* nonnull %c, i8* nonnull %a, i8* nonnull %b)
256
257 ; ATTRIBUTOR-LABEL: @parent2(i8* %a, i8* %b, i8* %c)
258 ; ATTRIBUTOR-NEXT: call void @use3nonnull(i8* nonnull %b, i8* nonnull %c, i8* nonnull %a)
259 ; ATTRIBUTOR-NEXT: call void @use3(i8* %c, i8* %a, i8* %b)
260
261 ; BOTH-NEXT: ret void
108262 call void @use3nonnull(i8* %b, i8* %c, i8* %a)
109263 call void @use3(i8* %c, i8* %a, i8* %b)
110264 ret void
113267 ; Extend non-null to parent for 1st argument.
114268
115269 define void @parent3(i8* %a, i8* %b, i8* %c) {
116 ; CHECK-LABEL: @parent3(i8* nonnull %a, i8* %b, i8* %c)
117 ; CHECK-NEXT: call void @use1nonnull(i8* %a)
118 ; CHECK-NEXT: call void @use3(i8* %c, i8* %b, i8* %a)
119 ; CHECK-NEXT: ret void
120 ;
270 ; FNATTR-LABEL: @parent3(i8* nonnull %a, i8* %b, i8* %c)
271 ; FNATTR-NEXT: call void @use1nonnull(i8* %a)
272 ; FNATTR-NEXT: call void @use3(i8* %c, i8* %b, i8* %a)
273
274 ; FIXME: missing "nonnull", it should be,
275 ; @parent3(i8* nonnull %a, i8* %b, i8* %c)
276 ; call void @use1nonnull(i8* nonnull %a)
277 ; call void @use3(i8* %c, i8* %b, i8* nonnull %a)
278 ; ATTRIBUTOR-LABEL: @parent3(i8* %a, i8* %b, i8* %c)
279 ; ATTRIBUTOR-NEXT: call void @use1nonnull(i8* nonnull %a)
280 ; ATTRIBUTOR-NEXT: call void @use3(i8* %c, i8* %b, i8* %a)
281
282 ; BOTH-NEXT: ret void
283
121284 call void @use1nonnull(i8* %a)
122285 call void @use3(i8* %c, i8* %b, i8* %a)
123286 ret void
130293 ; CHECK-NEXT: call void @use2nonnull(i8* %c, i8* %b)
131294 ; CHECK-NEXT: call void @use2(i8* %a, i8* %c)
132295 ; CHECK-NEXT: call void @use1(i8* %b)
133 ; CHECK-NEXT: ret void
134 ;
296
297 ; FIXME : missing "nonnull", it should be
298 ; @parent4(i8* %a, i8* nonnull %b, i8* nonnull %c)
299 ; call void @use2nonnull(i8* nonnull %c, i8* nonull %b)
300 ; call void @use2(i8* %a, i8* nonnull %c)
301 ; call void @use1(i8* nonnull %b)
302
303 ; ATTRIBUTOR-LABEL: @parent4(i8* %a, i8* %b, i8* %c)
304 ; ATTRIBUTOR-NEXT: call void @use2nonnull(i8* nonnull %c, i8* nonnull %b)
305 ; ATTRIBUTOR-NEXT: call void @use2(i8* %a, i8* %c)
306 ; ATTRIBUTOR-NEXT: call void @use1(i8* %b)
307
308 ; BOTH: ret void
309
135310 call void @use2nonnull(i8* %c, i8* %b)
136311 call void @use2(i8* %a, i8* %c)
137312 call void @use1(i8* %b)
143318 ; because it would incorrectly propagate the wrong information to its callers.
144319
145320 define void @parent5(i8* %a, i1 %a_is_notnull) {
146 ; CHECK-LABEL: @parent5(i8* %a, i1 %a_is_notnull)
147 ; CHECK-NEXT: br i1 %a_is_notnull, label %t, label %f
148 ; CHECK: t:
149 ; CHECK-NEXT: call void @use1nonnull(i8* %a)
150 ; CHECK-NEXT: ret void
151 ; CHECK: f:
152 ; CHECK-NEXT: ret void
153 ;
321 ; BOTH: @parent5(i8* %a, i1 %a_is_notnull)
322 ; BOTH-NEXT: br i1 %a_is_notnull, label %t, label %f
323 ; BOTH: t:
324 ; FNATTR-NEXT: call void @use1nonnull(i8* %a)
325 ; ATTRIBUTOR-NEXT: call void @use1nonnull(i8* nonnull %a)
326 ; BOTH-NEXT: ret void
327 ; BOTH: f:
328 ; BOTH-NEXT: ret void
329
154330 br i1 %a_is_notnull, label %t, label %f
155331 t:
156332 call void @use1nonnull(i8* %a)
163339 ; The volatile load might trap, so there's no guarantee that we'll ever get to the call.
164340
165341 define i8 @parent6(i8* %a, i8* %b) {
166 ; CHECK-LABEL: @parent6(i8* %a, i8* %b)
167 ; CHECK-NEXT: [[C:%.*]] = load volatile i8, i8* %b
168 ; CHECK-NEXT: call void @use1nonnull(i8* %a)
169 ; CHECK-NEXT: ret i8 [[C]]
170 ;
342 ; BOTH-LABEL: @parent6(i8* %a, i8* %b)
343 ; BOTH-NEXT: [[C:%.*]] = load volatile i8, i8* %b
344 ; FNATTR-NEXT: call void @use1nonnull(i8* %a)
345 ; ATTRIBUTOR-NEXT: call void @use1nonnull(i8* nonnull %a)
346 ; BOTH-NEXT: ret i8 [[C]]
347
171348 %c = load volatile i8, i8* %b
172349 call void @use1nonnull(i8* %a)
173350 ret i8 %c
176353 ; The nonnull callsite is guaranteed to execute, so the argument must be nonnull throughout the parent.
177354
178355 define i8 @parent7(i8* %a) {
179 ; CHECK-LABEL: @parent7(i8* nonnull %a)
180 ; CHECK-NEXT: [[RET:%.*]] = call i8 @use1safecall(i8* %a)
181 ; CHECK-NEXT: call void @use1nonnull(i8* %a)
182 ; CHECK-NEXT: ret i8 [[RET]]
183 ;
356 ; FNATTR-LABEL: @parent7(i8* nonnull %a)
357 ; FNATTR-NEXT: [[RET:%.*]] = call i8 @use1safecall(i8* %a)
358 ; FNATTR-NEXT: call void @use1nonnull(i8* %a)
359
360 ; FIXME : missing "nonnull", it should be
361 ; @parent7(i8* nonnull %a)
362 ; [[RET:%.*]] = call i8 @use1safecall(i8* nonnull %a)
363 ; call void @use1nonnull(i8* nonnull %a)
364 ; ret i8 [[RET]]
365
366 ; ATTRIBUTOR-LABEL: @parent7(i8* %a)
367 ; ATTRIBUTOR-NEXT: [[RET:%.*]] = call i8 @use1safecall(i8* %a)
368 ; ATTRIBUTOR-NEXT: call void @use1nonnull(i8* nonnull %a)
369
370 ; BOTH-NEXT: ret i8 [[RET]]
371
184372 %ret = call i8 @use1safecall(i8* %a)
185373 call void @use1nonnull(i8* %a)
186374 ret i8 %ret
191379 declare i32 @esfp(...)
192380
193381 define i1 @parent8(i8* %a, i8* %bogus1, i8* %b) personality i8* bitcast (i32 (...)* @esfp to i8*){
194 ; CHECK-LABEL: @parent8(i8* nonnull %a, i8* nocapture readnone %bogus1, i8* nonnull %b)
195 ; CHECK-NEXT: entry:
196 ; CHECK-NEXT: invoke void @use2nonnull(i8* %a, i8* %b)
197 ; CHECK-NEXT: to label %cont unwind label %exc
198 ; CHECK: cont:
199 ; CHECK-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* %b, null
200 ; CHECK-NEXT: ret i1 [[NULL_CHECK]]
201 ; CHECK: exc:
202 ; CHECK-NEXT: [[LP:%.*]] = landingpad { i8*, i32 }
203 ; CHECK-NEXT: filter [0 x i8*] zeroinitializer
204 ; CHECK-NEXT: unreachable
205 ;
382 ; FNATTR-LABEL: @parent8(i8* nonnull %a, i8* nocapture readnone %bogus1, i8* nonnull %b)
383 ; FIXME : missing "nonnull", it should be @parent8(i8* nonnull %a, i8* %bogus1, i8* nonnull %b)
384 ; ATTRIBUTOR-LABEL: @parent8(i8* %a, i8* %bogus1, i8* %b)
385 ; BOTH-NEXT: entry:
386 ; FNATTR-NEXT: invoke void @use2nonnull(i8* %a, i8* %b)
387 ; ATTRIBUTOR-NEXT: invoke void @use2nonnull(i8* nonnull %a, i8* nonnull %b)
388 ; BOTH-NEXT: to label %cont unwind label %exc
389 ; BOTH: cont:
390 ; BOTH-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* %b, null
391 ; BOTH-NEXT: ret i1 [[NULL_CHECK]]
392 ; BOTH: exc:
393 ; BOTH-NEXT: [[LP:%.*]] = landingpad { i8*, i32 }
394 ; BOTH-NEXT: filter [0 x i8*] zeroinitializer
395 ; BOTH-NEXT: unreachable
396
206397 entry:
207398 invoke void @use2nonnull(i8* %a, i8* %b)
208399 to label %cont unwind label %exc
217408 unreachable
218409 }
219410
220 ; CHECK: define nonnull i32* @gep1(
411 ; BOTH: define nonnull i32* @gep1(
221412 define i32* @gep1(i32* %p) {
222413 %q = getelementptr inbounds i32, i32* %p, i32 1
223414 ret i32* %q
225416
226417 define i32* @gep1_no_null_opt(i32* %p) #0 {
227418 ; Should't be able to derive nonnull based on gep.
228 ; CHECK: define i32* @gep1_no_null_opt(
419 ; BOTH: define i32* @gep1_no_null_opt(
229420 %q = getelementptr inbounds i32, i32* %p, i32 1
230421 ret i32* %q
231422 }
232423
233 ; CHECK: define i32 addrspace(3)* @gep2(
424 ; BOTH: define i32 addrspace(3)* @gep2(
234425 define i32 addrspace(3)* @gep2(i32 addrspace(3)* %p) {
235426 %q = getelementptr inbounds i32, i32 addrspace(3)* %p, i32 1
236427 ret i32 addrspace(3)* %q
237428 }
238429
239 ; CHECK: define internal nonnull i32* @f2()
240 define internal i32* @f2() {
430 ; BOTH: define internal nonnull i32* @g2()
431 define internal i32* @g2() {
241432 ret i32* inttoptr (i64 4 to i32*)
242433 }
243434
244 define i32* @f1() {
245 %c = call i32* @f2()
435 define i32* @g1() {
436 %c = call i32* @g2()
246437 ret i32* %c
247438 }
248439
2727 ; FNATTR: Function Attrs: norecurse nounwind optsize readnone ssp uwtable
2828 ; FNATTR-NEXT: define nonnull i32* @foo(%struct.ST* readnone %s)
2929 ; ATTRIBUTOR: Function Attrs: nofree nosync nounwind optsize readnone ssp uwtable
30 ; ATTRIBUTOR-NEXT: define i32* @foo(%struct.ST* %s)
30 ; ATTRIBUTOR-NEXT: define nonnull i32* @foo(%struct.ST* %s)
3131 define i32* @foo(%struct.ST* %s) nounwind uwtable readnone optsize ssp {
3232 entry:
3333 %arrayidx = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 1, i32 2, i32 1, i64 5, i64 13