-
Notifications
You must be signed in to change notification settings - Fork 11.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Inliner] Check number of operands in AddReturnAttributes #87093
Conversation
The commit 2da4960 enabled `noundef` attributes propagation. It looks like ret void is considered to be `noundef` thus `ValidUB.hasAttributes` now returns true for this type of instructions and everything proceed further to work with operands. The issue is that such instruction doesn't have operands, which means when accessing `RI->getOperand(0)` inliner pass crashes with an assert: llvm/include/llvm/IR/Instructions.h:3420: llvm::Value* llvm::ReturnInst::getOperand(unsigned int) const: Assertion `i_nocapture < OperandTraits<ReturnInst>::operands(this) && "getOperand() out of range!"' failed. Fix that by verifying if the ReturnInst in fact has some operands to process. Fixes llvm#86163
@llvm/pr-subscribers-llvm-transforms Author: Dmitrii Dolgov (erthalion) ChangesThe commit 2da4960 enabled
Fix that by verifying if the /cc @goldsteinn as an author of the commit referenced in [3], and @chandlerc as mentioned in code_owners regarding inlining pass. Fixes #86162 Full diff: https://github.com/llvm/llvm-project/pull/87093.diff 1 Files Affected:
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 833dcbec228b88..d5cf6bd036e07c 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -1384,7 +1384,7 @@ static void AddReturnAttributes(CallBase &CB, ValueToValueMapTy &VMap) {
for (auto &BB : *CalledFunction) {
auto *RI = dyn_cast<ReturnInst>(BB.getTerminator());
- if (!RI || !isa<CallBase>(RI->getOperand(0)))
+ if (!RI || RI->getNumOperands() == 0 || !isa<CallBase>(RI->getOperand(0)))
continue;
auto *RetVal = cast<CallBase>(RI->getOperand(0));
// Check that the cloned RetVal exists and is a call, otherwise we cannot
|
could you add a test so it's clearer what the input IR causing the crash is? or at least just paste some reduced IR that crashes with it'd seem like |
yeah that's not allowed (https://godbolt.org/z/ffM1qnfrn) so I'm not sure exactly what you're seeing. perhaps the input IR is already broken (run it through the verifier with |
Interesting, let me verify the IR. |
With help from @macdice we most likely found the reason behind #86162. PostgreSQL generates the module passed to the inliner, and it turns out one part of the generator copies function attributes, eventually applying Unless you folks think that the extra check proposed in this PR makes sense as a general defense measure, I'm going to close the PR and the issue. |
The commit 2da4960 enabled
noundef
attributes propagation. It looks like ret void is considered to benoundef
, thusValidUB.hasAttributes
now returns true for this type of instructions and everything proceed further to work with operands. The issue is that such instruction doesn't have operands, which means when accessingRI->getOperand(0)
inliner pass crashes with an assert:Fix that by verifying if the
ReturnInst
in fact has some operands to process./cc @goldsteinn as an author of the commit referenced in [3], and @chandlerc as mentioned in code_owners regarding inlining pass.
Fixes #86162