Skip to content

Commit b361885

Browse files
authored
[RISCV][IA] Check nuw on multiply when analyzing EVL (#149205)
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 34951f7 commit b361885

File tree

2 files changed

+38
-152
lines changed

2 files changed

+38
-152
lines changed

llvm/lib/Target/RISCV/RISCVInterleavedAccess.cpp

Lines changed: 11 additions & 15 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();
@@ -387,10 +385,8 @@ bool RISCVTargetLowering::lowerInterleaveIntrinsicToStore(
387385
if (!isMultipleOfN(WideEVL, DL, Factor))
388386
return false;
389387

390-
VL = Builder.CreateZExt(
391-
Builder.CreateUDiv(WideEVL,
392-
ConstantInt::get(WideEVL->getType(), Factor)),
393-
XLenTy);
388+
auto *FactorC = ConstantInt::get(WideEVL->getType(), Factor);
389+
VL = Builder.CreateZExt(Builder.CreateExactUDiv(WideEVL, FactorC), XLenTy);
394390
}
395391
Type *PtrTy = Ptr->getType();
396392
unsigned AS = Ptr->getType()->getPointerAddressSpace();
@@ -489,9 +485,9 @@ bool RISCVTargetLowering::lowerInterleavedVPLoad(
489485

490486
auto *PtrTy = Load->getArgOperand(0)->getType();
491487
auto *XLenTy = Type::getIntNTy(Load->getContext(), Subtarget.getXLen());
492-
Value *EVL = Builder.CreateZExt(
493-
Builder.CreateUDiv(WideEVL, ConstantInt::get(WideEVL->getType(), Factor)),
494-
XLenTy);
488+
auto *FactorC = ConstantInt::get(WideEVL->getType(), Factor);
489+
Value *EVL =
490+
Builder.CreateZExt(Builder.CreateExactUDiv(WideEVL, FactorC), XLenTy);
495491

496492
Value *Return = nullptr;
497493
if (isa<FixedVectorType>(VTy)) {
@@ -596,9 +592,9 @@ bool RISCVTargetLowering::lowerInterleavedVPStore(
596592

597593
auto *PtrTy = Store->getArgOperand(1)->getType();
598594
auto *XLenTy = Type::getIntNTy(Store->getContext(), Subtarget.getXLen());
599-
Value *EVL = Builder.CreateZExt(
600-
Builder.CreateUDiv(WideEVL, ConstantInt::get(WideEVL->getType(), Factor)),
601-
XLenTy);
595+
auto *FactorC = ConstantInt::get(WideEVL->getType(), Factor);
596+
Value *EVL =
597+
Builder.CreateZExt(Builder.CreateExactUDiv(WideEVL, FactorC), XLenTy);
602598

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

0 commit comments

Comments
 (0)