diff options
author | Shivam Gupta <shivam98.tkg@gmail.com> | 2025-07-01 18:34:52 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-01 18:34:52 +0530 |
commit | e44fbea0a17f468d45de5eaef158642f067f678c (patch) | |
tree | 7997491fe47493bb7645be7b68df409d35869b13 /llvm/lib/Transforms/IPO/FunctionAttrs.cpp | |
parent | 3702d64801c872bf41a29b0aabda868ab3e26f12 (diff) | |
download | llvm-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.cpp | 20 |
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 |