[Attributor] Selectively look at the callee even when there are operand bundles

While operand bundles carry unpredictable semantics, we know some of
them and can therefore "ignore" them. In this case we allow to look at
the declaration of `llvm.assume` when asked for the attributes at a call
site. The assume operand bundles we have do not invalidate the
declaration attributes.

We cannot test this in isolation because the llvm.assume attributes are
determined by the parser. However, a follow up patch will provide test
coverage.
This commit is contained in:
Johannes Doerfert 2020-09-04 11:14:33 -05:00
parent 2600c9e2ef
commit c0ab901bdd
1 changed files with 10 additions and 3 deletions

View File

@ -325,6 +325,13 @@ const IRPosition
SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) { SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
IRPositions.emplace_back(IRP); IRPositions.emplace_back(IRP);
// Helper to determine if operand bundles on a call site are benin or
// potentially problematic. We handle only llvm.assume for now.
auto CanIgnoreOperandBundles = [](const CallBase &CB) {
return (isa<IntrinsicInst>(CB) &&
cast<IntrinsicInst>(CB).getIntrinsicID() == Intrinsic ::assume);
};
const auto *CB = dyn_cast<CallBase>(&IRP.getAnchorValue()); const auto *CB = dyn_cast<CallBase>(&IRP.getAnchorValue());
switch (IRP.getPositionKind()) { switch (IRP.getPositionKind()) {
case IRPosition::IRP_INVALID: case IRPosition::IRP_INVALID:
@ -339,7 +346,7 @@ SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
assert(CB && "Expected call site!"); assert(CB && "Expected call site!");
// TODO: We need to look at the operand bundles similar to the redirection // TODO: We need to look at the operand bundles similar to the redirection
// in CallBase. // in CallBase.
if (!CB->hasOperandBundles()) if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB))
if (const Function *Callee = CB->getCalledFunction()) if (const Function *Callee = CB->getCalledFunction())
IRPositions.emplace_back(IRPosition::function(*Callee)); IRPositions.emplace_back(IRPosition::function(*Callee));
return; return;
@ -347,7 +354,7 @@ SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
assert(CB && "Expected call site!"); assert(CB && "Expected call site!");
// TODO: We need to look at the operand bundles similar to the redirection // TODO: We need to look at the operand bundles similar to the redirection
// in CallBase. // in CallBase.
if (!CB->hasOperandBundles()) { if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {
if (const Function *Callee = CB->getCalledFunction()) { if (const Function *Callee = CB->getCalledFunction()) {
IRPositions.emplace_back(IRPosition::returned(*Callee)); IRPositions.emplace_back(IRPosition::returned(*Callee));
IRPositions.emplace_back(IRPosition::function(*Callee)); IRPositions.emplace_back(IRPosition::function(*Callee));
@ -368,7 +375,7 @@ SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
assert(CB && ArgNo >= 0 && "Expected call site!"); assert(CB && ArgNo >= 0 && "Expected call site!");
// TODO: We need to look at the operand bundles similar to the redirection // TODO: We need to look at the operand bundles similar to the redirection
// in CallBase. // in CallBase.
if (!CB->hasOperandBundles()) { if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {
const Function *Callee = CB->getCalledFunction(); const Function *Callee = CB->getCalledFunction();
if (Callee && Callee->arg_size() > unsigned(ArgNo)) if (Callee && Callee->arg_size() > unsigned(ArgNo))
IRPositions.emplace_back(IRPosition::argument(*Callee->getArg(ArgNo))); IRPositions.emplace_back(IRPosition::argument(*Callee->getArg(ArgNo)));