diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 106 |
1 files changed, 80 insertions, 26 deletions
diff --git a/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index a7ddadc25de4..7f5a7b666903 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -173,14 +173,14 @@ std::optional<Value *> InstCombiner::targetSimplifyDemandedUseBitsIntrinsic( } std::optional<Value *> InstCombiner::targetSimplifyDemandedVectorEltsIntrinsic( - IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts, APInt &UndefElts2, - APInt &UndefElts3, + IntrinsicInst &II, APInt DemandedElts, APInt &PoisonElts, + APInt &PoisonElts2, APInt &PoisonElts3, std::function<void(Instruction *, unsigned, APInt, APInt &)> SimplifyAndSetOp) { // Handle target specific intrinsics if (II.getCalledFunction()->isTargetIntrinsic()) { return TTI.simplifyDemandedVectorEltsIntrinsic( - *this, II, DemandedElts, UndefElts, UndefElts2, UndefElts3, + *this, II, DemandedElts, PoisonElts, PoisonElts2, PoisonElts3, SimplifyAndSetOp); } return std::nullopt; @@ -1096,6 +1096,54 @@ Value *InstCombinerImpl::foldUsingDistributiveLaws(BinaryOperator &I) { return SimplifySelectsFeedingBinaryOp(I, LHS, RHS); } +std::optional<std::pair<Value *, Value *>> +InstCombinerImpl::matchSymmetricPhiNodesPair(PHINode *LHS, PHINode *RHS) { + if (LHS->getParent() != RHS->getParent()) + return std::nullopt; + + if (LHS->getNumIncomingValues() < 2) + return std::nullopt; + + if (!equal(LHS->blocks(), RHS->blocks())) + return std::nullopt; + + Value *L0 = LHS->getIncomingValue(0); + Value *R0 = RHS->getIncomingValue(0); + + for (unsigned I = 1, E = LHS->getNumIncomingValues(); I != E; ++I) { + Value *L1 = LHS->getIncomingValue(I); + Value *R1 = RHS->getIncomingValue(I); + + if ((L0 == L1 && R0 == R1) || (L0 == R1 && R0 == L1)) + continue; + + return std::nullopt; + } + + return std::optional(std::pair(L0, R0)); +} + +Value *InstCombinerImpl::SimplifyPhiCommutativeBinaryOp(BinaryOperator &I, + Value *Op0, + Value *Op1) { + assert(I.isCommutative() && "Instruction should be commutative"); + + PHINode *LHS = dyn_cast<PHINode>(Op0); + PHINode *RHS = dyn_cast<PHINode>(Op1); + + if (!LHS || !RHS) + return nullptr; + + if (auto P = matchSymmetricPhiNodesPair(LHS, RHS)) { + Value *BI = Builder.CreateBinOp(I.getOpcode(), P->first, P->second); + if (auto *BO = dyn_cast<BinaryOperator>(BI)) + BO->copyIRFlags(&I); + return BI; + } + + return nullptr; +} + Value *InstCombinerImpl::SimplifySelectsFeedingBinaryOp(BinaryOperator &I, Value *LHS, Value *RHS) { @@ -1529,6 +1577,11 @@ Instruction *InstCombinerImpl::foldBinopWithPhiOperands(BinaryOperator &BO) { BO.getParent() != Phi1->getParent()) return nullptr; + if (BO.isCommutative()) { + if (Value *V = SimplifyPhiCommutativeBinaryOp(BO, Phi0, Phi1)) + return replaceInstUsesWith(BO, V); + } + // Fold if there is at least one specific constant value in phi0 or phi1's // incoming values that comes from the same block and this specific constant // value can be used to do optimization for specific binary operator. @@ -1728,8 +1781,8 @@ Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) { // If both arguments of the binary operation are shuffles that use the same // mask and shuffle within a single vector, move the shuffle after the binop. - if (match(LHS, m_Shuffle(m_Value(V1), m_Undef(), m_Mask(Mask))) && - match(RHS, m_Shuffle(m_Value(V2), m_Undef(), m_SpecificMask(Mask))) && + if (match(LHS, m_Shuffle(m_Value(V1), m_Poison(), m_Mask(Mask))) && + match(RHS, m_Shuffle(m_Value(V2), m_Poison(), m_SpecificMask(Mask))) && V1->getType() == V2->getType() && (LHS->hasOneUse() || RHS->hasOneUse() || LHS == RHS)) { // Op(shuffle(V1, Mask), shuffle(V2, Mask)) -> shuffle(Op(V1, V2), Mask) @@ -1770,9 +1823,9 @@ Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) { Constant *C; auto *InstVTy = dyn_cast<FixedVectorType>(Inst.getType()); if (InstVTy && - match(&Inst, - m_c_BinOp(m_OneUse(m_Shuffle(m_Value(V1), m_Undef(), m_Mask(Mask))), - m_ImmConstant(C))) && + match(&Inst, m_c_BinOp(m_OneUse(m_Shuffle(m_Value(V1), m_Poison(), + m_Mask(Mask))), + m_ImmConstant(C))) && cast<FixedVectorType>(V1->getType())->getNumElements() <= InstVTy->getNumElements()) { assert(InstVTy->getScalarType() == V1->getType()->getScalarType() && @@ -1787,8 +1840,8 @@ Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) { ArrayRef<int> ShMask = Mask; unsigned SrcVecNumElts = cast<FixedVectorType>(V1->getType())->getNumElements(); - UndefValue *UndefScalar = UndefValue::get(C->getType()->getScalarType()); - SmallVector<Constant *, 16> NewVecC(SrcVecNumElts, UndefScalar); + PoisonValue *PoisonScalar = PoisonValue::get(C->getType()->getScalarType()); + SmallVector<Constant *, 16> NewVecC(SrcVecNumElts, PoisonScalar); bool MayChange = true; unsigned NumElts = InstVTy->getNumElements(); for (unsigned I = 0; I < NumElts; ++I) { @@ -1801,29 +1854,29 @@ Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) { // 2. The shuffle needs an element of the constant vector that can't // be mapped to a new constant vector. // 3. This is a widening shuffle that copies elements of V1 into the - // extended elements (extending with undef is allowed). - if (!CElt || (!isa<UndefValue>(NewCElt) && NewCElt != CElt) || + // extended elements (extending with poison is allowed). + if (!CElt || (!isa<PoisonValue>(NewCElt) && NewCElt != CElt) || I >= SrcVecNumElts) { MayChange = false; break; } NewVecC[ShMask[I]] = CElt; } - // If this is a widening shuffle, we must be able to extend with undef - // elements. If the original binop does not produce an undef in the high + // If this is a widening shuffle, we must be able to extend with poison + // elements. If the original binop does not produce a poison in the high // lanes, then this transform is not safe. - // Similarly for undef lanes due to the shuffle mask, we can only - // transform binops that preserve undef. - // TODO: We could shuffle those non-undef constant values into the - // result by using a constant vector (rather than an undef vector) + // Similarly for poison lanes due to the shuffle mask, we can only + // transform binops that preserve poison. + // TODO: We could shuffle those non-poison constant values into the + // result by using a constant vector (rather than an poison vector) // as operand 1 of the new binop, but that might be too aggressive // for target-independent shuffle creation. if (I >= SrcVecNumElts || ShMask[I] < 0) { - Constant *MaybeUndef = + Constant *MaybePoison = ConstOp1 - ? ConstantFoldBinaryOpOperands(Opcode, UndefScalar, CElt, DL) - : ConstantFoldBinaryOpOperands(Opcode, CElt, UndefScalar, DL); - if (!MaybeUndef || !match(MaybeUndef, m_Undef())) { + ? ConstantFoldBinaryOpOperands(Opcode, PoisonScalar, CElt, DL) + : ConstantFoldBinaryOpOperands(Opcode, CElt, PoisonScalar, DL); + if (!MaybePoison || !isa<PoisonValue>(MaybePoison)) { MayChange = false; break; } @@ -1831,9 +1884,10 @@ Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) { } if (MayChange) { Constant *NewC = ConstantVector::get(NewVecC); - // It may not be safe to execute a binop on a vector with undef elements + // It may not be safe to execute a binop on a vector with poison elements // because the entire instruction can be folded to undef or create poison // that did not exist in the original code. + // TODO: The shift case should not be necessary. if (Inst.isIntDivRem() || (Inst.isShift() && ConstOp1)) NewC = getSafeVectorConstantForBinop(Opcode, NewC, ConstOp1); @@ -2241,10 +2295,10 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) { // compile-time. if (auto *GEPFVTy = dyn_cast<FixedVectorType>(GEPType)) { auto VWidth = GEPFVTy->getNumElements(); - APInt UndefElts(VWidth, 0); + APInt PoisonElts(VWidth, 0); APInt AllOnesEltMask(APInt::getAllOnes(VWidth)); if (Value *V = SimplifyDemandedVectorElts(&GEP, AllOnesEltMask, - UndefElts)) { + PoisonElts)) { if (V != &GEP) return replaceInstUsesWith(GEP, V); return &GEP; @@ -2462,7 +2516,7 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) { Idx2); } ConstantInt *C; - if (match(GEP.getOperand(1), m_OneUse(m_SExt(m_OneUse(m_NSWAdd( + if (match(GEP.getOperand(1), m_OneUse(m_SExtLike(m_OneUse(m_NSWAdd( m_Value(Idx1), m_ConstantInt(C))))))) { // %add = add nsw i32 %idx1, idx2 // %sidx = sext i32 %add to i64 |