aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/Loads.cpp
diff options
context:
space:
mode:
authorDavid Sherwood <david.sherwood@arm.com>2024-07-22 11:31:50 +0100
committerGitHub <noreply@github.com>2024-07-22 11:31:50 +0100
commit102d16809b2cf79b5e1ff4728ef6164cd92f90d5 (patch)
tree454e4ec2b4b852c8e5f049848c79a244ecc390a4 /llvm/lib/Analysis/Loads.cpp
parentf406d83d9553c0ade8f9b2dea961e5a8caa220f3 (diff)
downloadllvm-102d16809b2cf79b5e1ff4728ef6164cd92f90d5.zip
llvm-102d16809b2cf79b5e1ff4728ef6164cd92f90d5.tar.gz
llvm-102d16809b2cf79b5e1ff4728ef6164cd92f90d5.tar.bz2
[Analysis] Bail out for negative offsets in isDereferenceableAndAlignedInLoop (#99490)
This patch now bails out explicitly for negative offsets so that it's more consistent with the unsigned remainder and add calculations, and it fixes a genuine bug as shown with the new test.
Diffstat (limited to 'llvm/lib/Analysis/Loads.cpp')
-rw-r--r--llvm/lib/Analysis/Loads.cpp7
1 files changed, 7 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp
index 255a7ae..4f0b92f5 100644
--- a/llvm/lib/Analysis/Loads.cpp
+++ b/llvm/lib/Analysis/Loads.cpp
@@ -313,6 +313,13 @@ bool llvm::isDereferenceableAndAlignedInLoop(LoadInst *LI, Loop *L,
const auto *Offset = dyn_cast<SCEVConstant>(StartS->getOperand(0));
const auto *NewBase = dyn_cast<SCEVUnknown>(StartS->getOperand(1));
if (StartS->getNumOperands() == 2 && Offset && NewBase) {
+ // The following code below assumes the offset is unsigned, but GEP
+ // offsets are treated as signed so we can end up with a signed value
+ // here too. For example, suppose the initial PHI value is (i8 255),
+ // the offset will be treated as (i8 -1) and sign-extended to (i64 -1).
+ if (Offset->getAPInt().isNegative())
+ return false;
+
// For the moment, restrict ourselves to the case where the offset is a
// multiple of the requested alignment and the base is aligned.
// TODO: generalize if a case found which warrants