aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/CloneFunction.cpp
diff options
context:
space:
mode:
authorAntonio Frighetto <me@antoniofrighetto.com>2024-04-29 17:53:29 +0200
committerAntonio Frighetto <me@antoniofrighetto.com>2024-05-02 16:29:09 +0200
commit1bb929833b18db4a26a4d145d7270597cb5d48ce (patch)
tree5358b1e4e25b671e5ff317620efa7f7a5ef8de96 /llvm/lib/Transforms/Utils/CloneFunction.cpp
parent42c7cb69694d274e46bb98d156b9be31b308b62c (diff)
downloadllvm-1bb929833b18db4a26a4d145d7270597cb5d48ce.zip
llvm-1bb929833b18db4a26a4d145d7270597cb5d48ce.tar.gz
llvm-1bb929833b18db4a26a4d145d7270597cb5d48ce.tar.bz2
[Inline][Cloning] Drop incompatible attributes from `NewFunc`
Performing `instSimplify` while cloning is unsafe due to incomplete remapping (as reported in #87534). Ideally, `instSimplify` ought to reason on the updated newly-cloned function, after returns have been rewritten and callee entry basic block / call-site have been fixed up. This is in contrast to `CloneAndPruneIntoFromInst` behaviour, which is inherently expected to clone basic blocks, with pruning on top of – if any –, and not actually fixing up returns / CFG, which should be up to the Inliner. We may solve this by letting `instSimplify` work on the newly-cloned function, while maintaining old function attributes, so as to avoid inconsistencies between the yet-to-be-solved return type, and new function ret type attributes.
Diffstat (limited to 'llvm/lib/Transforms/Utils/CloneFunction.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/CloneFunction.cpp12
1 files changed, 12 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp
index 38cab25..6f6dc63 100644
--- a/llvm/lib/Transforms/Utils/CloneFunction.cpp
+++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp
@@ -18,6 +18,7 @@
#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/AttributeMask.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
@@ -819,6 +820,14 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
}
}
+ // Drop all incompatible return attributes that cannot be applied to NewFunc
+ // during cloning, so as to allow instruction simplification to reason on the
+ // old state of the function. The original attributes are restored later.
+ AttributeMask IncompatibleAttrs =
+ AttributeFuncs::typeIncompatible(OldFunc->getReturnType());
+ AttributeList Attrs = NewFunc->getAttributes();
+ NewFunc->removeRetAttrs(IncompatibleAttrs);
+
// As phi-nodes have been now remapped, allow incremental simplification of
// newly-cloned instructions.
const DataLayout &DL = NewFunc->getParent()->getDataLayout();
@@ -849,6 +858,9 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
}
}
+ // Restore attributes.
+ NewFunc->setAttributes(Attrs);
+
// Remap debug intrinsic operands now that all values have been mapped.
// Doing this now (late) preserves use-before-defs in debug intrinsics. If
// we didn't do this, ValueAsMetadata(use-before-def) operands would be