[llvm] [VPlan] Always set flags for overflowing ops etc via VPIRFlags. (PR #179138)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 2 04:30:05 PST 2026
https://github.com/fhahn updated https://github.com/llvm/llvm-project/pull/179138
>From 8297d200698fc367841fdb36b040fb092202bb91 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Fri, 30 Jan 2026 09:12:02 +0000
Subject: [PATCH 1/2] [VPlan] Always set flags for overflowing ops etc via
VPIRFlags.
---
.../Vectorize/LoopVectorizationPlanner.h | 38 ++++++--
.../Transforms/Vectorize/LoopVectorize.cpp | 2 +-
llvm/lib/Transforms/Vectorize/VPlan.h | 11 +++
.../Vectorize/VPlanConstruction.cpp | 25 +++---
.../lib/Transforms/Vectorize/VPlanRecipes.cpp | 63 ++++++++++++++
llvm/lib/Transforms/Vectorize/VPlanSLP.cpp | 5 +-
.../Transforms/Vectorize/VPlanTransforms.cpp | 87 +++++++++----------
llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp | 24 +++--
.../Transforms/Vectorize/VPlanTest.cpp | 67 ++++++++++----
.../Vectorize/VPlanVerifierTest.cpp | 36 ++++++--
10 files changed, 250 insertions(+), 108 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h
index 44d4d92d4a7e2..14a18c856cbd0 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h
@@ -211,6 +211,22 @@ class VPBuilder {
VPRecipeWithIRFlags::DisjointFlagsTy(false), {}, DL, Name));
}
+ VPInstruction *
+ createAdd(VPValue *LHS, VPValue *RHS, DebugLoc DL = DebugLoc::getUnknown(),
+ const Twine &Name = "",
+ VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false}) {
+ return createOverflowingOp(Instruction::Add, {LHS, RHS}, WrapFlags, DL,
+ Name);
+ }
+
+ VPInstruction *
+ createSub(VPValue *LHS, VPValue *RHS, DebugLoc DL = DebugLoc::getUnknown(),
+ const Twine &Name = "",
+ VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false}) {
+ return createOverflowingOp(Instruction::Sub, {LHS, RHS}, WrapFlags, DL,
+ Name);
+ }
+
VPInstruction *createLogicalAnd(VPValue *LHS, VPValue *RHS,
DebugLoc DL = DebugLoc::getUnknown(),
const Twine &Name = "") {
@@ -247,7 +263,8 @@ class VPBuilder {
assert(Pred >= CmpInst::FIRST_FCMP_PREDICATE &&
Pred <= CmpInst::LAST_FCMP_PREDICATE && "invalid predicate");
return tryInsertInstruction(
- new VPInstruction(Instruction::FCmp, {A, B}, Pred, {}, DL, Name));
+ new VPInstruction(Instruction::FCmp, {A, B},
+ VPIRFlags(Pred, FastMathFlags()), {}, DL, Name));
}
VPInstruction *createPtrAdd(VPValue *Ptr, VPValue *Offset,
@@ -305,7 +322,15 @@ class VPBuilder {
VPInstruction *createScalarCast(Instruction::CastOps Opcode, VPValue *Op,
Type *ResultTy, DebugLoc DL,
- const VPIRFlags &Flags = {},
+ const VPIRMetadata &Metadata = {}) {
+ return tryInsertInstruction(new VPInstructionWithType(
+ Opcode, Op, ResultTy, VPIRFlags::getDefaultFlags(Opcode), Metadata,
+ DL));
+ }
+
+ VPInstruction *createScalarCast(Instruction::CastOps Opcode, VPValue *Op,
+ Type *ResultTy, DebugLoc DL,
+ const VPIRFlags &Flags,
const VPIRMetadata &Metadata = {}) {
return tryInsertInstruction(
new VPInstructionWithType(Opcode, Op, ResultTy, Flags, Metadata, DL));
@@ -335,13 +360,8 @@ class VPBuilder {
VPWidenCastRecipe *createWidenCast(Instruction::CastOps Opcode, VPValue *Op,
Type *ResultTy) {
- VPIRFlags Flags;
- if (Opcode == Instruction::Trunc)
- Flags = VPIRFlags::TruncFlagsTy(false, false);
- else if (Opcode == Instruction::ZExt)
- Flags = VPIRFlags::NonNegFlagsTy(false);
- return tryInsertInstruction(
- new VPWidenCastRecipe(Opcode, Op, ResultTy, nullptr, Flags));
+ return tryInsertInstruction(new VPWidenCastRecipe(
+ Opcode, Op, ResultTy, nullptr, VPIRFlags::getDefaultFlags(Opcode)));
}
VPScalarIVStepsRecipe *
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 383fc7bc50e72..92e67842e0c97 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -9163,7 +9163,7 @@ static SmallVector<Instruction *> preparePlanForEpilogueVectorLoop(
"the canonical IV should only be used by its increment or "
"ScalarIVSteps when resetting the start value");
VPBuilder Builder(Header, Header->getFirstNonPhi());
- VPInstruction *Add = Builder.createNaryOp(Instruction::Add, {IV, VPV});
+ VPInstruction *Add = Builder.createAdd(IV, VPV);
IV->replaceAllUsesWith(Add);
Add->setOperand(0, IV);
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index ae6988d86e194..ac3d987d17223 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -705,6 +705,7 @@ class VPIRFlags {
private:
struct ExactFlagsTy {
char IsExact : 1;
+ ExactFlagsTy(bool Exact) : IsExact(Exact) {}
};
struct FastMathFlagsTy {
char AllowReassoc : 1;
@@ -1015,9 +1016,17 @@ class VPIRFlags {
}
public:
+ /// Returns default flags for \p Opcode for opcodes that support it, asserts
+ /// otherwise. Opcodes not supporting default flags include compares and
+ /// ComputeReductionResult.
+ static VPIRFlags getDefaultFlags(unsigned Opcode);
+
#if !defined(NDEBUG)
/// Returns true if the set flags are valid for \p Opcode.
LLVM_ABI_FOR_TEST bool flagsValidForOpcode(unsigned Opcode) const;
+
+ /// Returns true if \p Opcode has its required flags set.
+ LLVM_ABI_FOR_TEST bool hasRequiredFlagsForOpcode(unsigned Opcode) const;
#endif
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
@@ -1701,6 +1710,8 @@ class VPWidenCastRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
VPIRMetadata(Metadata), Opcode(Opcode), ResultTy(ResultTy) {
assert(flagsValidForOpcode(Opcode) &&
"Set flags not supported for the provided opcode");
+ assert(hasRequiredFlagsForOpcode(Opcode) &&
+ "Opcode requires specific flags to be set");
setUnderlyingValue(CI);
}
diff --git a/llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp b/llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp
index 4e7b1bbab5227..ec4c0e0321e66 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp
@@ -476,9 +476,8 @@ static void addCanonicalIVRecipes(VPlan &Plan, VPBasicBlock *HeaderVPBB,
// Add a VPInstruction to increment the scalar canonical IV by VF * UF.
// Initially the induction increment is guaranteed to not wrap, but that may
// change later, e.g. when tail-folding, when the flags need to be dropped.
- auto *CanonicalIVIncrement = Builder.createOverflowingOp(
- Instruction::Add, {CanonicalIVPHI, &Plan.getVFxUF()}, {true, false}, DL,
- "index.next");
+ auto *CanonicalIVIncrement = Builder.createAdd(
+ CanonicalIVPHI, &Plan.getVFxUF(), DL, "index.next", {true, false});
CanonicalIVPHI->addOperand(CanonicalIVIncrement);
// Add the BranchOnCount VPInstruction to the latch.
@@ -813,11 +812,10 @@ void VPlanTransforms::createInLoopReductionRecipes(
match(CurrentLink, m_Sub(m_VPValue(), m_VPValue()))) {
Type *PhiTy = TypeInfo.inferScalarType(PhiR);
auto *Zero = Plan.getConstantInt(PhiTy, 0);
- auto *Sub = new VPInstruction(Instruction::Sub,
- {Zero, CurrentLink->getOperand(1)}, {},
- {}, CurrentLinkI->getDebugLoc());
+ VPBuilder Builder(LinkVPBB, CurrentLink->getIterator());
+ auto *Sub = Builder.createSub(Zero, CurrentLink->getOperand(1),
+ CurrentLinkI->getDebugLoc());
Sub->setUnderlyingValue(CurrentLinkI);
- LinkVPBB->insert(Sub, CurrentLink->getIterator());
VecOp = Sub;
} else {
// Index of the first operand which holds a non-mask vector operand.
@@ -1061,9 +1059,8 @@ void VPlanTransforms::addMinimumIterationCheck(
// Get the maximum unsigned value for the type.
VPValue *MaxUIntTripCount =
Plan.getConstantInt(cast<IntegerType>(TripCountTy)->getMask());
- VPValue *DistanceToMax = Builder.createNaryOp(
- Instruction::Sub, {MaxUIntTripCount, TripCountVPV},
- DebugLoc::getUnknown());
+ VPValue *DistanceToMax =
+ Builder.createSub(MaxUIntTripCount, TripCountVPV);
// Don't execute the vector loop if (UMax - n) < (VF * UF).
// FIXME: Should only check VF * UF, but currently checks Step=max(VF*UF,
@@ -1111,9 +1108,8 @@ void VPlanTransforms::addMinimumVectorEpilogueIterationCheck(
VPBuilder Builder(cast<VPBasicBlock>(Plan.getEntry()));
VPValue *VFxUF = Builder.createExpandSCEV(SE.getElementCount(
TripCount->getType(), (EpilogueVF * EpilogueUF), SCEV::FlagNUW));
- VPValue *Count = Builder.createNaryOp(
- Instruction::Sub, {TC, Plan.getOrAddLiveIn(VectorTripCount)},
- DebugLoc::getUnknown(), "n.vec.remaining");
+ VPValue *Count = Builder.createSub(TC, Plan.getOrAddLiveIn(VectorTripCount),
+ DebugLoc::getUnknown(), "n.vec.remaining");
// Generate code to check if the loop's trip count is less than VF * UF of
// the vector epilogue loop.
@@ -1262,8 +1258,7 @@ bool VPlanTransforms::handleMaxMinNumReductions(VPlan &Plan) {
auto *IsLatchExitTaken = LatchBuilder.createICmp(
CmpInst::ICMP_EQ, LatchExitingBranch->getOperand(0),
LatchExitingBranch->getOperand(1));
- auto *AnyExitTaken = LatchBuilder.createNaryOp(
- Instruction::Or, {AnyNaNLane, IsLatchExitTaken});
+ auto *AnyExitTaken = LatchBuilder.createOr(AnyNaNLane, IsLatchExitTaken);
LatchBuilder.createNaryOp(VPInstruction::BranchOnCond, AnyExitTaken);
LatchExitingBranch->eraseFromParent();
diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index 6fb4225f32800..d99edeb7bfbe5 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -425,6 +425,8 @@ VPInstruction::VPInstruction(unsigned Opcode, ArrayRef<VPValue *> Operands,
VPIRMetadata(MD), Opcode(Opcode), Name(Name.str()) {
assert(flagsValidForOpcode(getOpcode()) &&
"Set flags not supported for the provided opcode");
+ assert(hasRequiredFlagsForOpcode(getOpcode()) &&
+ "Opcode requires specific flags to be set");
assert((getNumOperandsForOpcode(Opcode) == -1u ||
getNumOperandsForOpcode(Opcode) == getNumOperands()) &&
"number of operands does not match opcode");
@@ -1275,6 +1277,8 @@ void VPInstruction::execute(VPTransformState &State) {
IRBuilderBase::FastMathFlagGuard FMFGuard(State.Builder);
assert(flagsValidForOpcode(getOpcode()) &&
"Set flags not supported for the provided opcode");
+ assert(hasRequiredFlagsForOpcode(getOpcode()) &&
+ "Opcode requires specific flags to be set");
if (hasFastMathFlags())
State.Builder.setFastMathFlags(getFastMathFlags());
Value *GeneratedValue = generate(State);
@@ -2052,6 +2056,52 @@ VPIRFlags::FastMathFlagsTy::FastMathFlagsTy(const FastMathFlags &FMF) {
ApproxFunc = FMF.approxFunc();
}
+VPIRFlags VPIRFlags::getDefaultFlags(unsigned Opcode) {
+ switch (Opcode) {
+ case Instruction::Add:
+ case Instruction::Sub:
+ case Instruction::Mul:
+ case Instruction::Shl:
+ case VPInstruction::CanonicalIVIncrementForPart:
+ return WrapFlagsTy(false, false);
+ case Instruction::Trunc:
+ return TruncFlagsTy(false, false);
+ case Instruction::Or:
+ return DisjointFlagsTy(false);
+ case Instruction::AShr:
+ case Instruction::LShr:
+ case Instruction::UDiv:
+ case Instruction::SDiv: {
+ VPIRFlags F;
+ F.OpType = OperationType::PossiblyExactOp;
+ F.ExactFlags = ExactFlagsTy(false);
+ return F;
+ }
+ case Instruction::GetElementPtr:
+ case VPInstruction::PtrAdd:
+ case VPInstruction::WidePtrAdd:
+ return GEPNoWrapFlags::none();
+ case Instruction::ZExt:
+ case Instruction::UIToFP:
+ return NonNegFlagsTy(false);
+ case Instruction::FAdd:
+ case Instruction::FSub:
+ case Instruction::FMul:
+ case Instruction::FDiv:
+ case Instruction::FRem:
+ case Instruction::FNeg:
+ case Instruction::FPExt:
+ case Instruction::FPTrunc:
+ return FastMathFlags();
+ case Instruction::ICmp:
+ case Instruction::FCmp:
+ case VPInstruction::ComputeReductionResult:
+ llvm_unreachable("opcode requires explicit flags");
+ default:
+ return VPIRFlags();
+ }
+}
+
#if !defined(NDEBUG)
bool VPIRFlags::flagsValidForOpcode(unsigned Opcode) const {
switch (OpType) {
@@ -2091,6 +2141,19 @@ bool VPIRFlags::flagsValidForOpcode(unsigned Opcode) const {
}
llvm_unreachable("Unknown OperationType enum");
}
+
+bool VPIRFlags::hasRequiredFlagsForOpcode(unsigned Opcode) const {
+ // Handle opcodes without default flags.
+ if (Opcode == Instruction::ICmp)
+ return OpType == OperationType::Cmp;
+ if (Opcode == Instruction::FCmp)
+ return OpType == OperationType::FCmp;
+ if (Opcode == VPInstruction::ComputeReductionResult)
+ return OpType == OperationType::ReductionOp;
+
+ OperationType Required = getDefaultFlags(Opcode).OpType;
+ return Required == OperationType::Other || Required == OpType;
+}
#endif
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
diff --git a/llvm/lib/Transforms/Vectorize/VPlanSLP.cpp b/llvm/lib/Transforms/Vectorize/VPlanSLP.cpp
index fd1176d4f5541..fb7e1dd5b1e4e 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanSLP.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanSLP.cpp
@@ -517,8 +517,9 @@ VPInstruction *VPlanSlp::buildGraph(ArrayRef<VPValue *> Values) {
assert(CombinedOperands.size() > 0 && "Need more some operands");
auto *Inst = cast<VPInstruction>(Values[0])->getUnderlyingInstr();
- auto *VPI =
- new VPInstruction(Opcode, CombinedOperands, {}, {}, Inst->getDebugLoc());
+ auto *VPI = new VPInstruction(Opcode, CombinedOperands,
+ VPIRFlags::getDefaultFlags(Opcode), {},
+ Inst->getDebugLoc());
LLVM_DEBUG(dbgs() << "Create VPInstruction " << *VPI << " " << Values[0]
<< "\n");
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index 2655b539ee7ff..b39d3a1a55ed6 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -967,15 +967,14 @@ static VPValue *optimizeEarlyExitInductionUser(VPlan &Plan,
Type *FirstActiveLaneType = TypeInfo.inferScalarType(FirstActiveLane);
FirstActiveLane = B.createScalarZExtOrTrunc(FirstActiveLane, CanonicalIVType,
FirstActiveLaneType, DL);
- VPValue *EndValue =
- B.createNaryOp(Instruction::Add, {CanonicalIV, FirstActiveLane}, DL);
+ VPValue *EndValue = B.createAdd(CanonicalIV, FirstActiveLane, DL);
// `getOptimizableIVOf()` always returns the pre-incremented IV, so if it
// changed it means the exit is using the incremented value, so we need to
// add the step.
if (Incoming != WideIV) {
VPValue *One = Plan.getConstantInt(CanonicalIVType, 1);
- EndValue = B.createNaryOp(Instruction::Add, {EndValue, One}, DL);
+ EndValue = B.createAdd(EndValue, One, DL);
}
if (!WideIntOrFp || !WideIntOrFp->isCanonical()) {
@@ -1017,13 +1016,11 @@ static VPValue *optimizeLatchExitInductionUser(
VPValue *Step = WideIV->getStepValue();
Type *ScalarTy = TypeInfo.inferScalarType(WideIV);
if (ScalarTy->isIntegerTy())
- return B.createNaryOp(Instruction::Sub, {EndValue, Step},
- DebugLoc::getUnknown(), "ind.escape");
+ return B.createSub(EndValue, Step, DebugLoc::getUnknown(), "ind.escape");
if (ScalarTy->isPointerTy()) {
Type *StepTy = TypeInfo.inferScalarType(Step);
auto *Zero = Plan.getConstantInt(StepTy, 0);
- return B.createPtrAdd(EndValue,
- B.createNaryOp(Instruction::Sub, {Zero, Step}),
+ return B.createPtrAdd(EndValue, B.createSub(Zero, Step),
DebugLoc::getUnknown(), "ind.escape");
}
if (ScalarTy->isFloatingPointTy()) {
@@ -1351,8 +1348,8 @@ static void simplifyRecipe(VPSingleDefRecipe *Def, VPTypeAnalysis &TypeInfo) {
APC->isPowerOf2())
return Def->replaceAllUsesWith(Builder.createNaryOp(
Instruction::LShr,
- {A, Plan->getConstantInt(APC->getBitWidth(), APC->exactLogBase2())}, {},
- Def->getDebugLoc()));
+ {A, Plan->getConstantInt(APC->getBitWidth(), APC->exactLogBase2())},
+ *cast<VPRecipeWithIRFlags>(Def), Def->getDebugLoc()));
if (match(Def, m_Not(m_VPValue(A)))) {
if (match(A, m_Not(m_VPValue(A))))
@@ -1868,7 +1865,8 @@ static bool optimizeVectorInductionWidthForTCAndVFUF(VPlan &Plan,
WideIV->setStepValue(NewStep);
auto *NewBTC = new VPWidenCastRecipe(
- Instruction::Trunc, Plan.getOrCreateBackedgeTakenCount(), NewIVTy);
+ Instruction::Trunc, Plan.getOrCreateBackedgeTakenCount(), NewIVTy,
+ nullptr, VPIRFlags::getDefaultFlags(Instruction::Trunc));
Plan.getVectorPreheader()->appendRecipe(NewBTC);
auto *Cmp = cast<VPInstruction>(WideIV->getSingleUser());
Cmp->setOperand(1, NewBTC);
@@ -2375,8 +2373,7 @@ bool VPlanTransforms::adjustFixedOrderRecurrences(VPlan &Plan,
Type *I64Ty = Type::getInt64Ty(Plan.getContext());
VPValue *Zero = Plan.getOrAddLiveIn(ConstantInt::get(I64Ty, 0));
VPValue *One = Plan.getOrAddLiveIn(ConstantInt::get(I64Ty, 1));
- VPValue *PenultimateIndex =
- B.createNaryOp(Instruction::Sub, {LastActiveLane, One});
+ VPValue *PenultimateIndex = B.createSub(LastActiveLane, One);
VPValue *PenultimateLastIter =
B.createNaryOp(VPInstruction::ExtractLane,
{PenultimateIndex, FOR->getBackedgeValue()});
@@ -2598,8 +2595,9 @@ void VPlanTransforms::truncateToMinimalBitwidths(
if (OldResSizeInBits != NewResSizeInBits &&
!match(&R, m_ICmp(m_VPValue(), m_VPValue()))) {
// Extend result to original width.
- auto *Ext =
- new VPWidenCastRecipe(Instruction::ZExt, ResultVPV, OldResTy);
+ auto *Ext = new VPWidenCastRecipe(
+ Instruction::ZExt, ResultVPV, OldResTy, nullptr,
+ VPIRFlags::getDefaultFlags(Instruction::ZExt));
Ext->insertAfter(&R);
ResultVPV->replaceAllUsesWith(Ext);
Ext->setOperand(0, ResultVPV);
@@ -3003,8 +3001,9 @@ static VPRecipeBase *optimizeMaskToEVL(VPValue *HeaderMask,
Type *Ty = TypeInfo.inferScalarType(CurRecipe.getVPSingleValue());
VPValue *ZExt =
VPBuilder(&CurRecipe).createScalarCast(Instruction::ZExt, &EVL, Ty, DL);
- return new VPInstruction(Instruction::Sub,
- {ZExt, Plan->getConstantInt(Ty, 1)}, {}, {}, DL);
+ return new VPInstruction(
+ Instruction::Sub, {ZExt, Plan->getConstantInt(Ty, 1)},
+ VPIRFlags::getDefaultFlags(Instruction::Sub), {}, DL);
}
return nullptr;
@@ -3228,16 +3227,15 @@ void VPlanTransforms::addExplicitVectorLength(
OpVPEVL = Builder.createScalarZExtOrTrunc(
OpVPEVL, CanIVTy, I32Ty, CanonicalIVIncrement->getDebugLoc());
- auto *NextEVLIV = Builder.createOverflowingOp(
- Instruction::Add, {OpVPEVL, EVLPhi},
+ auto *NextEVLIV = Builder.createAdd(
+ OpVPEVL, EVLPhi, CanonicalIVIncrement->getDebugLoc(), "index.evl.next",
{CanonicalIVIncrement->hasNoUnsignedWrap(),
- CanonicalIVIncrement->hasNoSignedWrap()},
- CanonicalIVIncrement->getDebugLoc(), "index.evl.next");
+ CanonicalIVIncrement->hasNoSignedWrap()});
EVLPhi->addOperand(NextEVLIV);
- VPValue *NextAVL = Builder.createOverflowingOp(
- Instruction::Sub, {AVLPhi, OpVPEVL}, {/*hasNUW=*/true, /*hasNSW=*/false},
- DebugLoc::getCompilerGenerated(), "avl.next");
+ VPValue *NextAVL =
+ Builder.createSub(AVLPhi, OpVPEVL, DebugLoc::getCompilerGenerated(),
+ "avl.next", {/*NUW=*/true, /*NSW=*/false});
AVLPhi->addOperand(NextAVL);
fixupVFUsersForEVL(Plan, *VPEVL);
@@ -3423,9 +3421,8 @@ void VPlanTransforms::dropPoisonGeneratingRecipes(
if (match(RecWithFlags, m_BinaryOr(m_VPValue(A), m_VPValue(B))) &&
RecWithFlags->isDisjoint()) {
VPBuilder Builder(RecWithFlags);
- VPInstruction *New = Builder.createOverflowingOp(
- Instruction::Add, {A, B}, {false, false},
- RecWithFlags->getDebugLoc());
+ VPInstruction *New =
+ Builder.createAdd(A, B, RecWithFlags->getDebugLoc());
New->setUnderlyingValue(RecWithFlags->getUnderlyingValue());
RecWithFlags->replaceAllUsesWith(New);
RecWithFlags->eraseFromParent();
@@ -3744,8 +3741,8 @@ static void expandVPWidenPointerInduction(VPWidenPointerInductionRecipe *R,
Type *StepTy = TypeInfo.inferScalarType(Step);
VPValue *Offset = Builder.createNaryOp(VPInstruction::StepVector, {}, StepTy);
Offset = Builder.createOverflowingOp(Instruction::Mul, {Offset, Step});
- VPValue *PtrAdd = Builder.createNaryOp(
- VPInstruction::WidePtrAdd, {ScalarPtrPhi, Offset}, DL, "vector.gep");
+ VPValue *PtrAdd =
+ Builder.createWidePtrAdd(ScalarPtrPhi, Offset, DL, "vector.gep");
R->replaceAllUsesWith(PtrAdd);
// Create the backedge value for the scalar pointer phi.
@@ -3888,9 +3885,9 @@ void VPlanTransforms::convertToConcreteRecipes(VPlan &Plan) {
// Subtract 1 to get the last active lane.
VPValue *One = Plan.getOrAddLiveIn(
ConstantInt::get(Type::getInt64Ty(Plan.getContext()), 1));
- VPValue *LastLane = Builder.createNaryOp(
- Instruction::Sub, {FirstInactiveLane, One},
- LastActiveL->getDebugLoc(), "last.active.lane");
+ VPValue *LastLane =
+ Builder.createSub(FirstInactiveLane, One,
+ LastActiveL->getDebugLoc(), "last.active.lane");
LastActiveL->replaceAllUsesWith(LastLane);
ToRemove.push_back(LastActiveL);
@@ -3931,11 +3928,15 @@ void VPlanTransforms::convertToConcreteRecipes(VPlan &Plan) {
}
VPIRFlags Flags;
- if (IVTy->isFloatingPointTy())
- Flags = {VPI->getFastMathFlags()};
+ unsigned MulOpc;
+ if (IVTy->isFloatingPointTy()) {
+ MulOpc = Instruction::FMul;
+ Flags = VPI->getFastMathFlags();
+ } else {
+ MulOpc = Instruction::Mul;
+ Flags = VPIRFlags::getDefaultFlags(MulOpc);
+ }
- unsigned MulOpc =
- IVTy->isFloatingPointTy() ? Instruction::FMul : Instruction::Mul;
VPInstruction *Mul = Builder.createNaryOp(
MulOpc, {VectorStep, ScalarStep}, Flags, R.getDebugLoc());
VectorStep = Mul;
@@ -4682,9 +4683,9 @@ void VPlanTransforms::materializeBackedgeTakenCount(VPlan &Plan,
VPBuilder Builder(VectorPH, VectorPH->begin());
auto *TCTy = VPTypeAnalysis(Plan).inferScalarType(Plan.getTripCount());
- auto *TCMO = Builder.createNaryOp(
- Instruction::Sub, {Plan.getTripCount(), Plan.getConstantInt(TCTy, 1)},
- DebugLoc::getCompilerGenerated(), "trip.count.minus.1");
+ auto *TCMO =
+ Builder.createSub(Plan.getTripCount(), Plan.getConstantInt(TCTy, 1),
+ DebugLoc::getCompilerGenerated(), "trip.count.minus.1");
BTC->replaceAllUsesWith(TCMO);
}
@@ -4805,10 +4806,8 @@ void VPlanTransforms::materializeVectorTripCount(VPlan &Plan,
// For scalable vectors the VF is not guaranteed to be a power of 2, but this
// is accounted for in emitIterationCountCheck that adds an overflow check.
if (TailByMasking) {
- TC = Builder.createNaryOp(
- Instruction::Add,
- {TC, Builder.createNaryOp(Instruction::Sub,
- {Step, Plan.getConstantInt(TCTy, 1)})},
+ TC = Builder.createAdd(
+ TC, Builder.createSub(Step, Plan.getConstantInt(TCTy, 1)),
DebugLoc::getCompilerGenerated(), "n.rnd.up");
}
@@ -4835,8 +4834,8 @@ void VPlanTransforms::materializeVectorTripCount(VPlan &Plan,
R = Builder.createSelect(IsZero, Step, R);
}
- VPValue *Res = Builder.createNaryOp(
- Instruction::Sub, {TC, R}, DebugLoc::getCompilerGenerated(), "n.vec");
+ VPValue *Res =
+ Builder.createSub(TC, R, DebugLoc::getCompilerGenerated(), "n.vec");
VectorTC.replaceAllUsesWith(Res);
}
diff --git a/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp b/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp
index 75b8164a33a7f..e065140019ee6 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp
@@ -210,22 +210,28 @@ void UnrollState::unrollWidenInductionByUF(
VPValue *Prev = IV;
Builder.setInsertPoint(IV->getParent(), InsertPtForPhi);
unsigned AddOpc;
- if (IVTy->isPointerTy())
+ VPIRFlags AddFlags;
+ if (IVTy->isPointerTy()) {
AddOpc = VPInstruction::WidePtrAdd;
- else if (IVTy->isFloatingPointTy())
+ AddFlags = GEPNoWrapFlags::none();
+ } else if (IVTy->isFloatingPointTy()) {
AddOpc = ID.getInductionOpcode();
- else
+ AddFlags = Flags; // FMF flags
+ } else {
AddOpc = Instruction::Add;
+ AddFlags = VPIRFlags::getDefaultFlags(AddOpc);
+ }
for (unsigned Part = 1; Part != UF; ++Part) {
std::string Name =
Part > 1 ? "step.add." + std::to_string(Part) : "step.add";
- VPInstruction *Add = Builder.createNaryOp(AddOpc,
- {
- Prev,
- VectorStep,
- },
- Flags, IV->getDebugLoc(), Name);
+ VPInstruction *Add =
+ Builder.createNaryOp(AddOpc,
+ {
+ Prev,
+ VectorStep,
+ },
+ AddFlags, IV->getDebugLoc(), Name);
ToSkip.insert(Add);
addRecipeForPart(IV, Add, Part);
Prev = Add;
diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
index 9b1e7c0af7c8c..13013794f3560 100644
--- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
@@ -136,7 +136,9 @@ TEST_F(VPInstructionTest, setOperand) {
IntegerType *Int32 = IntegerType::get(C, 32);
VPValue *VPV1 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 1));
VPValue *VPV2 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 2));
- VPInstruction *I1 = new VPInstruction(Instruction::Add, {VPV1, VPV2});
+ VPInstruction *I1 =
+ new VPInstruction(Instruction::Add, {VPV1, VPV2},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
EXPECT_EQ(1u, VPV1->getNumUsers());
EXPECT_EQ(I1, *VPV1->user_begin());
EXPECT_EQ(1u, VPV2->getNumUsers());
@@ -179,7 +181,9 @@ TEST_F(VPInstructionTest, replaceAllUsesWith) {
IntegerType *Int32 = IntegerType::get(C, 32);
VPValue *VPV1 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 1));
VPValue *VPV2 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 2));
- VPInstruction *I1 = new VPInstruction(Instruction::Add, {VPV1, VPV2});
+ VPInstruction *I1 =
+ new VPInstruction(Instruction::Add, {VPV1, VPV2},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
// Replace all uses of VPV1 with VPV3.
VPValue *VPV3 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 3));
@@ -210,7 +214,9 @@ TEST_F(VPInstructionTest, replaceAllUsesWith) {
EXPECT_EQ(0u, VPV2->getNumUsers());
EXPECT_EQ(0u, VPV3->getNumUsers());
- VPInstruction *I2 = new VPInstruction(Instruction::Add, {VPV1, VPV2});
+ VPInstruction *I2 =
+ new VPInstruction(Instruction::Add, {VPV1, VPV2},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
EXPECT_EQ(3u, VPV1->getNumUsers());
VPV1->replaceAllUsesWith(VPV3);
EXPECT_EQ(3u, VPV3->getNumUsers());
@@ -223,7 +229,9 @@ TEST_F(VPInstructionTest, releaseOperandsAtDeletion) {
IntegerType *Int32 = IntegerType::get(C, 32);
VPValue *VPV1 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 1));
VPValue *VPV2 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 1));
- VPInstruction *I1 = new VPInstruction(Instruction::Add, {VPV1, VPV2});
+ VPInstruction *I1 =
+ new VPInstruction(Instruction::Add, {VPV1, VPV2},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
EXPECT_EQ(1u, VPV1->getNumUsers());
EXPECT_EQ(I1, *VPV1->user_begin());
@@ -725,8 +733,12 @@ TEST_F(VPBasicBlockTest, print) {
VPValue *Val = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
VPBasicBlock *VPBB0 = Plan.getEntry();
- VPInstruction *I1 = new VPInstruction(Instruction::Add, {Val, Val});
- VPInstruction *I2 = new VPInstruction(Instruction::Sub, {I1, Val});
+ VPInstruction *I1 =
+ new VPInstruction(Instruction::Add, {Val, Val},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
+ VPInstruction *I2 =
+ new VPInstruction(Instruction::Sub, {I1, Val},
+ VPIRFlags::getDefaultFlags(Instruction::Sub));
VPInstruction *I3 = new VPInstruction(Instruction::Store, {I1, I2});
VPBasicBlock *VPBB1 = Plan.createVPBasicBlock("");
@@ -735,7 +747,8 @@ TEST_F(VPBasicBlockTest, print) {
VPBB1->appendRecipe(I3);
VPBB1->setName("bb1");
- VPInstruction *I4 = new VPInstruction(Instruction::Mul, {I2, I1});
+ VPInstruction *I4 = new VPInstruction(
+ Instruction::Mul, {I2, I1}, VPIRFlags::getDefaultFlags(Instruction::Mul));
VPInstruction *I5 = new VPInstruction(Instruction::Freeze, {I4});
VPBasicBlock *VPBB2 = Plan.createVPBasicBlock("");
VPBB2->appendRecipe(I4);
@@ -836,7 +849,9 @@ TEST_F(VPBasicBlockTest, printPlanWithVFsAndUFs) {
VPValue *Val = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
VPBasicBlock *VPBB0 = Plan.getEntry();
- VPInstruction *I1 = new VPInstruction(Instruction::Add, {Val, Val});
+ VPInstruction *I1 =
+ new VPInstruction(Instruction::Add, {Val, Val},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
VPBasicBlock *VPBB1 = Plan.createVPBasicBlock("");
VPBB1->appendRecipe(I1);
VPBB1->setName("bb1");
@@ -922,8 +937,12 @@ TEST_F(VPBasicBlockTest, cloneAndPrint) {
IntegerType *Int32 = IntegerType::get(C, 32);
VPValue *Val = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
- VPInstruction *I1 = new VPInstruction(Instruction::Add, {Val, Val});
- VPInstruction *I2 = new VPInstruction(Instruction::Sub, {I1, Val});
+ VPInstruction *I1 =
+ new VPInstruction(Instruction::Add, {Val, Val},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
+ VPInstruction *I2 =
+ new VPInstruction(Instruction::Sub, {I1, Val},
+ VPIRFlags::getDefaultFlags(Instruction::Sub));
VPInstruction *I3 = new VPInstruction(Instruction::Store, {I1, I2});
VPBasicBlock *VPBB1 = Plan.createVPBasicBlock("");
@@ -994,7 +1013,8 @@ TEST_F(VPRecipeTest, CastVPInstructionToVPUser) {
VPlan &Plan = getPlan();
VPValue *Op1 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
VPValue *Op2 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2));
- VPInstruction Recipe(Instruction::Add, {Op1, Op2});
+ VPInstruction Recipe(Instruction::Add, {Op1, Op2},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
checkVPRecipeCastImpl<VPInstruction, VPUser, VPIRMetadata>(&Recipe);
}
@@ -1067,7 +1087,8 @@ TEST_F(VPRecipeTest, CastVPWidenCastRecipeToVPUser) {
IntegerType *Int64 = IntegerType::get(C, 64);
auto *Cast = CastInst::CreateZExtOrBitCast(PoisonValue::get(Int32), Int64);
VPValue *Op1 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
- VPWidenCastRecipe Recipe(Instruction::ZExt, Op1, Int64, Cast);
+ VPWidenCastRecipe Recipe(Instruction::ZExt, Op1, Int64, Cast,
+ VPIRFlags::getDefaultFlags(Instruction::ZExt));
checkVPRecipeCastImpl<VPWidenCastRecipe, VPUser, VPIRMetadata>(&Recipe);
delete Cast;
@@ -1381,7 +1402,8 @@ TEST_F(VPRecipeTest, MayHaveSideEffectsAndMayReadWriteMemory) {
{
VPValue *Op1 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
VPValue *Op2 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2));
- VPInstruction VPInst(Instruction::Add, {Op1, Op2});
+ VPInstruction VPInst(Instruction::Add, {Op1, Op2},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
VPRecipeBase &Recipe = VPInst;
EXPECT_FALSE(Recipe.mayHaveSideEffects());
EXPECT_FALSE(Recipe.mayReadFromMemory());
@@ -1474,8 +1496,11 @@ TEST_F(VPRecipeTest, dumpRecipeUnnamedVPValuesInPlan) {
VPValue *ExtVPV2 = Plan.getOrAddLiveIn(AI);
Args.push_back(ExtVPV1);
Args.push_back(ExtVPV2);
- VPInstruction *I1 = new VPInstruction(Instruction::Add, {ExtVPV1, ExtVPV2});
- VPInstruction *I2 = new VPInstruction(Instruction::Mul, {I1, I1});
+ VPInstruction *I1 =
+ new VPInstruction(Instruction::Add, {ExtVPV1, ExtVPV2},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
+ VPInstruction *I2 = new VPInstruction(
+ Instruction::Mul, {I1, I1}, VPIRFlags::getDefaultFlags(Instruction::Mul));
VPBB1->appendRecipe(I1);
VPBB1->appendRecipe(I2);
@@ -1534,8 +1559,11 @@ TEST_F(VPRecipeTest, dumpRecipeUnnamedVPValuesNotInPlanOrBlock) {
VPValue *ExtVPV1 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 1));
VPValue *ExtVPV2 = getPlan().getOrAddLiveIn(AI);
- VPInstruction *I1 = new VPInstruction(Instruction::Add, {ExtVPV1, ExtVPV2});
- VPInstruction *I2 = new VPInstruction(Instruction::Mul, {I1, I1});
+ VPInstruction *I1 =
+ new VPInstruction(Instruction::Add, {ExtVPV1, ExtVPV2},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
+ VPInstruction *I2 = new VPInstruction(
+ Instruction::Mul, {I1, I1}, VPIRFlags::getDefaultFlags(Instruction::Mul));
// Check printing I1.
{
@@ -1642,8 +1670,9 @@ TEST(VPDoubleValueDefTest, traverseUseLists) {
VPDoubleValueDef DoubleValueDef({&Op0, &Op1});
// Create a new users of the defined values.
- VPInstruction I1(Instruction::Add, {DoubleValueDef.getVPValue(0),
- DoubleValueDef.getVPValue(1)});
+ VPInstruction I1(Instruction::Add,
+ {DoubleValueDef.getVPValue(0), DoubleValueDef.getVPValue(1)},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
VPInstruction I2(Instruction::Freeze, {DoubleValueDef.getVPValue(0)});
VPInstruction I3(Instruction::Freeze, {DoubleValueDef.getVPValue(1)});
diff --git a/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp
index 897c08b66563e..eeae72920854b 100644
--- a/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp
@@ -22,8 +22,12 @@ namespace {
TEST_F(VPVerifierTest, VPInstructionUseBeforeDefSameBB) {
VPlan &Plan = getPlan();
VPIRValue *Zero = Plan.getConstantInt(32, 0);
- VPInstruction *DefI = new VPInstruction(Instruction::Add, {Zero, Zero});
- VPInstruction *UseI = new VPInstruction(Instruction::Sub, {DefI, Zero});
+ VPInstruction *DefI =
+ new VPInstruction(Instruction::Add, {Zero, Zero},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
+ VPInstruction *UseI =
+ new VPInstruction(Instruction::Sub, {DefI, Zero},
+ VPIRFlags::getDefaultFlags(Instruction::Sub));
auto *CanIV = new VPCanonicalIVPHIRecipe(Zero, {});
VPBasicBlock *VPBB1 = Plan.getEntry();
@@ -57,8 +61,12 @@ TEST_F(VPVerifierTest, VPInstructionUseBeforeDefSameBB) {
TEST_F(VPVerifierTest, VPInstructionUseBeforeDefDifferentBB) {
VPlan &Plan = getPlan();
VPIRValue *Zero = Plan.getConstantInt(32, 0);
- VPInstruction *DefI = new VPInstruction(Instruction::Add, {Zero, Zero});
- VPInstruction *UseI = new VPInstruction(Instruction::Sub, {DefI, Zero});
+ VPInstruction *DefI =
+ new VPInstruction(Instruction::Add, {Zero, Zero},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
+ VPInstruction *UseI =
+ new VPInstruction(Instruction::Sub, {DefI, Zero},
+ VPIRFlags::getDefaultFlags(Instruction::Sub));
auto *CanIV = new VPCanonicalIVPHIRecipe(Zero, {});
VPInstruction *BranchOnCond =
new VPInstruction(VPInstruction::BranchOnCond, {CanIV});
@@ -99,7 +107,9 @@ TEST_F(VPVerifierTest, VPBlendUseBeforeDefDifferentBB) {
auto *Phi = PHINode::Create(Int32, 1);
VPIRValue *Zero = Plan.getConstantInt(Int32, 0);
- VPInstruction *DefI = new VPInstruction(Instruction::Add, {Zero, Zero});
+ VPInstruction *DefI =
+ new VPInstruction(Instruction::Add, {Zero, Zero},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
auto *CanIV = new VPCanonicalIVPHIRecipe(Zero, {});
VPInstruction *BranchOnCond =
new VPInstruction(VPInstruction::BranchOnCond, {CanIV});
@@ -153,7 +163,9 @@ TEST_F(VPVerifierTest, VPPhiIncomingValueDoesntDominateIncomingBlock) {
VPBasicBlock *VPBB3 = Plan.createVPBasicBlock("");
VPBasicBlock *VPBB4 = Plan.createVPBasicBlock("");
- VPInstruction *DefI = new VPInstruction(Instruction::Add, {Zero, Zero});
+ VPInstruction *DefI =
+ new VPInstruction(Instruction::Add, {Zero, Zero},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
VPPhi *Phi = new VPPhi({DefI}, {});
VPBB2->appendRecipe(Phi);
VPBB2->appendRecipe(DefI);
@@ -185,7 +197,9 @@ TEST_F(VPVerifierTest, VPPhiIncomingValueDoesntDominateIncomingBlock) {
TEST_F(VPVerifierTest, DuplicateSuccessorsOutsideRegion) {
VPlan &Plan = getPlan();
VPIRValue *Zero = Plan.getConstantInt(32, 0);
- VPInstruction *I1 = new VPInstruction(Instruction::Add, {Zero, Zero});
+ VPInstruction *I1 =
+ new VPInstruction(Instruction::Add, {Zero, Zero},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
auto *CanIV = new VPCanonicalIVPHIRecipe(Zero, {});
VPInstruction *BranchOnCond =
new VPInstruction(VPInstruction::BranchOnCond, {CanIV});
@@ -219,7 +233,9 @@ TEST_F(VPVerifierTest, DuplicateSuccessorsOutsideRegion) {
TEST_F(VPVerifierTest, DuplicateSuccessorsInsideRegion) {
VPlan &Plan = getPlan();
VPIRValue *Zero = Plan.getConstantInt(32, 0);
- VPInstruction *I1 = new VPInstruction(Instruction::Add, {Zero, Zero});
+ VPInstruction *I1 =
+ new VPInstruction(Instruction::Add, {Zero, Zero},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
auto *CanIV = new VPCanonicalIVPHIRecipe(Zero, {});
VPInstruction *BranchOnCond =
new VPInstruction(VPInstruction::BranchOnCond, {CanIV});
@@ -263,7 +279,9 @@ TEST_F(VPVerifierTest, BlockOutsideRegionWithParent) {
auto *CanIV = new VPCanonicalIVPHIRecipe(Zero, {});
VPBB2->appendRecipe(CanIV);
- VPInstruction *DefI = new VPInstruction(Instruction::Add, {Zero, Zero});
+ VPInstruction *DefI =
+ new VPInstruction(Instruction::Add, {Zero, Zero},
+ VPIRFlags::getDefaultFlags(Instruction::Add));
VPInstruction *BranchOnCond =
new VPInstruction(VPInstruction::BranchOnCond, {DefI});
>From e7c0e258a4502e709985816d0f441a78c2bfe6a7 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Mon, 2 Feb 2026 12:27:03 +0000
Subject: [PATCH 2/2] !fixup add IsExtact constructor
---
llvm/lib/Transforms/Vectorize/VPlan.h | 3 +++
llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 8 ++------
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index ac3d987d17223..00a9177be5278 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -817,6 +817,9 @@ class VPIRFlags {
VPIRFlags(NonNegFlagsTy NonNegFlags)
: OpType(OperationType::NonNegOp), NonNegFlags(NonNegFlags) {}
+ VPIRFlags(ExactFlagsTy ExactFlags)
+ : OpType(OperationType::PossiblyExactOp), ExactFlags(ExactFlags) {}
+
VPIRFlags(GEPNoWrapFlags GEPFlags)
: OpType(OperationType::GEPOp), GEPFlags(GEPFlags) {}
diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index d99edeb7bfbe5..fa395e7d07531 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -2071,12 +2071,8 @@ VPIRFlags VPIRFlags::getDefaultFlags(unsigned Opcode) {
case Instruction::AShr:
case Instruction::LShr:
case Instruction::UDiv:
- case Instruction::SDiv: {
- VPIRFlags F;
- F.OpType = OperationType::PossiblyExactOp;
- F.ExactFlags = ExactFlagsTy(false);
- return F;
- }
+ case Instruction::SDiv:
+ return ExactFlagsTy(false);
case Instruction::GetElementPtr:
case VPInstruction::PtrAdd:
case VPInstruction::WidePtrAdd:
More information about the llvm-commits
mailing list