aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
diff options
context:
space:
mode:
authorShivam Gupta <shivam98.tkg@gmail.com>2025-07-01 18:34:52 +0530
committerGitHub <noreply@github.com>2025-07-01 18:34:52 +0530
commite44fbea0a17f468d45de5eaef158642f067f678c (patch)
tree7997491fe47493bb7645be7b68df409d35869b13 /llvm/lib/Transforms/IPO/FunctionAttrs.cpp
parent3702d64801c872bf41a29b0aabda868ab3e26f12 (diff)
downloadllvm-e44fbea0a17f468d45de5eaef158642f067f678c.zip
llvm-e44fbea0a17f468d45de5eaef158642f067f678c.tar.gz
llvm-e44fbea0a17f468d45de5eaef158642f067f678c.tar.bz2
[FunctionAttrs] Handle ConstantRange overflow in memset initializes inference (#145739)
Avoid constructing invalid ConstantRange when Offset + Length in memset overflows signed 64-bit integer space. This prevents assertion failures when inferring the initializes attribute. Fixes #140345
Diffstat (limited to 'llvm/lib/Transforms/IPO/FunctionAttrs.cpp')
-rw-r--r--llvm/lib/Transforms/IPO/FunctionAttrs.cpp20
1 files changed, 15 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index f918d7e..f43202e 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -675,14 +675,24 @@ ArgumentAccessInfo getArgumentAccessInfo(const Instruction *I,
[](Value *Length,
std::optional<int64_t> Offset) -> std::optional<ConstantRange> {
auto *ConstantLength = dyn_cast<ConstantInt>(Length);
- if (ConstantLength && Offset &&
- ConstantLength->getValue().isStrictlyPositive()) {
- return ConstantRange(
- APInt(64, *Offset, true),
- APInt(64, *Offset + ConstantLength->getSExtValue(), true));
+ if (ConstantLength && Offset) {
+ int64_t Len = ConstantLength->getSExtValue();
+
+ // Reject zero or negative lengths
+ if (Len <= 0)
+ return std::nullopt;
+
+ APInt Low(64, *Offset, true);
+ bool Overflow;
+ APInt High = Low.sadd_ov(APInt(64, Len, true), Overflow);
+ if (Overflow)
+ return std::nullopt;
+
+ return ConstantRange(Low, High);
}
return std::nullopt;
};
+
if (auto *SI = dyn_cast<StoreInst>(I)) {
if (SI->isSimple() && &SI->getOperandUse(1) == ArgUse.U) {
// Get the fixed type size of "SI". Since the access range of a write