@@ -3242,44 +3242,47 @@ static std::optional<uint64_t> getExactInteger(const APFloat &APF,
32423242// determine whether this is worth generating code for.
32433243static std::optional<VIDSequence> isSimpleVIDSequence(SDValue Op,
32443244 unsigned EltSizeInBits) {
3245- unsigned NumElts = Op.getNumOperands();
32463245 assert(Op.getOpcode() == ISD::BUILD_VECTOR && "Unexpected BUILD_VECTOR");
3246+ if (!cast<BuildVectorSDNode>(Op)->isConstant())
3247+ return std::nullopt;
32473248 bool IsInteger = Op.getValueType().isInteger();
32483249
32493250 std::optional<unsigned> SeqStepDenom;
32503251 std::optional<int64_t> SeqStepNum, SeqAddend;
32513252 std::optional<std::pair<uint64_t, unsigned>> PrevElt;
32523253 assert(EltSizeInBits >= Op.getValueType().getScalarSizeInBits());
3253- for (unsigned Idx = 0; Idx < NumElts; Idx++) {
3254- // Assume undef elements match the sequence; we just have to be careful
3255- // when interpolating across them.
3256- if (Op.getOperand(Idx).isUndef())
3257- continue;
32583254
3259- uint64_t Val;
3255+ // First extract the ops into a list of constant integer values. This may not
3256+ // be possible for floats if they're not all representable as integers.
3257+ SmallVector<std::optional<uint64_t>> Elts(Op.getNumOperands());
3258+ const unsigned OpSize = Op.getScalarValueSizeInBits();
3259+ for (auto [Idx, Elt] : enumerate(Op->op_values())) {
3260+ if (Elt.isUndef()) {
3261+ Elts[Idx] = std::nullopt;
3262+ continue;
3263+ }
32603264 if (IsInteger) {
3261- // The BUILD_VECTOR must be all constants.
3262- if (!isa<ConstantSDNode>(Op.getOperand(Idx)))
3263- return std::nullopt;
3264- Val = Op.getConstantOperandVal(Idx) &
3265- maskTrailingOnes<uint64_t>(Op.getScalarValueSizeInBits());
3265+ Elts[Idx] = Elt->getAsZExtVal() & maskTrailingOnes<uint64_t>(OpSize);
32663266 } else {
3267- // The BUILD_VECTOR must be all constants.
3268- if (!isa<ConstantFPSDNode>(Op.getOperand(Idx)))
3269- return std::nullopt;
3270- if (auto ExactInteger = getExactInteger(
3271- cast<ConstantFPSDNode>(Op.getOperand(Idx))->getValueAPF(),
3272- Op.getScalarValueSizeInBits()))
3273- Val = *ExactInteger;
3274- else
3267+ auto ExactInteger =
3268+ getExactInteger(cast<ConstantFPSDNode>(Elt)->getValueAPF(), OpSize);
3269+ if (!ExactInteger)
32753270 return std::nullopt;
3271+ Elts[Idx] = *ExactInteger;
32763272 }
3273+ }
3274+
3275+ for (auto [Idx, Elt] : enumerate(Elts)) {
3276+ // Assume undef elements match the sequence; we just have to be careful
3277+ // when interpolating across them.
3278+ if (!Elt)
3279+ continue;
32773280
32783281 if (PrevElt) {
32793282 // Calculate the step since the last non-undef element, and ensure
32803283 // it's consistent across the entire sequence.
32813284 unsigned IdxDiff = Idx - PrevElt->second;
3282- int64_t ValDiff = SignExtend64(Val - PrevElt->first, EltSizeInBits);
3285+ int64_t ValDiff = SignExtend64(*Elt - PrevElt->first, EltSizeInBits);
32833286
32843287 // A zero-value value difference means that we're somewhere in the middle
32853288 // of a fractional step, e.g. <0,0,0*,0,1,1,1,1>. Wait until we notice a
@@ -3309,8 +3312,8 @@ static std::optional<VIDSequence> isSimpleVIDSequence(SDValue Op,
33093312 }
33103313
33113314 // Record this non-undef element for later.
3312- if (!PrevElt || PrevElt->first != Val )
3313- PrevElt = std::make_pair(Val , Idx);
3315+ if (!PrevElt || PrevElt->first != *Elt )
3316+ PrevElt = std::make_pair(*Elt , Idx);
33143317 }
33153318
33163319 // We need to have logged a step for this to count as a legal index sequence.
@@ -3319,21 +3322,12 @@ static std::optional<VIDSequence> isSimpleVIDSequence(SDValue Op,
33193322
33203323 // Loop back through the sequence and validate elements we might have skipped
33213324 // while waiting for a valid step. While doing this, log any sequence addend.
3322- for (unsigned Idx = 0; Idx < NumElts; Idx++ ) {
3323- if (Op.getOperand(Idx).isUndef() )
3325+ for (auto [ Idx, Elt] : enumerate(Elts) ) {
3326+ if (!Elt )
33243327 continue;
3325- uint64_t Val;
3326- if (IsInteger) {
3327- Val = Op.getConstantOperandVal(Idx) &
3328- maskTrailingOnes<uint64_t>(Op.getScalarValueSizeInBits());
3329- } else {
3330- Val = *getExactInteger(
3331- cast<ConstantFPSDNode>(Op.getOperand(Idx))->getValueAPF(),
3332- Op.getScalarValueSizeInBits());
3333- }
33343328 uint64_t ExpectedVal =
33353329 (int64_t)(Idx * (uint64_t)*SeqStepNum) / *SeqStepDenom;
3336- int64_t Addend = SignExtend64(Val - ExpectedVal, EltSizeInBits);
3330+ int64_t Addend = SignExtend64(*Elt - ExpectedVal, EltSizeInBits);
33373331 if (!SeqAddend)
33383332 SeqAddend = Addend;
33393333 else if (Addend != SeqAddend)
0 commit comments