@@ -3192,15 +3192,16 @@ static std::optional<uint64_t> getExactInteger(const APFloat &APF,
3192
3192
// Note that this method will also match potentially unappealing index
3193
3193
// sequences, like <i32 0, i32 50939494>, however it is left to the caller to
3194
3194
// determine whether this is worth generating code for.
3195
- static std::optional<VIDSequence> isSimpleVIDSequence(SDValue Op) {
3195
+ static std::optional<VIDSequence> isSimpleVIDSequence(SDValue Op,
3196
+ unsigned EltSizeInBits) {
3196
3197
unsigned NumElts = Op.getNumOperands();
3197
3198
assert(Op.getOpcode() == ISD::BUILD_VECTOR && "Unexpected BUILD_VECTOR");
3198
3199
bool IsInteger = Op.getValueType().isInteger();
3199
3200
3200
3201
std::optional<unsigned> SeqStepDenom;
3201
3202
std::optional<int64_t> SeqStepNum, SeqAddend;
3202
3203
std::optional<std::pair<uint64_t, unsigned>> PrevElt;
3203
- unsigned EltSizeInBits = Op.getValueType().getScalarSizeInBits();
3204
+ assert( EltSizeInBits > = Op.getValueType().getScalarSizeInBits() );
3204
3205
for (unsigned Idx = 0; Idx < NumElts; Idx++) {
3205
3206
// Assume undef elements match the sequence; we just have to be careful
3206
3207
// when interpolating across them.
@@ -3213,14 +3214,14 @@ static std::optional<VIDSequence> isSimpleVIDSequence(SDValue Op) {
3213
3214
if (!isa<ConstantSDNode>(Op.getOperand(Idx)))
3214
3215
return std::nullopt;
3215
3216
Val = Op.getConstantOperandVal(Idx) &
3216
- maskTrailingOnes<uint64_t>(EltSizeInBits );
3217
+ maskTrailingOnes<uint64_t>(Op.getScalarValueSizeInBits() );
3217
3218
} else {
3218
3219
// The BUILD_VECTOR must be all constants.
3219
3220
if (!isa<ConstantFPSDNode>(Op.getOperand(Idx)))
3220
3221
return std::nullopt;
3221
3222
if (auto ExactInteger = getExactInteger(
3222
3223
cast<ConstantFPSDNode>(Op.getOperand(Idx))->getValueAPF(),
3223
- EltSizeInBits ))
3224
+ Op.getScalarValueSizeInBits() ))
3224
3225
Val = *ExactInteger;
3225
3226
else
3226
3227
return std::nullopt;
@@ -3276,11 +3277,11 @@ static std::optional<VIDSequence> isSimpleVIDSequence(SDValue Op) {
3276
3277
uint64_t Val;
3277
3278
if (IsInteger) {
3278
3279
Val = Op.getConstantOperandVal(Idx) &
3279
- maskTrailingOnes<uint64_t>(EltSizeInBits );
3280
+ maskTrailingOnes<uint64_t>(Op.getScalarValueSizeInBits() );
3280
3281
} else {
3281
3282
Val = *getExactInteger(
3282
3283
cast<ConstantFPSDNode>(Op.getOperand(Idx))->getValueAPF(),
3283
- EltSizeInBits );
3284
+ Op.getScalarValueSizeInBits() );
3284
3285
}
3285
3286
uint64_t ExpectedVal =
3286
3287
(int64_t)(Idx * (uint64_t)*SeqStepNum) / *SeqStepDenom;
@@ -3550,7 +3551,7 @@ static SDValue lowerBuildVectorOfConstants(SDValue Op, SelectionDAG &DAG,
3550
3551
// Try and match index sequences, which we can lower to the vid instruction
3551
3552
// with optional modifications. An all-undef vector is matched by
3552
3553
// getSplatValue, above.
3553
- if (auto SimpleVID = isSimpleVIDSequence(Op)) {
3554
+ if (auto SimpleVID = isSimpleVIDSequence(Op, Op.getScalarValueSizeInBits() )) {
3554
3555
int64_t StepNumerator = SimpleVID->StepNumerator;
3555
3556
unsigned StepDenominator = SimpleVID->StepDenominator;
3556
3557
int64_t Addend = SimpleVID->Addend;
@@ -15562,7 +15563,10 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
15562
15563
15563
15564
if (Index.getOpcode() == ISD::BUILD_VECTOR &&
15564
15565
MGN->getExtensionType() == ISD::NON_EXTLOAD && isTypeLegal(VT)) {
15565
- if (std::optional<VIDSequence> SimpleVID = isSimpleVIDSequence(Index);
15566
+ // The sequence will be XLenVT, not the type of Index. Tell
15567
+ // isSimpleVIDSequence this so we avoid overflow.
15568
+ if (std::optional<VIDSequence> SimpleVID =
15569
+ isSimpleVIDSequence(Index, Subtarget.getXLen());
15566
15570
SimpleVID && SimpleVID->StepDenominator == 1) {
15567
15571
const int64_t StepNumerator = SimpleVID->StepNumerator;
15568
15572
const int64_t Addend = SimpleVID->Addend;
0 commit comments