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 @@ -1192,6 +1192,7 @@ "This is not a truncating conversion!"); assert(isSCEVable(Ty) && "This is not a conversion to a SCEVable type!"); + assert(!Op->getType()->isPointerTy() && "Can't truncate pointer!"); Ty = getEffectiveSCEVType(Ty); FoldingSetNodeID ID; @@ -1581,6 +1582,7 @@ "This is not an extending conversion!"); assert(isSCEVable(Ty) && "This is not a conversion to a SCEVable type!"); + assert(!Op->getType()->isPointerTy() && "Can't extend pointer!"); Ty = getEffectiveSCEVType(Ty); // Fold if the operand is constant. @@ -1883,6 +1885,7 @@ "This is not an extending conversion!"); assert(isSCEVable(Ty) && "This is not a conversion to a SCEVable type!"); + assert(!Op->getType()->isPointerTy() && "Can't extend pointer!"); Ty = getEffectiveSCEVType(Ty); // Fold if the operand is constant. @@ -2410,6 +2413,9 @@ for (unsigned i = 1, e = Ops.size(); i != e; ++i) assert(getEffectiveSCEVType(Ops[i]->getType()) == ETy && "SCEVAddExpr operand types don't match!"); + unsigned NumPtrs = count_if( + Ops, [](const SCEV *Op) { return Op->getType()->isPointerTy(); }); + assert(NumPtrs <= 1 && "add has at most one pointer operand"); #endif // Sort by complexity, this groups all similar expression types together. @@ -2645,12 +2651,16 @@ Ops.clear(); if (AccumulatedConstant != 0) Ops.push_back(getConstant(AccumulatedConstant)); - for (auto &MulOp : MulOpLists) - if (MulOp.first != 0) + for (auto &MulOp : MulOpLists) { + if (MulOp.first == 1) { + Ops.push_back(getAddExpr(MulOp.second, SCEV::FlagAnyWrap, Depth + 1)); + } else if (MulOp.first != 0) { Ops.push_back(getMulExpr( getConstant(MulOp.first), getAddExpr(MulOp.second, SCEV::FlagAnyWrap, Depth + 1), SCEV::FlagAnyWrap, Depth + 1)); + } + } if (Ops.empty()) return getZero(Ty); if (Ops.size() == 1) @@ -2969,9 +2979,10 @@ assert(!Ops.empty() && "Cannot get empty mul!"); if (Ops.size() == 1) return Ops[0]; #ifndef NDEBUG - Type *ETy = getEffectiveSCEVType(Ops[0]->getType()); + Type *ETy = Ops[0]->getType(); + assert(!ETy->isPointerTy()); for (unsigned i = 1, e = Ops.size(); i != e; ++i) - assert(getEffectiveSCEVType(Ops[i]->getType()) == ETy && + assert(Ops[i]->getType() == ETy && "SCEVMulExpr operand types don't match!"); #endif @@ -3256,8 +3267,9 @@ /// possible. const SCEV *ScalarEvolution::getUDivExpr(const SCEV *LHS, const SCEV *RHS) { - assert(getEffectiveSCEVType(LHS->getType()) == - getEffectiveSCEVType(RHS->getType()) && + assert(!LHS->getType()->isPointerTy() && + "SCEVUDivExpr operand can't be pointer!"); + assert(LHS->getType() == RHS->getType() && "SCEVUDivExpr operand types don't match!"); FoldingSetNodeID ID; @@ -3506,9 +3518,11 @@ if (Operands.size() == 1) return Operands[0]; #ifndef NDEBUG Type *ETy = getEffectiveSCEVType(Operands[0]->getType()); - for (unsigned i = 1, e = Operands.size(); i != e; ++i) + for (unsigned i = 1, e = Operands.size(); i != e; ++i) { assert(getEffectiveSCEVType(Operands[i]->getType()) == ETy && "SCEVAddRecExpr operand types don't match!"); + assert(!Operands[i]->getType()->isPointerTy() && "Step must be integer"); + } for (unsigned i = 0, e = Operands.size(); i != e; ++i) assert(isLoopInvariant(Operands[i], L) && "SCEVAddRecExpr operand is not loop-invariant!"); @@ -3662,9 +3676,13 @@ if (Ops.size() == 1) return Ops[0]; #ifndef NDEBUG Type *ETy = getEffectiveSCEVType(Ops[0]->getType()); - for (unsigned i = 1, e = Ops.size(); i != e; ++i) + for (unsigned i = 1, e = Ops.size(); i != e; ++i) { assert(getEffectiveSCEVType(Ops[i]->getType()) == ETy && "Operand types don't match!"); + assert(Ops[0]->getType()->isPointerTy() == + Ops[i]->getType()->isPointerTy() && + "min/max should be consistently pointerish"); + } #endif bool IsSigned = Kind == scSMaxExpr || Kind == scSMinExpr; @@ -10579,6 +10597,8 @@ } } + if (LHS->getType()->isPointerTy()) + return false; if (CmpInst::isSigned(Pred)) { LHS = getSignExtendExpr(LHS, FoundLHS->getType()); RHS = getSignExtendExpr(RHS, FoundLHS->getType()); @@ -10588,6 +10608,8 @@ } } else if (getTypeSizeInBits(LHS->getType()) > getTypeSizeInBits(FoundLHS->getType())) { + if (FoundLHS->getType()->isPointerTy()) + return false; if (CmpInst::isSigned(FoundPred)) { FoundLHS = getSignExtendExpr(FoundLHS, LHS->getType()); FoundRHS = getSignExtendExpr(FoundRHS, LHS->getType()); 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 @@ -682,8 +682,11 @@ const APInt &RA = RC->getAPInt(); // Handle x /s -1 as x * -1, to give ScalarEvolution a chance to do // some folding. - if (RA.isAllOnesValue()) + if (RA.isAllOnesValue()) { + if (LHS->getType()->isPointerTy()) + return nullptr; return SE.getMulExpr(LHS, RC); + } // Handle x /s 1 as x. if (RA == 1) return LHS; @@ -4063,7 +4066,8 @@ // Determine the integer type for the base formula. Type *DstTy = Base.getType(); if (!DstTy) return; - DstTy = SE.getEffectiveSCEVType(DstTy); + if (DstTy->isPointerTy()) + return; for (Type *SrcTy : Types) { if (SrcTy != DstTy && TTI.isTruncateFree(SrcTy, DstTy)) { @@ -5301,7 +5305,7 @@ if (F.BaseGV) { // Flush the operand list to suppress SCEVExpander hoisting. if (!Ops.empty()) { - Value *FullV = Rewriter.expandCodeFor(SE.getAddExpr(Ops), Ty); + Value *FullV = Rewriter.expandCodeFor(SE.getAddExpr(Ops), IntTy); Ops.clear(); Ops.push_back(SE.getUnknown(FullV)); } diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp --- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp @@ -1143,6 +1143,10 @@ const SCEVAddRecExpr *Phi, const SCEVAddRecExpr *Requested, bool &InvertStep) { + // We can't transform to match a pointer PHI. + if (Phi->getType()->isPointerTy()) + return false; + Type *PhiTy = SE.getEffectiveSCEVType(Phi->getType()); Type *RequestedTy = SE.getEffectiveSCEVType(Requested->getType()); @@ -1161,8 +1165,7 @@ } // Check whether inverting will help: {R,+,-1} == R - {0,+,1}. - if (SE.getAddExpr(Requested->getStart(), - SE.getNegativeSCEV(Requested)) == Phi) { + if (SE.getMinusSCEV(Requested->getStart(), Requested) == Phi) { InvertStep = true; return true; } @@ -1573,8 +1576,8 @@ // Rewrite an AddRec in terms of the canonical induction variable, if // its type is more narrow. if (CanonicalIV && - SE.getTypeSizeInBits(CanonicalIV->getType()) > - SE.getTypeSizeInBits(Ty)) { + SE.getTypeSizeInBits(CanonicalIV->getType()) > SE.getTypeSizeInBits(Ty) && + !S->getType()->isPointerTy()) { SmallVector NewOps(S->getNumOperands()); for (unsigned i = 0, e = S->getNumOperands(); i != e; ++i) NewOps[i] = SE.getAnyExtendExpr(S->op_begin()[i], CanonicalIV->getType()); diff --git a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp --- a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp +++ b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp @@ -96,13 +96,13 @@ const SCEV *S1 = SE.getSCEV(V1); const SCEV *S2 = SE.getSCEV(V2); - const SCEV *P0 = SE.getAddExpr(S0, S0); - const SCEV *P1 = SE.getAddExpr(S1, S1); - const SCEV *P2 = SE.getAddExpr(S2, S2); + const SCEV *P0 = SE.getAddExpr(S0, SE.getConstant(S0->getType(), 2)); + const SCEV *P1 = SE.getAddExpr(S1, SE.getConstant(S0->getType(), 2)); + const SCEV *P2 = SE.getAddExpr(S2, SE.getConstant(S0->getType(), 2)); - const SCEVMulExpr *M0 = cast(P0); - const SCEVMulExpr *M1 = cast(P1); - const SCEVMulExpr *M2 = cast(P2); + auto *M0 = cast(P0); + auto *M1 = cast(P1); + auto *M2 = cast(P2); EXPECT_EQ(cast(M0->getOperand(0))->getValue()->getZExtValue(), 2u); @@ -707,6 +707,7 @@ ReturnInst::Create(Context, nullptr, EndBB); ScalarEvolution SE = buildSE(*F); const SCEV *S = SE.getSCEV(Accum); + S = SE.getLosslessPtrToIntExpr(S); Type *I128Ty = Type::getInt128Ty(Context); SE.getZeroExtendExpr(S, I128Ty); }