Skip to content

Commit 087a8ee

Browse files
committed
[Attributes] Clean up handling of UB implying attributes (NFC)
Rather than adding methods for dropping these attributes in various places, add a function that returns an AttrBuilder with these attributes, which can then be used with existing methods for dropping attributes. This is with an eye on D104641, which also needs to drop them from returns, not just parameters. Also be more explicit about the semantics of the method in the documentation. Refer to UB rather than Undef, which is what this is actually about.
1 parent 99f869c commit 087a8ee

File tree

5 files changed

+18
-33
lines changed

5 files changed

+18
-33
lines changed

llvm/include/llvm/IR/Attributes.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -546,12 +546,6 @@ class AttributeList {
546546
return removeAttributes(C, ArgNo + FirstArgIndex, AttrsToRemove);
547547
}
548548

549-
/// Remove noundef attribute and other attributes that imply undefined
550-
/// behavior if a `undef` or `poison` value is passed from this attribute
551-
/// list. Returns a new list because attribute lists are immutable.
552-
LLVM_NODISCARD AttributeList
553-
removeParamUndefImplyingAttributes(LLVMContext &C, unsigned ArgNo) const;
554-
555549
/// Remove all attributes at the specified arg index from this
556550
/// attribute list. Returns a new list because attribute lists are immutable.
557551
LLVM_NODISCARD AttributeList removeParamAttributes(LLVMContext &C,
@@ -1038,6 +1032,13 @@ namespace AttributeFuncs {
10381032
/// Which attributes cannot be applied to a type.
10391033
AttrBuilder typeIncompatible(Type *Ty);
10401034

1035+
/// Get param/return attributes which imply immediate undefined behavior if an
1036+
/// invalid value is passed. For example, this includes noundef (where undef
1037+
/// implies UB), but not nonnull (where null implies poison). It also does not
1038+
/// include attributes like nocapture, which constrain the function
1039+
/// implementation rather than the passed value.
1040+
AttrBuilder getUBImplyingAttributes();
1041+
10411042
/// \returns Return true if the two functions have compatible target-independent
10421043
/// attributes for inlining purposes.
10431044
bool areInlineCompatible(const Function &Caller, const Function &Callee);

llvm/include/llvm/IR/InstrTypes.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,15 +1558,6 @@ class CallBase : public Instruction {
15581558
setAttributes(PAL);
15591559
}
15601560

1561-
/// Removes noundef and other attributes that imply undefined behavior if a
1562-
/// `undef` or `poison` value is passed from the given argument.
1563-
void removeParamUndefImplyingAttrs(unsigned ArgNo) {
1564-
assert(ArgNo < getNumArgOperands() && "Out of bounds");
1565-
AttributeList PAL = getAttributes();
1566-
PAL = PAL.removeParamUndefImplyingAttributes(getContext(), ArgNo);
1567-
setAttributes(PAL);
1568-
}
1569-
15701561
/// adds the dereferenceable attribute to the list of attributes.
15711562
void addDereferenceableAttr(unsigned i, uint64_t Bytes) {
15721563
AttributeList PAL = getAttributes();

llvm/lib/IR/Attributes.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,16 +1335,6 @@ AttributeList AttributeList::removeAttributes(LLVMContext &C,
13351335
return getImpl(C, AttrSets);
13361336
}
13371337

1338-
AttributeList
1339-
AttributeList::removeParamUndefImplyingAttributes(LLVMContext &C,
1340-
unsigned ArgNo) const {
1341-
AttrBuilder B;
1342-
B.addAttribute(Attribute::NoUndef);
1343-
B.addDereferenceableAttr(1);
1344-
B.addDereferenceableOrNullAttr(1);
1345-
return removeParamAttributes(C, ArgNo, B);
1346-
}
1347-
13481338
AttributeList AttributeList::addDereferenceableAttr(LLVMContext &C,
13491339
unsigned Index,
13501340
uint64_t Bytes) const {
@@ -1926,6 +1916,14 @@ AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
19261916
return Incompatible;
19271917
}
19281918

1919+
AttrBuilder AttributeFuncs::getUBImplyingAttributes() {
1920+
AttrBuilder B;
1921+
B.addAttribute(Attribute::NoUndef);
1922+
B.addDereferenceableAttr(1);
1923+
B.addDereferenceableOrNullAttr(1);
1924+
return B;
1925+
}
1926+
19291927
template<typename AttrClass>
19301928
static bool isEqual(const Function &Caller, const Function &Callee) {
19311929
return Caller.getFnAttribute(AttrClass::getKind()) ==

llvm/lib/IR/Function.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -601,12 +601,6 @@ void Function::removeParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs) {
601601
setAttributes(PAL);
602602
}
603603

604-
void Function::removeParamUndefImplyingAttrs(unsigned ArgNo) {
605-
AttributeList PAL = getAttributes();
606-
PAL = PAL.removeParamUndefImplyingAttributes(getContext(), ArgNo);
607-
setAttributes(PAL);
608-
}
609-
610604
void Function::addDereferenceableAttr(unsigned i, uint64_t Bytes) {
611605
AttributeList PAL = getAttributes();
612606
PAL = PAL.addDereferenceableAttr(getContext(), i, Bytes);

llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ bool DeadArgumentEliminationPass::RemoveDeadArgumentsFromCallers(Function &Fn) {
287287
SmallVector<unsigned, 8> UnusedArgs;
288288
bool Changed = false;
289289

290+
AttrBuilder UBImplyingAttributes = AttributeFuncs::getUBImplyingAttributes();
290291
for (Argument &Arg : Fn.args()) {
291292
if (!Arg.hasSwiftErrorAttr() && Arg.use_empty() &&
292293
!Arg.hasPassPointeeByValueCopyAttr()) {
@@ -295,7 +296,7 @@ bool DeadArgumentEliminationPass::RemoveDeadArgumentsFromCallers(Function &Fn) {
295296
Changed = true;
296297
}
297298
UnusedArgs.push_back(Arg.getArgNo());
298-
Fn.removeParamUndefImplyingAttrs(Arg.getArgNo());
299+
Fn.removeParamAttrs(Arg.getArgNo(), UBImplyingAttributes);
299300
}
300301
}
301302

@@ -313,7 +314,7 @@ bool DeadArgumentEliminationPass::RemoveDeadArgumentsFromCallers(Function &Fn) {
313314

314315
Value *Arg = CB->getArgOperand(ArgNo);
315316
CB->setArgOperand(ArgNo, UndefValue::get(Arg->getType()));
316-
CB->removeParamUndefImplyingAttrs(ArgNo);
317+
CB->removeParamAttrs(ArgNo, UBImplyingAttributes);
317318

318319
++NumArgumentsReplacedWithUndef;
319320
Changed = true;

0 commit comments

Comments
 (0)