[llvm] [VPlan] Absorb VPDef into VPRecipeBase (NFC) (PR #175085)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 8 15:03:20 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
@llvm/pr-subscribers-vectorizers
Author: Ramkumar Ramachandra (artagnon)
<details>
<summary>Changes</summary>
Simplify the class hierarchy by absorbing VPDef into VPRecipeBase, as VPDef serves no purpose by itself, and is only a potential source of confusion.
---
Patch is 64.00 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/175085.diff
6 Files Affected:
- (modified) llvm/lib/Transforms/Vectorize/LoopVectorize.cpp (+33-33)
- (modified) llvm/lib/Transforms/Vectorize/VPlan.cpp (+1-9)
- (modified) llvm/lib/Transforms/Vectorize/VPlan.h (+276-153)
- (modified) llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp (+15-7)
- (modified) llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp (+4-4)
- (modified) llvm/lib/Transforms/Vectorize/VPlanValue.h (+4-148)
``````````diff
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 645ee1ae4ea25..da2f11b743c44 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -4111,40 +4111,40 @@ static bool willGenerateVectors(VPlan &Plan, ElementCount VF,
// result. Note that this includes VPInstruction where some opcodes may
// produce a vector, to preserve existing behavior as VPInstructions model
// aspects not directly mapped to existing IR instructions.
- switch (R.getVPDefID()) {
- case VPDef::VPDerivedIVSC:
- case VPDef::VPScalarIVStepsSC:
- case VPDef::VPReplicateSC:
- case VPDef::VPInstructionSC:
- case VPDef::VPCanonicalIVPHISC:
- case VPDef::VPVectorPointerSC:
- case VPDef::VPVectorEndPointerSC:
- case VPDef::VPExpandSCEVSC:
- case VPDef::VPEVLBasedIVPHISC:
- case VPDef::VPPredInstPHISC:
- case VPDef::VPBranchOnMaskSC:
+ switch (R.getVPRecipeID()) {
+ case VPRecipeBase::VPDerivedIVSC:
+ case VPRecipeBase::VPScalarIVStepsSC:
+ case VPRecipeBase::VPReplicateSC:
+ case VPRecipeBase::VPInstructionSC:
+ case VPRecipeBase::VPCanonicalIVPHISC:
+ case VPRecipeBase::VPVectorPointerSC:
+ case VPRecipeBase::VPVectorEndPointerSC:
+ case VPRecipeBase::VPExpandSCEVSC:
+ case VPRecipeBase::VPEVLBasedIVPHISC:
+ case VPRecipeBase::VPPredInstPHISC:
+ case VPRecipeBase::VPBranchOnMaskSC:
continue;
- case VPDef::VPReductionSC:
- case VPDef::VPActiveLaneMaskPHISC:
- case VPDef::VPWidenCallSC:
- case VPDef::VPWidenCanonicalIVSC:
- case VPDef::VPWidenCastSC:
- case VPDef::VPWidenGEPSC:
- case VPDef::VPWidenIntrinsicSC:
- case VPDef::VPWidenSC:
- case VPDef::VPBlendSC:
- case VPDef::VPFirstOrderRecurrencePHISC:
- case VPDef::VPHistogramSC:
- case VPDef::VPWidenPHISC:
- case VPDef::VPWidenIntOrFpInductionSC:
- case VPDef::VPWidenPointerInductionSC:
- case VPDef::VPReductionPHISC:
- case VPDef::VPInterleaveEVLSC:
- case VPDef::VPInterleaveSC:
- case VPDef::VPWidenLoadEVLSC:
- case VPDef::VPWidenLoadSC:
- case VPDef::VPWidenStoreEVLSC:
- case VPDef::VPWidenStoreSC:
+ case VPRecipeBase::VPReductionSC:
+ case VPRecipeBase::VPActiveLaneMaskPHISC:
+ case VPRecipeBase::VPWidenCallSC:
+ case VPRecipeBase::VPWidenCanonicalIVSC:
+ case VPRecipeBase::VPWidenCastSC:
+ case VPRecipeBase::VPWidenGEPSC:
+ case VPRecipeBase::VPWidenIntrinsicSC:
+ case VPRecipeBase::VPWidenSC:
+ case VPRecipeBase::VPBlendSC:
+ case VPRecipeBase::VPFirstOrderRecurrencePHISC:
+ case VPRecipeBase::VPHistogramSC:
+ case VPRecipeBase::VPWidenPHISC:
+ case VPRecipeBase::VPWidenIntOrFpInductionSC:
+ case VPRecipeBase::VPWidenPointerInductionSC:
+ case VPRecipeBase::VPReductionPHISC:
+ case VPRecipeBase::VPInterleaveEVLSC:
+ case VPRecipeBase::VPInterleaveSC:
+ case VPRecipeBase::VPWidenLoadEVLSC:
+ case VPRecipeBase::VPWidenLoadSC:
+ case VPRecipeBase::VPWidenStoreEVLSC:
+ case VPRecipeBase::VPWidenStoreSC:
break;
default:
llvm_unreachable("unhandled recipe");
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp
index a6a46e36b397d..d7f6591566e5c 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp
@@ -106,14 +106,6 @@ void VPValue::dump() const {
print(dbgs(), SlotTracker);
dbgs() << "\n";
}
-
-void VPDef::dump() const {
- const VPRecipeBase *Instr = dyn_cast_or_null<VPRecipeBase>(this);
- VPSlotTracker SlotTracker(
- (Instr && Instr->getParent()) ? Instr->getParent()->getPlan() : nullptr);
- print(dbgs(), "", SlotTracker);
- dbgs() << "\n";
-}
#endif
VPRecipeBase *VPValue::getDefiningRecipe() {
@@ -136,7 +128,7 @@ Value *VPValue::getLiveInIRValue() const {
Type *VPIRValue::getType() const { return getUnderlyingValue()->getType(); }
-VPRecipeValue::VPRecipeValue(VPDef *Def, Value *UV)
+VPRecipeValue::VPRecipeValue(VPRecipeBase *Def, Value *UV)
: VPValue(VPVRecipeValueSC, UV), Def(Def) {
assert(Def && "VPRecipeValue requires a defining recipe");
Def->addDefinedValue(this);
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index 0fa5180f690ab..9d60cfd8423cf 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -377,16 +377,40 @@ class LLVM_ABI_FOR_TEST VPBlockBase {
};
/// VPRecipeBase is a base class modeling a sequence of one or more output IR
-/// instructions. VPRecipeBase owns the VPValues it defines through VPDef
-/// and is responsible for deleting its defined values. Single-value
-/// recipes must inherit from VPSingleDef instead of inheriting from both
-/// VPRecipeBase and VPValue separately.
+/// instructions. VPRecipeBase owns the VPValues and is responsible for deleting
+/// its defined values. Single-value recipes must inherit from VPSingleDef
+/// instead of inheriting from both VPRecipeBase and VPValue separately.
class LLVM_ABI_FOR_TEST VPRecipeBase
: public ilist_node_with_parent<VPRecipeBase, VPBasicBlock>,
- public VPDef,
public VPUser {
friend VPBasicBlock;
friend class VPBlockUtils;
+ friend class VPValue;
+ friend class VPRecipeValue;
+
+ /// Subclass identifier (for isa/dyn_cast).
+ const unsigned char SubclassID;
+
+ /// The VPValues defined by this VPRecipeBase.
+ TinyPtrVector<VPRecipeValue *> DefinedValues;
+
+ /// Add \p V as a defined value by this VPRecipeBase.
+ void addDefinedValue(VPRecipeValue *V) {
+ assert(V->Def == this &&
+ "can only add VPValue already linked with this VPRecipeBase");
+ DefinedValues.push_back(V);
+ }
+
+ /// Remove \p V from the values defined by this VPRecipeBase. \p V must be a
+ /// defined value of this VPRecipeBase.
+ void removeDefinedValue(VPRecipeValue *V) {
+ assert(V->Def == this &&
+ "can only remove VPValue linked with this VPRecipeBase");
+ assert(is_contained(DefinedValues, V) &&
+ "VPValue to remove must be in DefinedValues");
+ llvm::erase(DefinedValues, V);
+ V->Def = nullptr;
+ }
/// Each VPRecipe belongs to a single VPBasicBlock.
VPBasicBlock *Parent = nullptr;
@@ -395,11 +419,108 @@ class LLVM_ABI_FOR_TEST VPRecipeBase
DebugLoc DL;
public:
+ /// An enumeration for keeping track of the concrete subclass of VPRecipeBase
+ /// that is actually instantiated. Values of this enumeration are kept in the
+ /// SubclassID field of the VPRecipeBase objects. They are used for concrete
+ /// type identification.
+ using VPRecipeTy = enum {
+ VPBranchOnMaskSC,
+ VPDerivedIVSC,
+ VPExpandSCEVSC,
+ VPExpressionSC,
+ VPIRInstructionSC,
+ VPInstructionSC,
+ VPInterleaveEVLSC,
+ VPInterleaveSC,
+ VPReductionEVLSC,
+ VPReductionSC,
+ VPReplicateSC,
+ VPScalarIVStepsSC,
+ VPVectorPointerSC,
+ VPVectorEndPointerSC,
+ VPWidenCallSC,
+ VPWidenCanonicalIVSC,
+ VPWidenCastSC,
+ VPWidenGEPSC,
+ VPWidenIntrinsicSC,
+ VPWidenLoadEVLSC,
+ VPWidenLoadSC,
+ VPWidenStoreEVLSC,
+ VPWidenStoreSC,
+ VPWidenSC,
+ VPWidenSelectSC,
+ VPBlendSC,
+ VPHistogramSC,
+ // START: Phi-like recipes. Need to be kept together.
+ VPWidenPHISC,
+ VPPredInstPHISC,
+ // START: SubclassID for recipes that inherit VPHeaderPHIRecipe.
+ // VPHeaderPHIRecipe need to be kept together.
+ VPCanonicalIVPHISC,
+ VPActiveLaneMaskPHISC,
+ VPEVLBasedIVPHISC,
+ VPFirstOrderRecurrencePHISC,
+ VPWidenIntOrFpInductionSC,
+ VPWidenPointerInductionSC,
+ VPReductionPHISC,
+ // END: SubclassID for recipes that inherit VPHeaderPHIRecipe
+ // END: Phi-like recipes
+ VPFirstPHISC = VPWidenPHISC,
+ VPFirstHeaderPHISC = VPCanonicalIVPHISC,
+ VPLastHeaderPHISC = VPReductionPHISC,
+ VPLastPHISC = VPReductionPHISC,
+ };
+
VPRecipeBase(const unsigned char SC, ArrayRef<VPValue *> Operands,
DebugLoc DL = DebugLoc::getUnknown())
- : VPDef(SC), VPUser(Operands), DL(DL) {}
+ : VPUser(Operands), SubclassID(SC), DL(DL) {}
+
+ virtual ~VPRecipeBase() {
+ for (VPRecipeValue *D : to_vector(DefinedValues)) {
+ assert(
+ D->Def == this &&
+ "all defined VPValues should point to the containing VPRecipeBase");
+ assert(D->getNumUsers() == 0 &&
+ "all defined VPValues should have no more users");
+ delete D;
+ }
+ }
+
+ /// Returns the only VPValue defined by the VPRecipeBase. Can only be called
+ /// for VPRecipeBases with a single defined value.
+ VPValue *getVPSingleValue() {
+ assert(DefinedValues.size() == 1 && "must have exactly one defined value");
+ assert(DefinedValues[0] && "defined value must be non-null");
+ return DefinedValues[0];
+ }
+ const VPValue *getVPSingleValue() const {
+ assert(DefinedValues.size() == 1 && "must have exactly one defined value");
+ assert(DefinedValues[0] && "defined value must be non-null");
+ return DefinedValues[0];
+ }
+
+ /// Returns the VPValue with index \p I defined by the VPRecipeBase.
+ VPValue *getVPValue(unsigned I) {
+ assert(DefinedValues[I] && "defined value must be non-null");
+ return DefinedValues[I];
+ }
+ const VPValue *getVPValue(unsigned I) const {
+ assert(DefinedValues[I] && "defined value must be non-null");
+ return DefinedValues[I];
+ }
- ~VPRecipeBase() override = default;
+ /// Returns an ArrayRef of the values defined by the VPRecipeBase.
+ ArrayRef<VPRecipeValue *> definedValues() { return DefinedValues; }
+ /// Returns an ArrayRef of the values defined by the VPRecipeBase.
+ ArrayRef<VPRecipeValue *> definedValues() const { return DefinedValues; }
+
+ /// Returns the number of values defined by the VPRecipeBase.
+ unsigned getNumDefinedValues() const { return DefinedValues.size(); }
+
+ /// \return an ID for the concrete type of this object.
+ /// This is used to implement the classof checks. This should not be used
+ /// for any other purpose, as the values may change as LLVM evolves.
+ unsigned getVPRecipeID() const { return SubclassID; }
/// Clone the current recipe.
virtual VPRecipeBase *clone() = 0;
@@ -450,12 +571,6 @@ class LLVM_ABI_FOR_TEST VPRecipeBase
/// \returns an iterator pointing to the element after the erased one
iplist<VPRecipeBase>::iterator eraseFromParent();
- /// Method to support type inquiry through isa, cast, and dyn_cast.
- static inline bool classof(const VPDef *D) {
- // All VPDefs are also VPRecipeBases.
- return true;
- }
-
static inline bool classof(const VPUser *U) { return true; }
/// Returns true if the recipe may have side-effects.
@@ -485,9 +600,12 @@ class LLVM_ABI_FOR_TEST VPRecipeBase
void setDebugLoc(DebugLoc NewDL) { DL = NewDL; }
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ /// Dump the VPRecipeBase to stderr (for debugging).
+ LLVM_ABI_FOR_TEST void dump() const;
+
/// Print the recipe, delegating to printRecipe().
void print(raw_ostream &O, const Twine &Indent,
- VPSlotTracker &SlotTracker) const override final;
+ VPSlotTracker &SlotTracker) const;
#endif
protected:
@@ -506,23 +624,20 @@ class LLVM_ABI_FOR_TEST VPRecipeBase
};
// Helper macro to define common classof implementations for recipes.
-#define VP_CLASSOF_IMPL(VPDefID) \
- static inline bool classof(const VPDef *D) { \
- return D->getVPDefID() == VPDefID; \
- } \
+#define VP_CLASSOF_IMPL(VPRecipeID) \
static inline bool classof(const VPValue *V) { \
auto *R = V->getDefiningRecipe(); \
- return R && R->getVPDefID() == VPDefID; \
+ return R && R->getVPRecipeID() == VPRecipeID; \
} \
static inline bool classof(const VPUser *U) { \
auto *R = dyn_cast<VPRecipeBase>(U); \
- return R && R->getVPDefID() == VPDefID; \
+ return R && R->getVPRecipeID() == VPRecipeID; \
} \
static inline bool classof(const VPRecipeBase *R) { \
- return R->getVPDefID() == VPDefID; \
+ return R->getVPRecipeID() == VPRecipeID; \
} \
static inline bool classof(const VPSingleDefRecipe *R) { \
- return R->getVPDefID() == VPDefID; \
+ return R->getVPRecipeID() == VPRecipeID; \
}
/// VPSingleDef is a base class for recipes for modeling a sequence of one or
@@ -539,7 +654,7 @@ class VPSingleDefRecipe : public VPRecipeBase, public VPRecipeValue {
: VPRecipeBase(SC, Operands, DL), VPRecipeValue(this, UV) {}
static inline bool classof(const VPRecipeBase *R) {
- switch (R->getVPDefID()) {
+ switch (R->getVPRecipeID()) {
case VPRecipeBase::VPDerivedIVSC:
case VPRecipeBase::VPEVLBasedIVPHISC:
case VPRecipeBase::VPExpandSCEVSC:
@@ -580,7 +695,7 @@ class VPSingleDefRecipe : public VPRecipeBase, public VPRecipeValue {
// the recipes to be able to make widened loads VPSingleDefRecipes.
return false;
}
- llvm_unreachable("Unhandled VPDefID");
+ llvm_unreachable("Unhandled VPRecipeID");
}
static inline bool classof(const VPUser *U) {
@@ -926,17 +1041,17 @@ struct VPRecipeWithIRFlags : public VPSingleDefRecipe, public VPIRFlags {
: VPSingleDefRecipe(SC, Operands, DL), VPIRFlags(Flags) {}
static inline bool classof(const VPRecipeBase *R) {
- return R->getVPDefID() == VPRecipeBase::VPInstructionSC ||
- R->getVPDefID() == VPRecipeBase::VPWidenSC ||
- R->getVPDefID() == VPRecipeBase::VPWidenGEPSC ||
- R->getVPDefID() == VPRecipeBase::VPWidenCallSC ||
- R->getVPDefID() == VPRecipeBase::VPWidenCastSC ||
- R->getVPDefID() == VPRecipeBase::VPWidenIntrinsicSC ||
- R->getVPDefID() == VPRecipeBase::VPReductionSC ||
- R->getVPDefID() == VPRecipeBase::VPReductionEVLSC ||
- R->getVPDefID() == VPRecipeBase::VPReplicateSC ||
- R->getVPDefID() == VPRecipeBase::VPVectorEndPointerSC ||
- R->getVPDefID() == VPRecipeBase::VPVectorPointerSC;
+ return R->getVPRecipeID() == VPRecipeBase::VPInstructionSC ||
+ R->getVPRecipeID() == VPRecipeBase::VPWidenSC ||
+ R->getVPRecipeID() == VPRecipeBase::VPWidenGEPSC ||
+ R->getVPRecipeID() == VPRecipeBase::VPWidenCallSC ||
+ R->getVPRecipeID() == VPRecipeBase::VPWidenCastSC ||
+ R->getVPRecipeID() == VPRecipeBase::VPWidenIntrinsicSC ||
+ R->getVPRecipeID() == VPRecipeBase::VPReductionSC ||
+ R->getVPRecipeID() == VPRecipeBase::VPReductionEVLSC ||
+ R->getVPRecipeID() == VPRecipeBase::VPReplicateSC ||
+ R->getVPRecipeID() == VPRecipeBase::VPVectorEndPointerSC ||
+ R->getVPRecipeID() == VPRecipeBase::VPVectorPointerSC;
}
static inline bool classof(const VPUser *U) {
@@ -1178,7 +1293,7 @@ class LLVM_ABI_FOR_TEST VPInstruction : public VPRecipeWithIRFlags,
const VPIRFlags &Flags = {}, const VPIRMetadata &MD = {},
DebugLoc DL = DebugLoc::getUnknown(), const Twine &Name = "");
- VP_CLASSOF_IMPL(VPDef::VPInstructionSC)
+ VP_CLASSOF_IMPL(VPRecipeBase::VPInstructionSC)
VPInstruction *clone() override {
auto *New = new VPInstruction(Opcode, operands(), *this, *this,
@@ -1260,9 +1375,9 @@ class LLVM_ABI_FOR_TEST VPInstruction : public VPRecipeWithIRFlags,
/// A specialization of VPInstruction augmenting it with a dedicated result
/// type, to be used when the opcode and operands of the VPInstruction don't
-/// directly determine the result type. Note that there is no separate VPDef ID
-/// for VPInstructionWithType; it shares the same ID as VPInstruction and is
-/// distinguished purely by the opcode.
+/// directly determine the result type. Note that there is no separate
+/// VPRecipeBase ID for VPInstructionWithType; it shares the same ID as
+/// VPInstruction and is distinguished purely by the opcode.
class VPInstructionWithType : public VPInstruction {
/// Scalar result type produced by the recipe.
Type *ResultTy;
@@ -1430,7 +1545,8 @@ class VPIRInstruction : public VPRecipeBase {
/// VPIRInstruction::create() should be used to create VPIRInstructions, as
/// subclasses may need to be created, e.g. VPIRPhi.
VPIRInstruction(Instruction &I)
- : VPRecipeBase(VPDef::VPIRInstructionSC, ArrayRef<VPValue *>()), I(I) {}
+ : VPRecipeBase(VPRecipeBase::VPIRInstructionSC, ArrayRef<VPValue *>()),
+ I(I) {}
public:
~VPIRInstruction() override = default;
@@ -1439,7 +1555,7 @@ class VPIRInstruction : public VPRecipeBase {
/// VPIRInstruction.
LLVM_ABI_FOR_TEST static VPIRInstruction *create(Instruction &I);
- VP_CLASSOF_IMPL(VPDef::VPIRInstructionSC)
+ VP_CLASSOF_IMPL(VPRecipeBase::VPIRInstructionSC)
VPIRInstruction *clone() override {
auto *R = create(I);
@@ -1526,7 +1642,7 @@ class LLVM_ABI_FOR_TEST VPWidenRecipe : public VPRecipeWithIRFlags,
VPWidenRecipe(Instruction &I, ArrayRef<VPValue *> Operands,
const VPIRFlags &Flags = {}, const VPIRMetadata &Metadata = {},
DebugLoc DL = {})
- : VPRecipeWithIRFlags(VPDef::VPWidenSC, Operands, Flags, DL),
+ : VPRecipeWithIRFlags(VPRecipeBase::VPWidenSC, Operands, Flags, DL),
VPIRMetadata(Metadata), Opcode(I.getOpcode()) {
setUnderlyingValue(&I);
}
@@ -1538,7 +1654,7 @@ class LLVM_ABI_FOR_TEST VPWidenRecipe : public VPRecipeWithIRFlags,
getDebugLoc());
}
- VP_CLASSOF_IMPL(VPDef::VPWidenSC)
+ VP_CLASSOF_IMPL(VPRecipeBase::VPWidenSC)
/// Produce a widened instruction using the opcode and operands of the recipe,
/// processing State.VF elements.
@@ -1579,7 +1695,7 @@ class VPWidenCastRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
CastInst *CI = nullptr, const VPIRFlags &Flags = {},
const VPIRMetadata &Metadata = {},
DebugLoc DL = DebugLoc::getUnknown())
- : VPRecipeWithIRFlags(VPDef::VPWidenCastSC, Op, Flags, DL),
+ : VPRecipeWithIRFlags(VPRecipeBase::VPWidenCastSC, Op, Flags, DL),
VPIRMetadata(Metadata), Opcode(Opcode), ResultTy(ResultTy) {
assert(flagsValidForOpcode(Opcode) &&
"Set flags not supported for the provided opcode");
@@ -1594,7 +1710,7 @@ class VPWidenCastRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
*this, *this, getDebugLoc());
}
- VP_CLASSOF_IMPL(VPDef::VPWidenCastSC)
+ VP_CLASSOF_IMPL(VPRecipeBase::VPWidenCastSC)
/// Produce widened copies of the cast.
LLVM_ABI_FOR_TEST void execute(VPTransformState &State) override;
@@ -1639,8 +1755,8 @@ class VPWidenIntrinsicRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
const VPIRFlags &Flags = {},
const VPIRMetadata &MD = {},
DebugLoc DL = DebugLoc::getUnknown())
- : VPRecipeWithIRFlags(VPDef::VPWidenIntrinsicSC, CallArguments, Flags,
- DL),
+ : VPRecipeWithIRFlags(VPRecipeBase::VPWidenIntrinsicSC, CallArguments,
+ Flags, DL),
VPIRMetadata(MD), VectorIntrinsicID(VectorIntrinsicID), ResultTy(Ty),
MayReadFromMemory(CI.mayReadFromMemory()),
MayWriteToMemory(CI.mayWriteToMemory()),
@@ -1653,8 +1769,8 @@ cla...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/175085
More information about the llvm-commits
mailing list