@@ -3240,15 +3240,16 @@ static std::optional<uint64_t> getExactInteger(const APFloat &APF,
3240
3240
// Note that this method will also match potentially unappealing index
3241
3241
// sequences, like <i32 0, i32 50939494>, however it is left to the caller to
3242
3242
// determine whether this is worth generating code for.
3243
- static std::optional<VIDSequence> isSimpleVIDSequence(SDValue Op) {
3243
+ static std::optional<VIDSequence> isSimpleVIDSequence(SDValue Op,
3244
+ unsigned EltSizeInBits) {
3244
3245
unsigned NumElts = Op.getNumOperands();
3245
3246
assert(Op.getOpcode() == ISD::BUILD_VECTOR && "Unexpected BUILD_VECTOR");
3246
3247
bool IsInteger = Op.getValueType().isInteger();
3247
3248
3248
3249
std::optional<unsigned> SeqStepDenom;
3249
3250
std::optional<int64_t> SeqStepNum, SeqAddend;
3250
3251
std::optional<std::pair<uint64_t, unsigned>> PrevElt;
3251
- unsigned EltSizeInBits = Op.getValueType().getScalarSizeInBits();
3252
+ assert( EltSizeInBits > = Op.getValueType().getScalarSizeInBits() );
3252
3253
for (unsigned Idx = 0; Idx < NumElts; Idx++) {
3253
3254
// Assume undef elements match the sequence; we just have to be careful
3254
3255
// when interpolating across them.
@@ -3261,14 +3262,14 @@ static std::optional<VIDSequence> isSimpleVIDSequence(SDValue Op) {
3261
3262
if (!isa<ConstantSDNode>(Op.getOperand(Idx)))
3262
3263
return std::nullopt;
3263
3264
Val = Op.getConstantOperandVal(Idx) &
3264
- maskTrailingOnes<uint64_t>(EltSizeInBits );
3265
+ maskTrailingOnes<uint64_t>(Op.getScalarValueSizeInBits() );
3265
3266
} else {
3266
3267
// The BUILD_VECTOR must be all constants.
3267
3268
if (!isa<ConstantFPSDNode>(Op.getOperand(Idx)))
3268
3269
return std::nullopt;
3269
3270
if (auto ExactInteger = getExactInteger(
3270
3271
cast<ConstantFPSDNode>(Op.getOperand(Idx))->getValueAPF(),
3271
- EltSizeInBits ))
3272
+ Op.getScalarValueSizeInBits() ))
3272
3273
Val = *ExactInteger;
3273
3274
else
3274
3275
return std::nullopt;
@@ -3324,11 +3325,11 @@ static std::optional<VIDSequence> isSimpleVIDSequence(SDValue Op) {
3324
3325
uint64_t Val;
3325
3326
if (IsInteger) {
3326
3327
Val = Op.getConstantOperandVal(Idx) &
3327
- maskTrailingOnes<uint64_t>(EltSizeInBits );
3328
+ maskTrailingOnes<uint64_t>(Op.getScalarValueSizeInBits() );
3328
3329
} else {
3329
3330
Val = *getExactInteger(
3330
3331
cast<ConstantFPSDNode>(Op.getOperand(Idx))->getValueAPF(),
3331
- EltSizeInBits );
3332
+ Op.getScalarValueSizeInBits() );
3332
3333
}
3333
3334
uint64_t ExpectedVal =
3334
3335
(int64_t)(Idx * (uint64_t)*SeqStepNum) / *SeqStepDenom;
@@ -3598,7 +3599,7 @@ static SDValue lowerBuildVectorOfConstants(SDValue Op, SelectionDAG &DAG,
3598
3599
// Try and match index sequences, which we can lower to the vid instruction
3599
3600
// with optional modifications. An all-undef vector is matched by
3600
3601
// getSplatValue, above.
3601
- if (auto SimpleVID = isSimpleVIDSequence(Op)) {
3602
+ if (auto SimpleVID = isSimpleVIDSequence(Op, Op.getScalarValueSizeInBits() )) {
3602
3603
int64_t StepNumerator = SimpleVID->StepNumerator;
3603
3604
unsigned StepDenominator = SimpleVID->StepDenominator;
3604
3605
int64_t Addend = SimpleVID->Addend;
@@ -15978,7 +15979,10 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
15978
15979
15979
15980
if (Index.getOpcode() == ISD::BUILD_VECTOR &&
15980
15981
MGN->getExtensionType() == ISD::NON_EXTLOAD && isTypeLegal(VT)) {
15981
- if (std::optional<VIDSequence> SimpleVID = isSimpleVIDSequence(Index);
15982
+ // The sequence will be XLenVT, not the type of Index. Tell
15983
+ // isSimpleVIDSequence this so we avoid overflow.
15984
+ if (std::optional<VIDSequence> SimpleVID =
15985
+ isSimpleVIDSequence(Index, Subtarget.getXLen());
15982
15986
SimpleVID && SimpleVID->StepDenominator == 1) {
15983
15987
const int64_t StepNumerator = SimpleVID->StepNumerator;
15984
15988
const int64_t Addend = SimpleVID->Addend;
0 commit comments