From: Matt Arsenault Date: Fri, 1 Jul 2016 02:16:24 +0000 (+0000) Subject: LoadStoreVectorizer: improvements: better pointer analysis X-Git-Tag: android-x86-7.1-r4~30909 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=af386368d0d329d4685955e9ad71fa18e5973a75;p=android-x86%2Fexternal-llvm.git 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@274324 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp b/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp index b56d0ed0c9b..f24628eb2f5 100644 --- a/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp +++ b/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp @@ -286,20 +286,41 @@ bool Vectorizer::isConsecutiveAccess(Value *A, Value *B) { if (!isa(OpA) && !isa(OpA)) return false; + bool Signed = isa(OpA); + OpA = dyn_cast(OpA->getOperand(0)); OpB = dyn_cast(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(OpB->getOperand(1)) && + cast(OpB->getOperand(1))->getSExtValue() > 0) { + if (Signed) + Safe = cast(OpB)->hasNoSignedWrap(); + else + Safe = cast(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);