summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2016-07-01 02:16:24 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2016-07-01 02:16:24 +0000
commita8576706e378ef10ea79ed381eddea0238a21353 (patch)
tree9749e3277ebacdb217eba7357effbeda3a19ce07 /llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp
parent0101ecade0e37741b4d2fe9126b0bb978a0bf925 (diff)
downloadbcm5719-llvm-a8576706e378ef10ea79ed381eddea0238a21353.tar.gz
bcm5719-llvm-a8576706e378ef10ea79ed381eddea0238a21353.zip
LoadStoreVectorizer: improvements: better pointer analysis
If OpB has an ADD NSW/NUW, we can use that to prove that adding 1 to OpA won't wrap if OpA + 1 == OpB. Patch by Fiona Glaser llvm-svn: 274324
Diffstat (limited to 'llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp')
-rw-r--r--llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp31
1 files changed, 26 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp b/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp
index b56d0ed0c9b..f24628eb2f5 100644
--- a/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp
@@ -286,20 +286,41 @@ bool Vectorizer::isConsecutiveAccess(Value *A, Value *B) {
if (!isa<SExtInst>(OpA) && !isa<ZExtInst>(OpA))
return false;
+ bool Signed = isa<SExtInst>(OpA);
+
OpA = dyn_cast<Instruction>(OpA->getOperand(0));
OpB = dyn_cast<Instruction>(OpB->getOperand(0));
if (!OpA || !OpB || OpA->getType() != OpB->getType())
return false;
// Now we need to prove that adding 1 to OpA won't overflow.
+ bool Safe = false;
+ // First attempt: if OpB is an add with NSW/NUW, and OpB is 1 added to OpA,
+ // we're okay.
+ if (OpB->getOpcode() == Instruction::Add &&
+ isa<ConstantInt>(OpB->getOperand(1)) &&
+ cast<ConstantInt>(OpB->getOperand(1))->getSExtValue() > 0) {
+ if (Signed)
+ Safe = cast<BinaryOperator>(OpB)->hasNoSignedWrap();
+ else
+ Safe = cast<BinaryOperator>(OpB)->hasNoUnsignedWrap();
+ }
+
unsigned BitWidth = OpA->getType()->getScalarSizeInBits();
- APInt KnownZero = APInt(BitWidth, 0);
- APInt KnownOne = APInt(BitWidth, 0);
- computeKnownBits(OpA, KnownZero, KnownOne, DL, 0, nullptr, OpA, &DT);
+
+ // Second attempt:
// If any bits are known to be zero other than the sign bit in OpA, we can
// add 1 to it while guaranteeing no overflow of any sort.
- KnownZero &= ~APInt::getHighBitsSet(BitWidth, 1);
- if (KnownZero == 0)
+ if (!Safe) {
+ APInt KnownZero(BitWidth, 0);
+ APInt KnownOne(BitWidth, 0);
+ computeKnownBits(OpA, KnownZero, KnownOne, DL, 0, nullptr, OpA, &DT);
+ KnownZero &= ~APInt::getHighBitsSet(BitWidth, 1);
+ if (KnownZero != 0)
+ Safe = true;
+ }
+
+ if (!Safe)
return false;
const SCEV *OffsetSCEVA = SE.getSCEV(OpA);
OpenPOWER on IntegriCloud