[llvm] [NFC] Convert LoadExtActions to a map (PR #157627)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 9 02:03:10 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-selectiondag
Author: Sam Parker (sparker-arm)
<details>
<summary>Changes</summary>
So we can store actions per address space.
---
Patch is 57.54 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/157627.diff
2 Files Affected:
- (modified) llvm/include/llvm/CodeGen/TargetLowering.h (+241-273)
- (modified) llvm/lib/CodeGen/TargetLoweringBase.cpp (-1)
``````````diff
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 2ba8b29e775e0..d295cfa043503 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -200,11 +200,11 @@ class LLVM_ABI TargetLoweringBase {
/// This enum indicates whether operations are valid for a target, and if not,
/// what action should be used to make them valid.
enum LegalizeAction : uint8_t {
- Legal, // The target natively supports this operation.
- Promote, // This operation should be executed in a larger type.
- Expand, // Try to expand this to other ops, otherwise use a libcall.
- LibCall, // Don't try to expand this to other ops, always use a libcall.
- Custom // Use the LowerOperation hook to implement custom lowering.
+ Legal, // The target natively supports this operation.
+ Promote, // This operation should be executed in a larger type.
+ Expand, // Try to expand this to other ops, otherwise use a libcall.
+ LibCall, // Don't try to expand this to other ops, always use a libcall.
+ Custom // Use the LowerOperation hook to implement custom lowering.
};
/// This enum indicates whether a types are legal for a target, and if not,
@@ -220,13 +220,13 @@ class LLVM_ABI TargetLoweringBase {
TypeWidenVector, // This vector should be widened into a larger vector.
TypePromoteFloat, // Replace this float with a larger one.
TypeSoftPromoteHalf, // Soften half to i16 and use float to do arithmetic.
- TypeScalarizeScalableVector, // This action is explicitly left unimplemented.
- // While it is theoretically possible to
- // legalize operations on scalable types with a
- // loop that handles the vscale * #lanes of the
- // vector, this is non-trivial at SelectionDAG
- // level and these types are better to be
- // widened or promoted.
+ TypeScalarizeScalableVector, // This action is explicitly left
+ // unimplemented. While it is theoretically
+ // possible to legalize operations on scalable
+ // types with a loop that handles the vscale *
+ // #lanes of the vector, this is non-trivial at
+ // SelectionDAG level and these types are
+ // better to be widened or promoted.
};
/// LegalizeKind holds the legalization kind that needs to happen to EVT
@@ -235,18 +235,18 @@ class LLVM_ABI TargetLoweringBase {
/// Enum that describes how the target represents true/false values.
enum BooleanContent {
- UndefinedBooleanContent, // Only bit 0 counts, the rest can hold garbage.
- ZeroOrOneBooleanContent, // All bits zero except for bit 0.
+ UndefinedBooleanContent, // Only bit 0 counts, the rest can hold garbage.
+ ZeroOrOneBooleanContent, // All bits zero except for bit 0.
ZeroOrNegativeOneBooleanContent // All bits equal to bit 0.
};
/// Enum that describes what type of support for selects the target has.
enum SelectSupportKind {
- ScalarValSelect, // The target supports scalar selects (ex: cmov).
- ScalarCondVectorVal, // The target supports selects with a scalar condition
- // and vector values (ex: cmov).
- VectorMaskSelect // The target supports vector selects with a vector
- // mask (ex: x86 blends).
+ ScalarValSelect, // The target supports scalar selects (ex: cmov).
+ ScalarCondVectorVal, // The target supports selects with a scalar condition
+ // and vector values (ex: cmov).
+ VectorMaskSelect // The target supports vector selects with a vector
+ // mask (ex: x86 blends).
};
/// Enum that specifies what an atomic load/AtomicRMWInst is expanded
@@ -284,9 +284,9 @@ class LLVM_ABI TargetLoweringBase {
/// Enum that specifies when a float negation is beneficial.
enum class NegatibleCost {
- Cheaper = 0, // Negated expression is cheaper.
- Neutral = 1, // Negated expression has the same cost.
- Expensive = 2 // Negated expression is more expensive.
+ Cheaper = 0, // Negated expression is cheaper.
+ Neutral = 1, // Negated expression has the same cost.
+ Expensive = 2 // Negated expression is more expensive.
};
/// Enum of different potentially desirable ways to fold (and/or (setcc ...),
@@ -361,9 +361,7 @@ class LLVM_ABI TargetLoweringBase {
virtual ~TargetLoweringBase();
/// Return true if the target support strict float operation
- bool isStrictFPEnabled() const {
- return IsStrictFPEnabled;
- }
+ bool isStrictFPEnabled() const { return IsStrictFPEnabled; }
protected:
/// Initialize all of the actions to default values.
@@ -454,7 +452,8 @@ class LLVM_ABI TargetLoweringBase {
/// This callback is used to inspect load/store instructions and add
/// target-specific MachineMemOperand flags to them. The default
/// implementation does nothing.
- virtual MachineMemOperand::Flags getTargetMMOFlags(const Instruction &I) const {
+ virtual MachineMemOperand::Flags
+ getTargetMMOFlags(const Instruction &I) const {
return MachineMemOperand::MONone;
}
@@ -525,9 +524,7 @@ class LLVM_ABI TargetLoweringBase {
/// a constant pool load whose address depends on the select condition. The
/// parameter may be used to differentiate a select with FP compare from
/// integer compare.
- virtual bool reduceSelectOfFPConstantLoads(EVT CmpOpVT) const {
- return true;
- }
+ virtual bool reduceSelectOfFPConstantLoads(EVT CmpOpVT) const { return true; }
/// Does the target have multiple (allocatable) condition registers that
/// can be used to store the results of comparisons for use by selects
@@ -586,9 +583,7 @@ class LLVM_ABI TargetLoweringBase {
virtual bool isIntDivCheap(EVT VT, AttributeList Attr) const { return false; }
/// Return true if the target can handle a standalone remainder operation.
- virtual bool hasStandaloneRem(EVT VT) const {
- return true;
- }
+ virtual bool hasStandaloneRem(EVT VT) const { return true; }
/// Return true if SQRT(X) shouldn't be replaced with X*RSQRT(X).
virtual bool isFsqrtCheap(SDValue X, SelectionDAG &DAG) const {
@@ -597,11 +592,7 @@ class LLVM_ABI TargetLoweringBase {
}
/// Reciprocal estimate status values used by the functions below.
- enum ReciprocalEstimate : int {
- Unspecified = -1,
- Disabled = 0,
- Enabled = 1
- };
+ enum ReciprocalEstimate : int { Unspecified = -1, Disabled = 0, Enabled = 1 };
/// Return a ReciprocalEstimate enum value for a square root of the given type
/// based on the function's attributes. If the operation is not overridden by
@@ -720,9 +711,7 @@ class LLVM_ABI TargetLoweringBase {
/// Allow store merging for the specified type after legalization in addition
/// to before legalization. This may transform stores that do not exist
/// earlier (for example, stores created from intrinsics).
- virtual bool mergeStoresAfterLegalization(EVT MemVT) const {
- return true;
- }
+ virtual bool mergeStoresAfterLegalization(EVT MemVT) const { return true; }
/// Returns if it's reasonable to merge stores to MemVT size.
virtual bool canMergeStoresTo(unsigned AS, EVT MemVT,
@@ -731,19 +720,13 @@ class LLVM_ABI TargetLoweringBase {
}
/// Return true if it is cheap to speculate a call to intrinsic cttz.
- virtual bool isCheapToSpeculateCttz(Type *Ty) const {
- return false;
- }
+ virtual bool isCheapToSpeculateCttz(Type *Ty) const { return false; }
/// Return true if it is cheap to speculate a call to intrinsic ctlz.
- virtual bool isCheapToSpeculateCtlz(Type *Ty) const {
- return false;
- }
+ virtual bool isCheapToSpeculateCtlz(Type *Ty) const { return false; }
/// Return true if ctlz instruction is fast.
- virtual bool isCtlzFast() const {
- return false;
- }
+ virtual bool isCtlzFast() const { return false; }
/// Return true if ctpop instruction is fast.
virtual bool isCtpopFast(EVT VT) const {
@@ -796,9 +779,7 @@ class LLVM_ABI TargetLoweringBase {
/// This should be true when it takes more than one instruction to lower
/// setcc (cmp+set on x86 scalar), when bitwise ops are faster than logic on
/// condition bits (crand on PowerPC), and/or when reducing cmp+br is a win.
- virtual bool convertSetCCLogicToBitwiseLogic(EVT VT) const {
- return false;
- }
+ virtual bool convertSetCCLogicToBitwiseLogic(EVT VT) const { return false; }
/// Return the preferred operand type if the target has a quick way to compare
/// integer values of the given size. Assume that any legal integer type can
@@ -821,9 +802,7 @@ class LLVM_ABI TargetLoweringBase {
/// because a mask and compare of a single bit can be handled by inverting the
/// predicate, for example:
/// (X & 8) == 8 ---> (X & 8) != 0
- virtual bool hasAndNotCompare(SDValue Y) const {
- return false;
- }
+ virtual bool hasAndNotCompare(SDValue Y) const { return false; }
/// Return true if the target has a bitwise and-not operation:
/// X = ~A & B
@@ -952,9 +931,7 @@ class LLVM_ABI TargetLoweringBase {
// By default prefer folding (abs (sub nsw x, y)) -> abds(x, y). Some targets
// may want to avoid this to prevent loss of sub_nsw pattern.
- virtual bool preferABDSToABSWithNSW(EVT VT) const {
- return true;
- }
+ virtual bool preferABDSToABSWithNSW(EVT VT) const { return true; }
// Return true if the target wants to transform Op(Splat(X)) -> Splat(Op(X))
virtual bool preferScalarizeSplat(SDNode *N) const { return true; }
@@ -991,9 +968,7 @@ class LLVM_ABI TargetLoweringBase {
/// Return true if inserting a scalar into a variable element of an undef
/// vector is more efficiently handled by splatting the scalar instead.
- virtual bool shouldSplatInsEltVarIndex(EVT) const {
- return false;
- }
+ virtual bool shouldSplatInsEltVarIndex(EVT) const { return false; }
/// Return true if target always benefits from combining into FMA for a
/// given value type. This must typically return false on targets where FMA
@@ -1012,8 +987,7 @@ class LLVM_ABI TargetLoweringBase {
/// Return the ValueType for comparison libcalls. Comparison libcalls include
/// floating point comparison calls, and Ordered/Unordered check calls on
/// floating point numbers.
- virtual
- MVT::SimpleValueType getCmpLibcallReturnType() const;
+ virtual MVT::SimpleValueType getCmpLibcallReturnType() const;
/// For targets without i1 registers, this gives the nature of the high-bits
/// of boolean values held in types wider than i1.
@@ -1066,7 +1040,8 @@ class LLVM_ABI TargetLoweringBase {
/// Return the register class that should be used for the specified value
/// type.
- virtual const TargetRegisterClass *getRegClassFor(MVT VT, bool isDivergent = false) const {
+ virtual const TargetRegisterClass *
+ getRegClassFor(MVT VT, bool isDivergent = false) const {
(void)isDivergent;
const TargetRegisterClass *RC = RegClassForVT[VT.SimpleTy];
assert(RC && "This value type is not natively supported!");
@@ -1224,8 +1199,8 @@ class LLVM_ABI TargetLoweringBase {
}
struct IntrinsicInfo {
- unsigned opc = 0; // target opcode
- EVT memVT; // memory VT
+ unsigned opc = 0; // target opcode
+ EVT memVT; // memory VT
// value representing memory location
PointerUnion<const Value *, const PseudoSourceValue *> ptrVal;
@@ -1234,10 +1209,10 @@ class LLVM_ABI TargetLoweringBase {
// unknown address space.
std::optional<unsigned> fallbackAddressSpace;
- int offset = 0; // offset off of ptrVal
- uint64_t size = 0; // the size of the memory location
- // (taken from memVT if zero)
- MaybeAlign align = Align(1); // alignment
+ int offset = 0; // offset off of ptrVal
+ uint64_t size = 0; // the size of the memory location
+ // (taken from memVT if zero)
+ MaybeAlign align = Align(1); // alignment
MachineMemOperand::Flags flags = MachineMemOperand::MONone;
SyncScope::ID ssid = SyncScope::System;
@@ -1348,11 +1323,16 @@ class LLVM_ABI TargetLoweringBase {
LegalizeAction getStrictFPOperationAction(unsigned Op, EVT VT) const {
unsigned EqOpc;
switch (Op) {
- default: llvm_unreachable("Unexpected FP pseudo-opcode");
+ default:
+ llvm_unreachable("Unexpected FP pseudo-opcode");
#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
- case ISD::STRICT_##DAGN: EqOpc = ISD::DAGN; break;
+ case ISD::STRICT_##DAGN: \
+ EqOpc = ISD::DAGN; \
+ break;
#define CMP_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
- case ISD::STRICT_##DAGN: EqOpc = ISD::SETCC; break;
+ case ISD::STRICT_##DAGN: \
+ EqOpc = ISD::SETCC; \
+ break;
#include "llvm/IR/ConstrainedOps.def"
}
@@ -1369,8 +1349,8 @@ class LLVM_ABI TargetLoweringBase {
return isOperationLegal(Op, VT);
return (VT == MVT::Other || isTypeLegal(VT)) &&
- (getOperationAction(Op, VT) == Legal ||
- getOperationAction(Op, VT) == Custom);
+ (getOperationAction(Op, VT) == Legal ||
+ getOperationAction(Op, VT) == Custom);
}
/// Return true if the specified operation is legal on this target or can be
@@ -1383,8 +1363,8 @@ class LLVM_ABI TargetLoweringBase {
return isOperationLegal(Op, VT);
return (VT == MVT::Other || isTypeLegal(VT)) &&
- (getOperationAction(Op, VT) == Legal ||
- getOperationAction(Op, VT) == Promote);
+ (getOperationAction(Op, VT) == Legal ||
+ getOperationAction(Op, VT) == Promote);
}
/// Return true if the specified operation is legal on this target or can be
@@ -1397,9 +1377,9 @@ class LLVM_ABI TargetLoweringBase {
return isOperationLegal(Op, VT);
return (VT == MVT::Other || isTypeLegal(VT)) &&
- (getOperationAction(Op, VT) == Legal ||
- getOperationAction(Op, VT) == Custom ||
- getOperationAction(Op, VT) == Promote);
+ (getOperationAction(Op, VT) == Legal ||
+ getOperationAction(Op, VT) == Custom ||
+ getOperationAction(Op, VT) == Promote);
}
/// Return true if the operation uses custom lowering, regardless of whether
@@ -1479,33 +1459,39 @@ class LLVM_ABI TargetLoweringBase {
/// Return how this load with extension should be treated: either it is legal,
/// needs to be promoted to a larger size, needs to be expanded to some other
/// code sequence, or the target has a custom expander for it.
- LegalizeAction getLoadExtAction(unsigned ExtType, EVT ValVT,
- EVT MemVT) const {
- if (ValVT.isExtended() || MemVT.isExtended()) return Expand;
- unsigned ValI = (unsigned) ValVT.getSimpleVT().SimpleTy;
- unsigned MemI = (unsigned) MemVT.getSimpleVT().SimpleTy;
+ LegalizeAction getLoadExtAction(unsigned ExtType, EVT ValVT, EVT MemVT,
+ unsigned AddrSpace = 0) const {
+ if (ValVT.isExtended() || MemVT.isExtended())
+ return Expand;
+ unsigned ValI = (unsigned)ValVT.getSimpleVT().SimpleTy;
+ unsigned MemI = (unsigned)MemVT.getSimpleVT().SimpleTy;
assert(ExtType < ISD::LAST_LOADEXT_TYPE && ValI < MVT::VALUETYPE_SIZE &&
MemI < MVT::VALUETYPE_SIZE && "Table isn't big enough!");
unsigned Shift = 4 * ExtType;
- return (LegalizeAction)((LoadExtActions[ValI][MemI] >> Shift) & 0xf);
+ return (
+ LegalizeAction)((LoadExtActions.at(AddrSpace)[ValI][MemI] >> Shift) &
+ 0xf);
}
/// Return true if the specified load with extension is legal on this target.
- bool isLoadExtLegal(unsigned ExtType, EVT ValVT, EVT MemVT) const {
- return getLoadExtAction(ExtType, ValVT, MemVT) == Legal;
+ bool isLoadExtLegal(unsigned ExtType, EVT ValVT, EVT MemVT,
+ unsigned AddrSpace = 0) const {
+ return getLoadExtAction(ExtType, ValVT, MemVT, AddrSpace) == Legal;
}
/// Return true if the specified load with extension is legal or custom
/// on this target.
- bool isLoadExtLegalOrCustom(unsigned ExtType, EVT ValVT, EVT MemVT) const {
- return getLoadExtAction(ExtType, ValVT, MemVT) == Legal ||
- getLoadExtAction(ExtType, ValVT, MemVT) == Custom;
+ bool isLoadExtLegalOrCustom(unsigned ExtType, EVT ValVT, EVT MemVT,
+ unsigned AddrSpace = 0) const {
+ return getLoadExtAction(ExtType, ValVT, MemVT, AddrSpace) == Legal ||
+ getLoadExtAction(ExtType, ValVT, MemVT, AddrSpace) == Custom;
}
/// Same as getLoadExtAction, but for atomic loads.
LegalizeAction getAtomicLoadExtAction(unsigned ExtType, EVT ValVT,
EVT MemVT) const {
- if (ValVT.isExtended() || MemVT.isExtended()) return Expand;
+ if (ValVT.isExtended() || MemVT.isExtended())
+ return Expand;
unsigned ValI = (unsigned)ValVT.getSimpleVT().SimpleTy;
unsigned MemI = (unsigned)MemVT.getSimpleVT().SimpleTy;
assert(ExtType < ISD::LAST_LOADEXT_TYPE && ValI < MVT::VALUETYPE_SIZE &&
@@ -1528,9 +1514,10 @@ class LLVM_ABI TargetLoweringBase {
/// legal, needs to be promoted to a larger size, needs to be expanded to some
/// other code sequence, or the target has a custom expander for it.
LegalizeAction getTruncStoreAction(EVT ValVT, EVT MemVT) const {
- if (ValVT.isExtended() || MemVT.isExtended()) return Expand;
- unsigned ValI = (unsigned) ValVT.getSimpleVT().SimpleTy;
- unsigned MemI = (unsigned) MemVT.getSimpleVT().SimpleTy;
+ if (ValVT.isExtended() || MemVT.isExtended())
+ return Expand;
+ unsigned ValI = (unsigned)ValVT.getSimpleVT().SimpleTy;
+ unsigned MemI = (unsigned)MemVT.getSimpleVT().SimpleTy;
assert(ValI < MVT::VALUETYPE_SIZE && MemI < MVT::VALUETYPE_SIZE &&
"Table isn't big enough!");
return TruncStoreActions[ValI][MemI];
@@ -1545,9 +1532,8 @@ class LLVM_ABI TargetLoweringBase {
/// Return true if the specified store with truncation has solution on this
/// target.
bool isTruncStoreLegalOrCustom(EVT ValVT, EVT MemVT) const {
- return isTypeLegal(ValVT) &&
- (getTruncStoreAction(ValVT, MemVT) == Legal ||
- getTruncStoreAction(ValVT, MemVT) == Custom);
+ return isTypeLegal(ValVT) && (getTruncStoreAction(ValVT, MemVT) == Legal ||
+ getTruncStoreAction(ValVT, MemVT) == Custom);
}
virtual bool canCombineTruncStore(EVT ValVT, EVT MemVT,
@@ -1568,8 +1554,8 @@ class LLVM_ABI TargetLoweringBase {
/// Return true if the specified indexed load is legal on this target.
bool isIndexedLoadLegal(unsigned IdxMode, EVT VT) const {
return VT.isSimple() &&
- (getIndexedLoadAction(IdxMode, VT.getSimpleVT()) == Legal ||
- getIndexedLoadAction(IdxMode, VT.getSimpleVT()) == Custom);
+ (getIndexedLoadAction(IdxMode, VT.getSimpleVT()) == Legal ||
+ getIndexedLoadAction(IdxMode, VT.getSimpleVT()) == Custom);
}
/// Return how the indexed store should be treated: either it is legal, needs
@@ -1582,8 +1568,8 @@ class LLVM_ABI TargetLoweringBase {
/// Return true if the specified indexed load is legal on this target.
bool isIndexedStoreLegal(unsigned IdxMode, EVT VT) const {
return VT.isSimple() &&
- (getIndexedStoreAction(IdxMode, VT.getSimpleVT()) == Legal ||
- getIndexedStoreAction(IdxMode, VT.getSimpleVT()) == Custom);
+ (getIndexedStoreAction(IdxMode, VT.getSimpleVT()) == Legal ||
+ getIndexedStoreAction(IdxMode, VT.getSimpleVT()) == Custom);
}
/// Return how the indexed load should be treated: either ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/157627
More information about the llvm-commits
mailing list