diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -633,6 +633,12 @@ const SCEV *getNotSCEV(const SCEV *V); /// Return LHS-RHS. Minus is represented in SCEV as A+B*-1. + /// + /// If the LHS and RHS are pointers which don't share a common base + /// (according to getPointerBase()), this returns a SCEVCouldNotCompute. + /// To compute the difference between two unrelated pointers, you can + /// explicitly convert the arguments using getPtrToIntExpr(), for pointer + /// types that support it. const SCEV *getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap, unsigned Depth = 0); diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -4138,6 +4138,15 @@ if (LHS == RHS) return getZero(LHS->getType()); + // If we subtract two pointers with different pointer bases, bail. + // Eventually, we're going to add an assertion to getMulExpr that we + // can't multiply by a pointer. + if (RHS->getType()->isPointerTy()) { + if (!LHS->getType()->isPointerTy() || + getPointerBase(LHS) != getPointerBase(RHS)) + return getCouldNotCompute(); + } + // We represent LHS - RHS as LHS + (-1)*RHS. This transformation // makes it so that we cannot make much use of NUW. auto AddFlags = SCEV::FlagAnyWrap; @@ -8029,6 +8038,16 @@ } case ICmpInst::ICMP_EQ: { // while (X == Y) // Convert to: while (X-Y == 0) + if (LHS->getType()->isPointerTy()) { + LHS = getLosslessPtrToIntExpr(LHS); + if (isa(LHS)) + return LHS; + } + if (RHS->getType()->isPointerTy()) { + RHS = getLosslessPtrToIntExpr(RHS); + if (isa(RHS)) + return RHS; + } ExitLimit EL = howFarToNonZero(getMinusSCEV(LHS, RHS), L); if (EL.hasAnyInfo()) return EL; break; @@ -10066,10 +10085,13 @@ if (Pred == CmpInst::ICMP_EQ) return false; - if (Pred == CmpInst::ICMP_NE) - return CheckRanges(getSignedRange(LHS), getSignedRange(RHS)) || - CheckRanges(getUnsignedRange(LHS), getUnsignedRange(RHS)) || - isKnownNonZero(getMinusSCEV(LHS, RHS)); + if (Pred == CmpInst::ICMP_NE) { + if (CheckRanges(getSignedRange(LHS), getSignedRange(RHS)) || + CheckRanges(getUnsignedRange(LHS), getUnsignedRange(RHS))) + return true; + auto *Diff = getMinusSCEV(LHS, RHS); + return !isa(Diff) && isKnownNonZero(Diff); + } if (CmpInst::isSigned(Pred)) return CheckRanges(getSignedRange(LHS), getSignedRange(RHS)); @@ -10590,6 +10612,10 @@ if (!isa(FoundRHS) && !isa(FoundLHS)) return isImpliedCondOperands(Pred, LHS, RHS, FoundRHS, FoundLHS, Context); + // Don't try to getNotSCEV pointers. + if (LHS->getType()->isPointerTy() || FoundLHS->getType()->isPointerTy()) + return false; + // There's no clear preference between forms 3. and 4., try both. return isImpliedCondOperands(FoundPred, getNotSCEV(LHS), getNotSCEV(RHS), FoundLHS, FoundRHS, Context) || diff --git a/llvm/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp b/llvm/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp --- a/llvm/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp +++ b/llvm/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp @@ -57,7 +57,8 @@ // Test whether the difference is known to be great enough that memory of // the given sizes don't overlap. This assumes that ASizeInt and BSizeInt // are non-zero, which is special-cased above. - if (ASizeInt.ule(SE.getUnsignedRange(BA).getUnsignedMin()) && + if (!isa(BA) && + ASizeInt.ule(SE.getUnsignedRange(BA).getUnsignedMin()) && (-BSizeInt).uge(SE.getUnsignedRange(BA).getUnsignedMax())) return AliasResult::NoAlias; @@ -71,7 +72,8 @@ // Test whether the difference is known to be great enough that memory of // the given sizes don't overlap. This assumes that ASizeInt and BSizeInt // are non-zero, which is special-cased above. - if (BSizeInt.ule(SE.getUnsignedRange(AB).getUnsignedMin()) && + if (!isa(AB) && + BSizeInt.ule(SE.getUnsignedRange(AB).getUnsignedMin()) && (-ASizeInt).uge(SE.getUnsignedRange(AB).getUnsignedMax())) return AliasResult::NoAlias; } diff --git a/llvm/lib/Analysis/StackSafetyAnalysis.cpp b/llvm/lib/Analysis/StackSafetyAnalysis.cpp --- a/llvm/lib/Analysis/StackSafetyAnalysis.cpp +++ b/llvm/lib/Analysis/StackSafetyAnalysis.cpp @@ -263,6 +263,8 @@ const SCEV *AddrExp = SE.getTruncateOrZeroExtend(SE.getSCEV(Addr), PtrTy); const SCEV *BaseExp = SE.getTruncateOrZeroExtend(SE.getSCEV(Base), PtrTy); const SCEV *Diff = SE.getMinusSCEV(AddrExp, BaseExp); + if (isa(Diff)) + return UnknownRange; ConstantRange Offset = SE.getSignedRange(Diff); if (isUnsafe(Offset)) diff --git a/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp b/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp --- a/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp +++ b/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp @@ -135,6 +135,8 @@ PtrSCEV = SE->getTruncateOrZeroExtend( PtrSCEV, SE->getEffectiveSCEVType(AASCEV->getType())); const SCEV *DiffSCEV = SE->getMinusSCEV(PtrSCEV, AASCEV); + if (isa(DiffSCEV)) + return Align(1); // On 32-bit platforms, DiffSCEV might now have type i32 -- we've always // sign-extended OffSCEV to i64, so make sure they agree again. diff --git a/llvm/lib/Transforms/Scalar/LoopRerollPass.cpp b/llvm/lib/Transforms/Scalar/LoopRerollPass.cpp --- a/llvm/lib/Transforms/Scalar/LoopRerollPass.cpp +++ b/llvm/lib/Transforms/Scalar/LoopRerollPass.cpp @@ -911,6 +911,8 @@ // Check that the first root is evenly spaced. unsigned N = DRS.Roots.size() + 1; const SCEV *StepSCEV = SE->getMinusSCEV(SE->getSCEV(DRS.Roots[0]), ADR); + if (isa(StepSCEV)) + return false; const SCEV *ScaleSCEV = SE->getConstant(StepSCEV->getType(), N); if (ADR->getStepRecurrence(*SE) != SE->getMulExpr(StepSCEV, ScaleSCEV)) return false; diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp --- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -2963,7 +2963,7 @@ // The increment must be loop-invariant so it can be kept in a register. const SCEV *PrevExpr = SE.getSCEV(PrevIV); const SCEV *IncExpr = SE.getMinusSCEV(OperExpr, PrevExpr); - if (!SE.isLoopInvariant(IncExpr, L)) + if (isa(IncExpr) || !SE.isLoopInvariant(IncExpr, L)) continue; if (Chain.isProfitableIncrement(OperExpr, IncExpr, SE)) { @@ -3316,7 +3316,9 @@ // x == y --> x - y == 0 const SCEV *N = SE.getSCEV(NV); - if (SE.isLoopInvariant(N, L) && isSafeToExpand(N, SE)) { + if (SE.isLoopInvariant(N, L) && isSafeToExpand(N, SE) && + (!NV->getType()->isPointerTy() || + SE.getPointerBase(N) == SE.getPointerBase(S))) { // S is normalized, so normalize N before folding it into S // to keep the result normalized. N = normalizeForPostIncUse(N, TmpPostIncLoops, SE); diff --git a/llvm/test/Analysis/StackSafetyAnalysis/local.ll b/llvm/test/Analysis/StackSafetyAnalysis/local.ll --- a/llvm/test/Analysis/StackSafetyAnalysis/local.ll +++ b/llvm/test/Analysis/StackSafetyAnalysis/local.ll @@ -71,7 +71,7 @@ ; CHECK-LABEL: @StoreInBounds4 dso_preemptable{{$}} ; CHECK-NEXT: args uses: ; CHECK-NEXT: allocas uses: -; CHECK-NEXT: x[4]: [-9223372036854775808,9223372036854775807){{$}} +; CHECK-NEXT: x[4]: full-set{{$}} ; CHECK-EMPTY: entry: %x = alloca i32, align 4 diff --git a/llvm/test/CodeGen/ARM/lsr-undef-in-binop.ll b/llvm/test/CodeGen/ARM/lsr-undef-in-binop.ll deleted file mode 100644 --- a/llvm/test/CodeGen/ARM/lsr-undef-in-binop.ll +++ /dev/null @@ -1,251 +0,0 @@ -; REQUIRES: arm-registered-target -; RUN: opt -S -loop-reduce %s -o - | FileCheck %s - -target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" -target triple = "armv8-unknown-hurd-eabihf" - -%"class.std::__1::vector.182" = type { %"class.std::__1::__vector_base.183" } -%"class.std::__1::__vector_base.183" = type { i8*, i8*, %"class.std::__1::__compressed_pair.184" } -%"class.std::__1::__compressed_pair.184" = type { %"struct.std::__1::__compressed_pair_elem.185" } -%"struct.std::__1::__compressed_pair_elem.185" = type { i8* } -%"class.std::__1::__vector_base_common" = type { i8 } - -$vector_insert = comdat any - -declare i8* @Allocate(i32) local_unnamed_addr -declare void @Free(i8*) local_unnamed_addr -declare void @_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv(%"class.std::__1::__vector_base_common"*) local_unnamed_addr -declare i8* @memmove(i8*, i8*, i32) local_unnamed_addr - -; Function Attrs: noimplicitfloat nounwind uwtable -define linkonce_odr i32 @vector_insert(%"class.std::__1::vector.182"*, [1 x i32], i8*, i8*) local_unnamed_addr #1 comdat align 2 { -; CHECK-LABEL: vector_insert - %5 = extractvalue [1 x i32] %1, 0 - %6 = getelementptr inbounds %"class.std::__1::vector.182", %"class.std::__1::vector.182"* %0, i32 0, i32 0, i32 0 - %7 = load i8*, i8** %6, align 4 -; CHECK: [[LOAD:%[0-9]+]] = load i8*, i8** - %8 = bitcast %"class.std::__1::vector.182"* %0 to i32* - %9 = ptrtoint i8* %7 to i32 -; CHECK: [[NEW_CAST:%[0-9]+]] = ptrtoint i8* [[LOAD]] to i32 -; CHECK: [[OLD_CAST:%[0-9]+]] = ptrtoint i8* [[LOAD]] to i32 - %10 = sub i32 %5, %9 - %11 = getelementptr inbounds i8, i8* %7, i32 %10 - %12 = ptrtoint i8* %3 to i32 - %13 = ptrtoint i8* %2 to i32 - %14 = sub i32 %12, %13 - %15 = icmp sgt i32 %14, 0 - br i1 %15, label %18, label %16 - -;