diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2016-07-01 02:16:24 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2016-07-01 02:16:24 +0000 |
commit | a8576706e378ef10ea79ed381eddea0238a21353 (patch) | |
tree | 9749e3277ebacdb217eba7357effbeda3a19ce07 /llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp | |
parent | 0101ecade0e37741b4d2fe9126b0bb978a0bf925 (diff) | |
download | bcm5719-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.cpp | 31 |
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); |