Skip to content

Commit 35a8d38

Browse files
committed
[RISCV][IA] Check nuw on multiply when analyzing EVL
If we're checking to see if a number is a multiple of a small constant, we need to be sure the multiply doesn't overflow for the mul logic to hold. The VL is a unsigned number, so we care about unsigned overflow. Once we've proven a number of a multiple, we can also use an exact udiv as we know we're not discarding any bits. This fixes what is technically a miscompile with EVL vectorization, but I doubt we'd ever have seen it in practice since most EVLs are going to much less than UINT_MAX.
1 parent 9912ccb commit 35a8d38

File tree

2 files changed

+36
-148
lines changed

2 files changed

+36
-148
lines changed

llvm/lib/Target/RISCV/RISCVInterleavedAccess.cpp

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ static bool isMultipleOfN(const Value *V, const DataLayout &DL, unsigned N) {
244244
// Right now we're only recognizing the simplest pattern.
245245
uint64_t C;
246246
if (match(V, m_CombineOr(m_ConstantInt(C),
247-
m_c_Mul(m_Value(), m_ConstantInt(C)))) &&
247+
m_NUWMul(m_Value(), m_ConstantInt(C)))) &&
248248
C && C % N == 0)
249249
return true;
250250

@@ -296,10 +296,8 @@ bool RISCVTargetLowering::lowerDeinterleaveIntrinsicToLoad(
296296
if (!isMultipleOfN(WideEVL, Load->getDataLayout(), Factor))
297297
return false;
298298

299-
VL = Builder.CreateZExt(
300-
Builder.CreateUDiv(WideEVL,
301-
ConstantInt::get(WideEVL->getType(), Factor)),
302-
XLenTy);
299+
auto *FactorC = ConstantInt::get(WideEVL->getType(), Factor);
300+
VL = Builder.CreateZExt(Builder.CreateExactUDiv(WideEVL, FactorC), XLenTy);
303301
}
304302

305303
Type *PtrTy = Ptr->getType();
@@ -465,9 +463,9 @@ bool RISCVTargetLowering::lowerInterleavedVPLoad(
465463

466464
auto *PtrTy = Load->getArgOperand(0)->getType();
467465
auto *XLenTy = Type::getIntNTy(Load->getContext(), Subtarget.getXLen());
468-
Value *EVL = Builder.CreateZExt(
469-
Builder.CreateUDiv(WideEVL, ConstantInt::get(WideEVL->getType(), Factor)),
470-
XLenTy);
466+
auto *FactorC = ConstantInt::get(WideEVL->getType(), Factor);
467+
Value *EVL =
468+
Builder.CreateZExt(Builder.CreateExactUDiv(WideEVL, FactorC), XLenTy);
471469

472470
Value *Return = nullptr;
473471
if (isa<FixedVectorType>(VTy)) {
@@ -572,9 +570,9 @@ bool RISCVTargetLowering::lowerInterleavedVPStore(
572570

573571
auto *PtrTy = Store->getArgOperand(1)->getType();
574572
auto *XLenTy = Type::getIntNTy(Store->getContext(), Subtarget.getXLen());
575-
Value *EVL = Builder.CreateZExt(
576-
Builder.CreateUDiv(WideEVL, ConstantInt::get(WideEVL->getType(), Factor)),
577-
XLenTy);
573+
auto *FactorC = ConstantInt::get(WideEVL->getType(), Factor);
574+
Value *EVL =
575+
Builder.CreateZExt(Builder.CreateExactUDiv(WideEVL, FactorC), XLenTy);
578576

579577
if (isa<FixedVectorType>(VTy)) {
580578
SmallVector<Value *, 8> Operands(InterleaveOperands);

0 commit comments

Comments
 (0)