@@ -3242,44 +3242,47 @@ static std::optional<uint64_t> getExactInteger(const APFloat &APF,
3242
3242
// determine whether this is worth generating code for.
3243
3243
static std::optional<VIDSequence> isSimpleVIDSequence(SDValue Op,
3244
3244
unsigned EltSizeInBits) {
3245
- unsigned NumElts = Op.getNumOperands();
3246
3245
assert(Op.getOpcode() == ISD::BUILD_VECTOR && "Unexpected BUILD_VECTOR");
3246
+ if (!cast<BuildVectorSDNode>(Op)->isConstant())
3247
+ return std::nullopt;
3247
3248
bool IsInteger = Op.getValueType().isInteger();
3248
3249
3249
3250
std::optional<unsigned> SeqStepDenom;
3250
3251
std::optional<int64_t> SeqStepNum, SeqAddend;
3251
3252
std::optional<std::pair<uint64_t, unsigned>> PrevElt;
3252
3253
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;
3258
3254
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
+ }
3260
3264
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);
3266
3266
} 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)
3275
3270
return std::nullopt;
3271
+ Elts[Idx] = *ExactInteger;
3276
3272
}
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;
3277
3280
3278
3281
if (PrevElt) {
3279
3282
// Calculate the step since the last non-undef element, and ensure
3280
3283
// it's consistent across the entire sequence.
3281
3284
unsigned IdxDiff = Idx - PrevElt->second;
3282
- int64_t ValDiff = SignExtend64(Val - PrevElt->first, EltSizeInBits);
3285
+ int64_t ValDiff = SignExtend64(*Elt - PrevElt->first, EltSizeInBits);
3283
3286
3284
3287
// A zero-value value difference means that we're somewhere in the middle
3285
3288
// 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,
3309
3312
}
3310
3313
3311
3314
// 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);
3314
3317
}
3315
3318
3316
3319
// 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,
3319
3322
3320
3323
// Loop back through the sequence and validate elements we might have skipped
3321
3324
// 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 )
3324
3327
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
- }
3334
3328
uint64_t ExpectedVal =
3335
3329
(int64_t)(Idx * (uint64_t)*SeqStepNum) / *SeqStepDenom;
3336
- int64_t Addend = SignExtend64(Val - ExpectedVal, EltSizeInBits);
3330
+ int64_t Addend = SignExtend64(*Elt - ExpectedVal, EltSizeInBits);
3337
3331
if (!SeqAddend)
3338
3332
SeqAddend = Addend;
3339
3333
else if (Addend != SeqAddend)
0 commit comments