diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index e27a88baf411..5745ff4d2b7c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1412,49 +1412,41 @@ bool TargetLowering::SimplifyDemandedBits( Known = Known.zext(BitWidth, true /* ExtendedBitsAreKnownZero */); break; } - case ISD::SIGN_EXTEND: { + case ISD::SIGN_EXTEND: + case ISD::SIGN_EXTEND_VECTOR_INREG: { SDValue Src = Op.getOperand(0); - unsigned InBits = Src.getScalarValueSizeInBits(); + EVT SrcVT = Src.getValueType(); + unsigned InBits = SrcVT.getScalarSizeInBits(); + unsigned InElts = SrcVT.isVector() ? SrcVT.getVectorNumElements() : 1; + bool IsVecInReg = Op.getOpcode() == ISD::SIGN_EXTEND_VECTOR_INREG; // If none of the top bits are demanded, convert this into an any_extend. - if (DemandedBits.getActiveBits() <= InBits) + // TODO: Add SIGN_EXTEND_VECTOR_INREG - ANY_EXTEND_VECTOR_INREG fold. + if (DemandedBits.getActiveBits() <= InBits && !IsVecInReg) return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ANY_EXTEND, dl, VT, Src)); + APInt InDemandedBits = DemandedBits.trunc(InBits); + APInt InDemandedElts = DemandedElts.zextOrSelf(InElts); + // Since some of the sign extended bits are demanded, we know that the sign // bit is demanded. - APInt InDemandedBits = DemandedBits.trunc(InBits); InDemandedBits.setBit(InBits - 1); - if (SimplifyDemandedBits(Src, InDemandedBits, Known, TLO, Depth + 1)) + if (SimplifyDemandedBits(Src, InDemandedBits, InDemandedElts, Known, TLO, + Depth + 1)) return true; assert(!Known.hasConflict() && "Bits known to be one AND zero?"); + assert(Known.getBitWidth() == InBits && "Src width has changed?"); + // If the sign bit is known one, the top bits match. Known = Known.sext(BitWidth); // If the sign bit is known zero, convert this to a zero extend. - if (Known.isNonNegative()) + // TODO: Add SIGN_EXTEND_VECTOR_INREG - ZERO_EXTEND_VECTOR_INREG fold. + if (Known.isNonNegative() && !IsVecInReg) return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ZERO_EXTEND, dl, VT, Src)); break; } - case ISD::SIGN_EXTEND_VECTOR_INREG: { - // TODO - merge this with SIGN_EXTEND above? - SDValue Src = Op.getOperand(0); - unsigned InBits = Src.getScalarValueSizeInBits(); - - APInt InDemandedBits = DemandedBits.trunc(InBits); - - // If some of the sign extended bits are demanded, we know that the sign - // bit is demanded. - if (InBits < DemandedBits.getActiveBits()) - InDemandedBits.setBit(InBits - 1); - - if (SimplifyDemandedBits(Src, InDemandedBits, Known, TLO, Depth + 1)) - return true; - assert(!Known.hasConflict() && "Bits known to be one AND zero?"); - // If the sign bit is known one, the top bits match. - Known = Known.sext(BitWidth); - break; - } case ISD::ANY_EXTEND: { SDValue Src = Op.getOperand(0); unsigned InBits = Src.getScalarValueSizeInBits();