[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