[llvm] Spaceship intrinsic for GSoC 2024 (PR #83227)

Miguel Raz Guzmán Macedo via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 27 22:10:19 PST 2024


https://github.com/miguelraz created https://github.com/llvm/llvm-project/pull/83227

Draft PR of my work so far.

Beware: Mistakes abound.

Checklist, based on a very rough understanding of [this previously mentioned PR](https://github.com/llvm/llvm-project/commit/905abe5b5d8bfb0e7819d9215a4b52c9f3296414)
* [X] Add intrinsic to ISDOpcodes.h
* [X] Add intrinsic to `expandThreeWayCmp` in TargetLowering.h
* [X] Add to tablegen

cc @nikic 

>From bfd853a12730f8b48d7e898c5077e1a3e48d0e45 Mon Sep 17 00:00:00 2001
From: miguelraz <miguelraz at ciencias.unam.mx>
Date: Tue, 27 Feb 2024 23:41:02 -0600
Subject: [PATCH 1/3] add ISDOpcode of USTHREEWAYCMP

---
 llvm/include/llvm/CodeGen/ISDOpcodes.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h
index 8cb0bc9fd98133..8e1dad95e41fc6 100644
--- a/llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -386,6 +386,13 @@ enum NodeType {
   SDIVFIXSAT,
   UDIVFIXSAT,
 
+  /// RESULT = [US]THREEWAYCMP(LHS, RHS) - Perform 3 way comparison and return
+  /// the values -1, 0, or 1 depending on whether the values compare lower,
+  /// equal
+  /// or greater.
+  UTHREEWAYCMP,
+  STHREEWAYCMP,
+
   /// Simple binary floating point operators.
   FADD,
   FSUB,

>From f1306f5970fc261dcae44994238830466463b7b1 Mon Sep 17 00:00:00 2001
From: miguelraz <miguelraz at ciencias.unam.mx>
Date: Tue, 27 Feb 2024 23:52:12 -0600
Subject: [PATCH 2/3] add expandThreeWayCMP to TargetLowering.h

---
 llvm/include/llvm/CodeGen/TargetLowering.h | 519 ++++++++++-----------
 1 file changed, 234 insertions(+), 285 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index f2e00aab8d5da2..a125510c7a6ea1 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -195,11 +195,11 @@ class 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,
@@ -215,13 +215,13 @@ class 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
@@ -230,18 +230,18 @@ class 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
@@ -249,20 +249,20 @@ class TargetLoweringBase {
   /// support for these atomic instructions, and also have different options
   /// w.r.t. what they should expand to.
   enum class AtomicExpansionKind {
-    None,    // Don't expand the instruction.
-    CastToInteger,    // Cast the atomic instruction to another type, e.g. from
-                      // floating-point to integer type.
+    None,          // Don't expand the instruction.
+    CastToInteger, // Cast the atomic instruction to another type, e.g. from
+                   // floating-point to integer type.
     LLSC,    // Expand the instruction into loadlinked/storeconditional; used
              // by ARM/AArch64.
     LLOnly,  // Expand the (load) instruction into just a load-linked, which has
              // greater atomic guarantees than a normal load.
     CmpXChg, // Expand the instruction into cmpxchg; used by at least X86.
-    MaskedIntrinsic,  // Use a target-specific intrinsic for the LL/SC loop.
-    BitTestIntrinsic, // Use a target-specific intrinsic for special bit
-                      // operations; used by X86.
-    CmpArithIntrinsic,// Use a target-specific intrinsic for special compare
-                      // operations; used by X86.
-    Expand,           // Generic expansion in terms of other atomic operations.
+    MaskedIntrinsic,   // Use a target-specific intrinsic for the LL/SC loop.
+    BitTestIntrinsic,  // Use a target-specific intrinsic for special bit
+                       // operations; used by X86.
+    CmpArithIntrinsic, // Use a target-specific intrinsic for special compare
+                       // operations; used by X86.
+    Expand,            // Generic expansion in terms of other atomic operations.
 
     // Rewrite to a non-atomic form for use in a known non-preemptible
     // environment.
@@ -278,9 +278,9 @@ class 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 ...),
@@ -348,9 +348,7 @@ class TargetLoweringBase {
   virtual ~TargetLoweringBase() = default;
 
   /// 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.
@@ -431,7 +429,8 @@ class 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;
   }
 
@@ -480,9 +479,7 @@ class 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; }
 
   /// Return true if multiple condition registers are available.
   bool hasMultipleConditionRegisters() const {
@@ -539,9 +536,7 @@ class 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 {
@@ -550,11 +545,7 @@ class 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
@@ -637,9 +628,7 @@ class 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,
@@ -648,19 +637,13 @@ class 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 {
@@ -713,9 +696,7 @@ class 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
@@ -738,9 +719,7 @@ class 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
@@ -869,9 +848,7 @@ class 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; }
@@ -908,9 +885,7 @@ class 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
@@ -929,8 +904,7 @@ class 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.
@@ -983,7 +957,8 @@ class 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!");
@@ -1144,8 +1119,8 @@ class 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;
@@ -1154,10 +1129,10 @@ class 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;
     IntrinsicInfo() = default;
@@ -1212,7 +1187,8 @@ class TargetLoweringBase {
   /// 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 getOperationAction(unsigned Op, EVT VT) const {
-    if (VT.isExtended()) return Expand;
+    if (VT.isExtended())
+      return Expand;
     // If a target-specific SDNode requires legalization, require the target
     // to provide custom legalization for it.
     if (Op >= std::size(OpActions[0]))
@@ -1264,11 +1240,16 @@ class 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"
     }
 
@@ -1285,8 +1266,8 @@ class 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
@@ -1299,8 +1280,8 @@ class 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
@@ -1313,9 +1294,9 @@ class 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
@@ -1397,9 +1378,10 @@ class TargetLoweringBase {
   /// 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;
+    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;
@@ -1422,9 +1404,10 @@ class 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];
@@ -1439,9 +1422,8 @@ class 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,
@@ -1462,8 +1444,8 @@ class 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
@@ -1476,8 +1458,8 @@ class 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 it is legal, needs
@@ -1512,8 +1494,8 @@ class TargetLoweringBase {
   /// extending
   virtual bool shouldExtendGSIndex(EVT VT, EVT &EltTy) const { return false; }
 
-  // Returns true if Extend can be folded into the index of a masked gathers/scatters
-  // on this target.
+  // Returns true if Extend can be folded into the index of a masked
+  // gathers/scatters on this target.
   virtual bool shouldRemoveExtendFromGSIndex(SDValue Extend, EVT DataVT) const {
     return false;
   }
@@ -1533,15 +1515,14 @@ class TargetLoweringBase {
   /// Return how the condition code should be treated: either it is legal, needs
   /// to be expanded to some other code sequence, or the target has a custom
   /// expander for it.
-  LegalizeAction
-  getCondCodeAction(ISD::CondCode CC, MVT VT) const {
+  LegalizeAction getCondCodeAction(ISD::CondCode CC, MVT VT) const {
     assert((unsigned)CC < std::size(CondCodeActions) &&
            ((unsigned)VT.SimpleTy >> 3) < std::size(CondCodeActions[0]) &&
            "Table isn't big enough!");
     // See setCondCodeAction for how this is encoded.
     uint32_t Shift = 4 * (VT.SimpleTy & 0x7);
     uint32_t Value = CondCodeActions[CC][VT.SimpleTy >> 3];
-    LegalizeAction Action = (LegalizeAction) ((Value >> Shift) & 0xF);
+    LegalizeAction Action = (LegalizeAction)((Value >> Shift) & 0xF);
     assert(Action != Promote && "Can't promote condition code!");
     return Action;
   }
@@ -1567,19 +1548,19 @@ class TargetLoweringBase {
     // See if this has an explicit type specified.
     std::map<std::pair<unsigned, MVT::SimpleValueType>,
              MVT::SimpleValueType>::const_iterator PTTI =
-      PromoteToType.find(std::make_pair(Op, VT.SimpleTy));
-    if (PTTI != PromoteToType.end()) return PTTI->second;
+        PromoteToType.find(std::make_pair(Op, VT.SimpleTy));
+    if (PTTI != PromoteToType.end())
+      return PTTI->second;
 
     assert((VT.isInteger() || VT.isFloatingPoint()) &&
            "Cannot autopromote this type, add it with AddPromotedToType.");
 
     MVT NVT = VT;
     do {
-      NVT = (MVT::SimpleValueType)(NVT.SimpleTy+1);
+      NVT = (MVT::SimpleValueType)(NVT.SimpleTy + 1);
       assert(NVT.isInteger() == VT.isInteger() && NVT != MVT::isVoid &&
              "Didn't find type to promote to!");
-    } while (!isTypeLegal(NVT) ||
-              getOperationAction(Op, NVT) == Promote);
+    } while (!isTypeLegal(NVT) || getOperationAction(Op, NVT) == Promote);
     return NVT;
   }
 
@@ -1631,7 +1612,6 @@ class TargetLoweringBase {
     return getValueType(DL, Ty, AllowUnknown);
   }
 
-
   /// Return the MVT corresponding to this LLVM type. See getValueType.
   MVT getSimpleValueType(const DataLayout &DL, Type *Ty,
                          bool AllowUnknown = false) const {
@@ -1657,8 +1637,8 @@ class TargetLoweringBase {
       EVT VT1;
       MVT RegisterVT;
       unsigned NumIntermediates;
-      (void)getVectorTypeBreakdown(Context, VT, VT1,
-                                   NumIntermediates, RegisterVT);
+      (void)getVectorTypeBreakdown(Context, VT, VT1, NumIntermediates,
+                                   RegisterVT);
       return RegisterVT;
     }
     if (VT.isInteger()) {
@@ -1756,7 +1736,7 @@ class TargetLoweringBase {
   /// perform for the specified node.
   bool hasTargetDAGCombine(ISD::NodeType NT) const {
     assert(unsigned(NT >> 3) < std::size(TargetDAGCombineArray));
-    return TargetDAGCombineArray[NT >> 3] & (1 << (NT&7));
+    return TargetDAGCombineArray[NT >> 3] & (1 << (NT & 7));
   }
 
   unsigned getGatherAllAliasesMaxDepth() const {
@@ -2006,9 +1986,13 @@ class TargetLoweringBase {
 
   /// Returns the name of the symbol used to emit stack probes or the empty
   /// string if not applicable.
-  virtual bool hasStackProbeSymbol(const MachineFunction &MF) const { return false; }
+  virtual bool hasStackProbeSymbol(const MachineFunction &MF) const {
+    return false;
+  }
 
-  virtual bool hasInlineStackProbe(const MachineFunction &MF) const { return false; }
+  virtual bool hasInlineStackProbe(const MachineFunction &MF) const {
+    return false;
+  }
 
   virtual StringRef getStackProbeSymbolName(const MachineFunction &MF) const {
     return "";
@@ -2195,7 +2179,8 @@ class TargetLoweringBase {
   // a dedicated instruction, if desired.
   // E.g., on ARM, if ldrex isn't followed by strex, the exclusive monitor would
   // be unnecessarily held, except if clrex, inserted by this hook, is executed.
-  virtual void emitAtomicCmpXchgNoStoreLLBalance(IRBuilderBase &Builder) const {}
+  virtual void emitAtomicCmpXchgNoStoreLLBalance(IRBuilderBase &Builder) const {
+  }
 
   /// Returns true if arguments should be sign-extended in lib calls.
   virtual bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const {
@@ -2203,9 +2188,7 @@ class TargetLoweringBase {
   }
 
   /// Returns true if arguments should be extended in lib calls.
-  virtual bool shouldExtendTypeInLibCall(EVT Type) const {
-    return true;
-  }
+  virtual bool shouldExtendTypeInLibCall(EVT Type) const { return true; }
 
   /// Returns how the given (atomic) load should be expanded by the
   /// IR-level AtomicExpand pass.
@@ -2246,9 +2229,10 @@ class TargetLoweringBase {
 
   /// Returns how the IR-level AtomicExpand pass should expand the given
   /// AtomicRMW, if at all. Default is to never expand.
-  virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const {
-    return RMW->isFloatingPointOperation() ?
-      AtomicExpansionKind::CmpXChg : AtomicExpansionKind::None;
+  virtual AtomicExpansionKind
+  shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const {
+    return RMW->isFloatingPointOperation() ? AtomicExpansionKind::CmpXChg
+                                           : AtomicExpansionKind::None;
   }
 
   /// Returns how the given atomic atomicrmw should be cast by the IR-level
@@ -2314,7 +2298,7 @@ class TargetLoweringBase {
     // registers.
     LegalizeTypeAction Action = getTypeAction(Context, VT);
     return Action != TypeExpandInteger && Action != TypeExpandFloat &&
-      Action != TypeSplitVector;
+           Action != TypeSplitVector;
   }
 
   virtual bool isProfitableToCombineMinNumMaxNum(EVT VT) const { return true; }
@@ -2322,17 +2306,15 @@ class TargetLoweringBase {
   /// Return true if a select of constants (select Cond, C1, C2) should be
   /// transformed into simple math ops with the condition value. For example:
   /// select Cond, C1, C1-1 --> add (zext Cond), C1-1
-  virtual bool convertSelectOfConstantsToMath(EVT VT) const {
-    return false;
-  }
+  virtual bool convertSelectOfConstantsToMath(EVT VT) const { return false; }
 
   /// Return true if it is profitable to transform an integer
   /// multiplication-by-constant into simpler operations like shifts and adds.
   /// This may be true if the target does not directly support the
   /// multiplication operation for the specified type or the sequence of simpler
   /// ops is faster than the multiply.
-  virtual bool decomposeMulByConstant(LLVMContext &Context,
-                                      EVT VT, SDValue C) const {
+  virtual bool decomposeMulByConstant(LLVMContext &Context, EVT VT,
+                                      SDValue C) const {
     return false;
   }
 
@@ -2679,8 +2661,8 @@ class TargetLoweringBase {
   /// targets also pass back when this should be done on intrinsics which
   /// load/store.
   virtual bool getAddrModeArguments(IntrinsicInst * /*I*/,
-                                    SmallVectorImpl<Value*> &/*Ops*/,
-                                    Type *&/*AccessTy*/) const {
+                                    SmallVectorImpl<Value *> & /*Ops*/,
+                                    Type *& /*AccessTy*/) const {
     return false;
   }
 
@@ -2693,9 +2675,9 @@ class TargetLoweringBase {
   /// no scale.
   struct AddrMode {
     GlobalValue *BaseGV = nullptr;
-    int64_t      BaseOffs = 0;
-    bool         HasBaseReg = false;
-    int64_t      Scale = 0;
+    int64_t BaseOffs = 0;
+    bool HasBaseReg = false;
+    int64_t Scale = 0;
     AddrMode() = default;
   };
 
@@ -2722,16 +2704,12 @@ class TargetLoweringBase {
   /// Return true if the specified immediate is legal icmp immediate, that is
   /// the target has icmp instructions which can compare a register against the
   /// immediate without having to materialize the immediate into a register.
-  virtual bool isLegalICmpImmediate(int64_t) const {
-    return true;
-  }
+  virtual bool isLegalICmpImmediate(int64_t) const { return true; }
 
   /// Return true if the specified immediate is legal add immediate, that is the
   /// target has add instructions which can add a register with the immediate
   /// without having to materialize the immediate into a register.
-  virtual bool isLegalAddImmediate(int64_t) const {
-    return true;
-  }
+  virtual bool isLegalAddImmediate(int64_t) const { return true; }
 
   /// Return true if the specified immediate is legal for the value input of a
   /// store instruction.
@@ -2746,16 +2724,14 @@ class TargetLoweringBase {
   /// AVX2 for example, there is a "psllw" instruction for the former case, but
   /// no simple instruction for a general "a << b" operation on vectors.
   /// This should also apply to lowering for vector funnel shifts (rotates).
-  virtual bool isVectorShiftByScalarCheap(Type *Ty) const {
-    return false;
-  }
+  virtual bool isVectorShiftByScalarCheap(Type *Ty) const { return false; }
 
   /// Given a shuffle vector SVI representing a vector splat, return a new
   /// scalar type of size equal to SVI's scalar type if the new type is more
   /// profitable. Returns nullptr otherwise. For example under MVE float splats
   /// are converted to integer to prevent the need to move from SPR to GPR
   /// registers.
-  virtual Type* shouldConvertSplatType(ShuffleVectorInst* SVI) const {
+  virtual Type *shouldConvertSplatType(ShuffleVectorInst *SVI) const {
     return nullptr;
   }
 
@@ -2805,7 +2781,8 @@ class TargetLoweringBase {
     case ISD::ABDS:
     case ISD::ABDU:
       return true;
-    default: return false;
+    default:
+      return false;
     }
   }
 
@@ -2841,9 +2818,7 @@ class TargetLoweringBase {
   /// ToTy. e.g. On x86 it's free to truncate a i32 value in register EAX to i16
   /// by referencing its sub-register AX.
   /// Targets must return false when FromTy <= ToTy.
-  virtual bool isTruncateFree(Type *FromTy, Type *ToTy) const {
-    return false;
-  }
+  virtual bool isTruncateFree(Type *FromTy, Type *ToTy) const { return false; }
 
   /// Return true if a truncation from FromTy to ToTy is permitted when deciding
   /// whether a call is in tail position. Typically this means that both results
@@ -2936,9 +2911,7 @@ class TargetLoweringBase {
   /// explicit truncate, which is not necessarily free, but this function
   /// does not deal with those cases.
   /// Targets must return false when FromTy >= ToTy.
-  virtual bool isZExtFree(Type *FromTy, Type *ToTy) const {
-    return false;
-  }
+  virtual bool isZExtFree(Type *FromTy, Type *ToTy) const { return false; }
 
   virtual bool isZExtFree(EVT FromTy, EVT ToTy) const { return false; }
   virtual bool isZExtFree(LLT FromTy, LLT ToTy, const DataLayout &DL,
@@ -3214,9 +3187,7 @@ class TargetLoweringBase {
 
   /// Try to convert an extract element of a vector binary operation into an
   /// extract element followed by a scalar operation.
-  virtual bool shouldScalarizeBinop(SDValue VecOp) const {
-    return false;
-  }
+  virtual bool shouldScalarizeBinop(SDValue VecOp) const { return false; }
 
   /// Return true if extraction of a scalar element from the given vector type
   /// at the given index is cheap. For example, if scalar operations occur on
@@ -3352,8 +3323,8 @@ class TargetLoweringBase {
   //  GlobalISel Hooks
   //===----------------------------------------------------------------------===//
   /// Check whether or not \p MI needs to be moved close to its uses.
-  virtual bool shouldLocalize(const MachineInstr &MI, const TargetTransformInfo *TTI) const;
-
+  virtual bool shouldLocalize(const MachineInstr &MI,
+                              const TargetTransformInfo *TTI) const;
 
 private:
   const TargetMachine &TM;
@@ -3375,7 +3346,7 @@ class TargetLoweringBase {
   /// instructions. For example, BypassSlowDivWidths[32,8] tells the code
   /// generator to bypass 32-bit integer div/rem with an 8-bit unsigned integer
   /// div/rem when the operands are positive and less than 256.
-  DenseMap <unsigned int, unsigned int> BypassSlowDivWidths;
+  DenseMap<unsigned int, unsigned int> BypassSlowDivWidths;
 
   /// Tells the code generator that it shouldn't generate extra flow control
   /// instructions and should attempt to combine flow control instructions via
@@ -3503,7 +3474,7 @@ class TargetLoweringBase {
   /// callbacks for by calling setTargetDAGCombine(), which sets a bit in this
   /// array.
   unsigned char
-  TargetDAGCombineArray[(ISD::BUILTIN_OP_END+CHAR_BIT-1)/CHAR_BIT];
+      TargetDAGCombineArray[(ISD::BUILTIN_OP_END + CHAR_BIT - 1) / CHAR_BIT];
 
   /// For operations that must be promoted to a specific type, this holds the
   /// destination type.  This map should be sparse, so don't hold it as an
@@ -3512,7 +3483,7 @@ class TargetLoweringBase {
   /// Targets add entries to this map with AddPromotedToType(..), clients access
   /// this with getTypeToPromoteTo(..).
   std::map<std::pair<unsigned, MVT::SimpleValueType>, MVT::SimpleValueType>
-    PromoteToType;
+      PromoteToType;
 
   /// Stores the name each libcall.
   const char *LibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL + 1];
@@ -3694,17 +3665,15 @@ class TargetLowering : public TargetLoweringBase {
     return MRI.hasOneNonDBGUse(N0);
   }
 
-  virtual bool isSDNodeAlwaysUniform(const SDNode * N) const {
-    return false;
-  }
+  virtual bool isSDNodeAlwaysUniform(const SDNode *N) const { return false; }
 
   /// Returns true by value, base pointer and offset pointer and addressing mode
   /// by reference if the node's address can be legally represented as
   /// pre-indexed load / store address.
-  virtual bool getPreIndexedAddressParts(SDNode * /*N*/, SDValue &/*Base*/,
-                                         SDValue &/*Offset*/,
-                                         ISD::MemIndexedMode &/*AM*/,
-                                         SelectionDAG &/*DAG*/) const {
+  virtual bool getPreIndexedAddressParts(SDNode * /*N*/, SDValue & /*Base*/,
+                                         SDValue & /*Offset*/,
+                                         ISD::MemIndexedMode & /*AM*/,
+                                         SelectionDAG & /*DAG*/) const {
     return false;
   }
 
@@ -3712,10 +3681,10 @@ class TargetLowering : public TargetLoweringBase {
   /// by reference if this node can be combined with a load / store to form a
   /// post-indexed load / store.
   virtual bool getPostIndexedAddressParts(SDNode * /*N*/, SDNode * /*Op*/,
-                                          SDValue &/*Base*/,
-                                          SDValue &/*Offset*/,
-                                          ISD::MemIndexedMode &/*AM*/,
-                                          SelectionDAG &/*DAG*/) const {
+                                          SDValue & /*Base*/,
+                                          SDValue & /*Offset*/,
+                                          ISD::MemIndexedMode & /*AM*/,
+                                          SelectionDAG & /*DAG*/) const {
     return false;
   }
 
@@ -3734,7 +3703,7 @@ class TargetLowering : public TargetLoweringBase {
   virtual const MCExpr *
   LowerCustomJumpTableEntry(const MachineJumpTableInfo * /*MJTI*/,
                             const MachineBasicBlock * /*MBB*/, unsigned /*uid*/,
-                            MCContext &/*Ctx*/) const {
+                            MCContext & /*Ctx*/) const {
     llvm_unreachable("Need to implement this hook if target has custom JTIs");
   }
 
@@ -3744,9 +3713,9 @@ class TargetLowering : public TargetLoweringBase {
 
   /// This returns the relocation base for the given PIC jumptable, the same as
   /// getPICJumpTableRelocBase, but as an MCExpr.
-  virtual const MCExpr *
-  getPICJumpTableRelocBaseExpr(const MachineFunction *MF,
-                               unsigned JTI, MCContext &Ctx) const;
+  virtual const MCExpr *getPICJumpTableRelocBaseExpr(const MachineFunction *MF,
+                                                     unsigned JTI,
+                                                     MCContext &Ctx) const;
 
   /// Return true if folding a constant offset with the given GlobalAddress is
   /// legal.  It is frequently not legal in PIC relocation models.
@@ -3791,9 +3760,9 @@ class TargetLowering : public TargetLoweringBase {
   /// registers are the same as from the calling function.  This needs to be
   /// checked for tail call eligibility.
   bool parametersInCSRMatch(const MachineRegisterInfo &MRI,
-      const uint32_t *CallerPreservedMask,
-      const SmallVectorImpl<CCValAssign> &ArgLocs,
-      const SmallVectorImpl<SDValue> &OutVals) const;
+                            const uint32_t *CallerPreservedMask,
+                            const SmallVectorImpl<CCValAssign> &ArgLocs,
+                            const SmallVectorImpl<SDValue> &OutVals) const;
 
   //===--------------------------------------------------------------------===//
   // TargetLowering Optimization Methods
@@ -3809,9 +3778,8 @@ class TargetLowering : public TargetLoweringBase {
     SDValue Old;
     SDValue New;
 
-    explicit TargetLoweringOpt(SelectionDAG &InDAG,
-                               bool LT, bool LO) :
-      DAG(InDAG), LegalTys(LT), LegalOps(LO) {}
+    explicit TargetLoweringOpt(SelectionDAG &InDAG, bool LT, bool LO)
+        : DAG(InDAG), LegalTys(LT), LegalOps(LO) {}
 
     bool LegalTypes() const { return LegalTys; }
     bool LegalOperations() const { return LegalOps; }
@@ -3823,11 +3791,11 @@ class TargetLowering : public TargetLoweringBase {
     }
   };
 
-  /// Determines the optimal series of memory ops to replace the memset / memcpy.
-  /// Return true if the number of memory ops is below the threshold (Limit).
-  /// Note that this is always the case when Limit is ~0.
-  /// It returns the types of the sequence of memory ops to perform
-  /// memset / memcpy by reference.
+  /// Determines the optimal series of memory ops to replace the memset /
+  /// memcpy. Return true if the number of memory ops is below the threshold
+  /// (Limit). Note that this is always the case when Limit is ~0. It returns
+  /// the types of the sequence of memory ops to perform memset / memcpy by
+  /// reference.
   virtual bool
   findOptimalMemOpLowering(std::vector<EVT> &MemOps, unsigned Limit,
                            const MemOp &Op, unsigned DstAS, unsigned SrcAS,
@@ -3956,8 +3924,7 @@ class TargetLowering : public TargetLoweringBase {
   /// or one and return them in the KnownZero/KnownOne bitsets. The DemandedElts
   /// argument allows us to only collect the known bits that are shared by the
   /// requested vector elements.
-  virtual void computeKnownBitsForTargetNode(const SDValue Op,
-                                             KnownBits &Known,
+  virtual void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known,
                                              const APInt &DemandedElts,
                                              const SelectionDAG &DAG,
                                              unsigned Depth = 0) const;
@@ -3984,8 +3951,7 @@ class TargetLowering : public TargetLoweringBase {
   /// Determine which of the bits of FrameIndex \p FIOp are known to be 0.
   /// Default implementation computes low bits based on alignment
   /// information. This should preserve known bits passed into it.
-  virtual void computeKnownBitsForFrameIndex(int FIOp,
-                                             KnownBits &Known,
+  virtual void computeKnownBitsForFrameIndex(int FIOp, KnownBits &Known,
                                              const MachineFunction &MF) const;
 
   /// This method can be implemented by targets that want to expose additional
@@ -4001,11 +3967,9 @@ class TargetLowering : public TargetLoweringBase {
   /// information about sign bits to GlobalISel combiners. The DemandedElts
   /// argument allows us to only collect the minimum sign bits that are shared
   /// by the requested vector elements.
-  virtual unsigned computeNumSignBitsForTargetInstr(GISelKnownBits &Analysis,
-                                                    Register R,
-                                                    const APInt &DemandedElts,
-                                                    const MachineRegisterInfo &MRI,
-                                                    unsigned Depth = 0) const;
+  virtual unsigned computeNumSignBitsForTargetInstr(
+      GISelKnownBits &Analysis, Register R, const APInt &DemandedElts,
+      const MachineRegisterInfo &MRI, unsigned Depth = 0) const;
 
   /// Attempt to simplify any target nodes based on the demanded vector
   /// elements, returning true on success. Otherwise, analyze the expression and
@@ -4021,12 +3985,9 @@ class TargetLowering : public TargetLoweringBase {
   /// expression and return a mask of KnownOne and KnownZero bits for the
   /// expression (used to simplify the caller).  The KnownZero/One bits may only
   /// be accurate for those bits in the Demanded masks.
-  virtual bool SimplifyDemandedBitsForTargetNode(SDValue Op,
-                                                 const APInt &DemandedBits,
-                                                 const APInt &DemandedElts,
-                                                 KnownBits &Known,
-                                                 TargetLoweringOpt &TLO,
-                                                 unsigned Depth = 0) const;
+  virtual bool SimplifyDemandedBitsForTargetNode(
+      SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts,
+      KnownBits &Known, TargetLoweringOpt &TLO, unsigned Depth = 0) const;
 
   /// More limited version of SimplifyDemandedBits that can be used to "look
   /// through" ops that don't contribute to the DemandedBits/DemandedElts -
@@ -4065,8 +4026,7 @@ class TargetLowering : public TargetLoweringBase {
   /// If \p SNaN is false, \returns true if \p Op is known to never be any
   /// NaN. If \p sNaN is true, returns if \p Op is known to never be a signaling
   /// NaN.
-  virtual bool isKnownNeverNaNForTargetNode(SDValue Op,
-                                            const SelectionDAG &DAG,
+  virtual bool isKnownNeverNaNForTargetNode(SDValue Op, const SelectionDAG &DAG,
                                             bool SNaN = false,
                                             unsigned Depth = 0) const;
 
@@ -4085,15 +4045,15 @@ class TargetLowering : public TargetLoweringBase {
   }
 
   struct DAGCombinerInfo {
-    void *DC;  // The DAG Combiner object.
+    void *DC; // The DAG Combiner object.
     CombineLevel Level;
     bool CalledByLegalizer;
 
   public:
     SelectionDAG &DAG;
 
-    DAGCombinerInfo(SelectionDAG &dag, CombineLevel level,  bool cl, void *dc)
-      : DC(dc), Level(level), CalledByLegalizer(cl), DAG(dag) {}
+    DAGCombinerInfo(SelectionDAG &dag, CombineLevel level, bool cl, void *dc)
+        : DC(dc), Level(level), CalledByLegalizer(cl), DAG(dag) {}
 
     bool isBeforeLegalize() const { return Level == BeforeLegalizeTypes; }
     bool isBeforeLegalizeOps() const { return Level < AfterLegalizeVectorOps; }
@@ -4133,8 +4093,8 @@ class TargetLowering : public TargetLoweringBase {
 
   /// Returns true (and the GlobalValue and the offset) if the node is a
   /// GlobalAddress + offset.
-  virtual bool
-  isGAPlusOffset(SDNode *N, const GlobalValue* &GA, int64_t &Offset) const;
+  virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA,
+                              int64_t &Offset) const;
 
   /// This method will be invoked for all target nodes and for any
   /// target-independent nodes that the target has registered with invoke it
@@ -4234,21 +4194,17 @@ class TargetLowering : public TargetLoweringBase {
   /// This method query the target whether it is beneficial for dag combiner to
   /// promote the specified node. If true, it should return the desired
   /// promotion type by reference.
-  virtual bool IsDesirableToPromoteOp(SDValue /*Op*/, EVT &/*PVT*/) const {
+  virtual bool IsDesirableToPromoteOp(SDValue /*Op*/, EVT & /*PVT*/) const {
     return false;
   }
 
   /// Return true if the target supports swifterror attribute. It optimizes
   /// loads and stores to reading and writing a specific register.
-  virtual bool supportSwiftError() const {
-    return false;
-  }
+  virtual bool supportSwiftError() const { return false; }
 
   /// Return true if the target supports that a subset of CSRs for the given
   /// machine function is handled explicitly via copies.
-  virtual bool supportSplitCSR(MachineFunction *MF) const {
-    return false;
-  }
+  virtual bool supportSplitCSR(MachineFunction *MF) const { return false; }
 
   /// Return true if the target supports kcfi operand bundles.
   virtual bool supportKCFIBundles() const { return false; }
@@ -4321,9 +4277,10 @@ class TargetLowering : public TargetLoweringBase {
 
   /// Target-specific splitting of values into parts that fit a register
   /// storing a legal type
-  virtual bool splitValueIntoRegisterParts(
-      SelectionDAG & DAG, const SDLoc &DL, SDValue Val, SDValue *Parts,
-      unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC) const {
+  virtual bool
+  splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val,
+                              SDValue *Parts, unsigned NumParts, MVT PartVT,
+                              std::optional<CallingConv::ID> CC) const {
     return false;
   }
 
@@ -4371,16 +4328,16 @@ class TargetLowering : public TargetLoweringBase {
   struct CallLoweringInfo {
     SDValue Chain;
     Type *RetTy = nullptr;
-    bool RetSExt           : 1;
-    bool RetZExt           : 1;
-    bool IsVarArg          : 1;
-    bool IsInReg           : 1;
-    bool DoesNotReturn     : 1;
+    bool RetSExt : 1;
+    bool RetZExt : 1;
+    bool IsVarArg : 1;
+    bool IsInReg : 1;
+    bool DoesNotReturn : 1;
     bool IsReturnValueUsed : 1;
-    bool IsConvergent      : 1;
-    bool IsPatchPoint      : 1;
+    bool IsConvergent : 1;
+    bool IsPatchPoint : 1;
     bool IsPreallocated : 1;
-    bool NoMerge           : 1;
+    bool NoMerge : 1;
 
     // IsTailCall should be modified by implementations of
     // TargetLowering::LowerCall that perform tail call conversions.
@@ -4405,8 +4362,8 @@ class TargetLowering : public TargetLoweringBase {
     CallLoweringInfo(SelectionDAG &DAG)
         : RetSExt(false), RetZExt(false), IsVarArg(false), IsInReg(false),
           DoesNotReturn(false), IsReturnValueUsed(true), IsConvergent(false),
-          IsPatchPoint(false), IsPreallocated(false), NoMerge(false),
-          DAG(DAG) {}
+          IsPatchPoint(false), IsPreallocated(false), NoMerge(false), DAG(DAG) {
+    }
 
     CallLoweringInfo &setDebugLoc(const SDLoc &dl) {
       DL = dl;
@@ -4524,7 +4481,7 @@ class TargetLowering : public TargetLoweringBase {
       return *this;
     }
 
-    CallLoweringInfo &setIsPostTypeLegalization(bool Value=true) {
+    CallLoweringInfo &setIsPostTypeLegalization(bool Value = true) {
       IsPostTypeLegalization = Value;
       return *this;
     }
@@ -4534,9 +4491,7 @@ class TargetLowering : public TargetLoweringBase {
       return *this;
     }
 
-    ArgListTy &getArgs() {
-      return Args;
-    }
+    ArgListTy &getArgs() { return Args; }
   };
 
   /// This structure is used to pass arguments to makeLibCall function.
@@ -4595,9 +4550,8 @@ class TargetLowering : public TargetLoweringBase {
   /// and the values to be returned by the call are described by the Ins
   /// array. The implementation should fill in the InVals array with legal-type
   /// return values from the call, and return the resulting token chain value.
-  virtual SDValue
-    LowerCall(CallLoweringInfo &/*CLI*/,
-              SmallVectorImpl<SDValue> &/*InVals*/) const {
+  virtual SDValue LowerCall(CallLoweringInfo & /*CLI*/,
+                            SmallVectorImpl<SDValue> & /*InVals*/) const {
     llvm_unreachable("Not Implemented");
   }
 
@@ -4608,10 +4562,9 @@ class TargetLowering : public TargetLoweringBase {
   /// described by the Outs array can fit into the return registers.  If false
   /// is returned, an sret-demotion is performed.
   virtual bool CanLowerReturn(CallingConv::ID /*CallConv*/,
-                              MachineFunction &/*MF*/, bool /*isVarArg*/,
-               const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
-               LLVMContext &/*Context*/) const
-  {
+                              MachineFunction & /*MF*/, bool /*isVarArg*/,
+                              const SmallVectorImpl<ISD::OutputArg> & /*Outs*/,
+                              LLVMContext & /*Context*/) const {
     // Return true by default to get preexisting behavior.
     return true;
   }
@@ -4633,27 +4586,25 @@ class TargetLowering : public TargetLoweringBase {
   ///
   /// This is used to determine whether it is possible to codegen a libcall as
   /// tail call at legalization time.
-  virtual bool isUsedByReturnOnly(SDNode *, SDValue &/*Chain*/) const {
+  virtual bool isUsedByReturnOnly(SDNode *, SDValue & /*Chain*/) const {
     return false;
   }
 
   /// Return true if the target may be able emit the call instruction as a tail
   /// call. This is used by optimization passes to determine if it's profitable
   /// to duplicate return instructions to enable tailcall optimization.
-  virtual bool mayBeEmittedAsTailCall(const CallInst *) const {
-    return false;
-  }
+  virtual bool mayBeEmittedAsTailCall(const CallInst *) const { return false; }
 
   /// Return the builtin name for the __builtin___clear_cache intrinsic
   /// Default is to invoke the clear cache library call
-  virtual const char * getClearCacheBuiltinName() const {
+  virtual const char *getClearCacheBuiltinName() const {
     return "__clear_cache";
   }
 
   /// Return the register ID of the name passed in. Used by named register
   /// global variables extension. There is no target-independent behaviour
   /// so the default action is to bail.
-  virtual Register getRegisterByName(const char* RegName, LLT Ty,
+  virtual Register getRegisterByName(const char *RegName, LLT Ty,
                                      const MachineFunction &MF) const {
     report_fatal_error("Named registers not implemented for this target");
   }
@@ -4665,7 +4616,7 @@ class TargetLowering : public TargetLoweringBase {
   /// conventions. The frontend should handle this and include all of the
   /// necessary information.
   virtual EVT getTypeForExtReturn(LLVMContext &Context, EVT VT,
-                                       ISD::NodeType /*ExtendKind*/) const {
+                                  ISD::NodeType /*ExtendKind*/) const {
     EVT MinVT = getRegisterType(MVT::i32);
     return VT.bitsLT(MinVT) ? MinVT : VT;
   }
@@ -4747,8 +4698,8 @@ class TargetLowering : public TargetLoweringBase {
   /// If the target has no operations that require custom lowering, it need not
   /// implement this.  The default implementation aborts.
   virtual void ReplaceNodeResults(SDNode * /*N*/,
-                                  SmallVectorImpl<SDValue> &/*Results*/,
-                                  SelectionDAG &/*DAG*/) const {
+                                  SmallVectorImpl<SDValue> & /*Results*/,
+                                  SelectionDAG & /*DAG*/) const {
     llvm_unreachable("ReplaceNodeResults not implemented for this target!");
   }
 
@@ -4773,34 +4724,32 @@ class TargetLowering : public TargetLoweringBase {
   /// llvm code if it wants to.  This is useful for turning simple inline asms
   /// into LLVM intrinsics, which gives the compiler more information about the
   /// behavior of the code.
-  virtual bool ExpandInlineAsm(CallInst *) const {
-    return false;
-  }
+  virtual bool ExpandInlineAsm(CallInst *) const { return false; }
 
   enum ConstraintType {
-    C_Register,            // Constraint represents specific register(s).
-    C_RegisterClass,       // Constraint represents any of register(s) in class.
-    C_Memory,              // Memory constraint.
-    C_Address,             // Address constraint.
-    C_Immediate,           // Requires an immediate.
-    C_Other,               // Something else.
-    C_Unknown              // Unsupported constraint.
+    C_Register,      // Constraint represents specific register(s).
+    C_RegisterClass, // Constraint represents any of register(s) in class.
+    C_Memory,        // Memory constraint.
+    C_Address,       // Address constraint.
+    C_Immediate,     // Requires an immediate.
+    C_Other,         // Something else.
+    C_Unknown        // Unsupported constraint.
   };
 
   enum ConstraintWeight {
     // Generic weights.
-    CW_Invalid  = -1,     // No match.
-    CW_Okay     = 0,      // Acceptable.
-    CW_Good     = 1,      // Good weight.
-    CW_Better   = 2,      // Better weight.
-    CW_Best     = 3,      // Best weight.
+    CW_Invalid = -1, // No match.
+    CW_Okay = 0,     // Acceptable.
+    CW_Good = 1,     // Good weight.
+    CW_Better = 2,   // Better weight.
+    CW_Best = 3,     // Best weight.
 
     // Well-known weights.
-    CW_SpecificReg  = CW_Okay,    // Specific register operands.
-    CW_Register     = CW_Good,    // Register operands.
-    CW_Memory       = CW_Better,  // Memory operands.
-    CW_Constant     = CW_Best,    // Constant operand.
-    CW_Default      = CW_Okay     // Default or don't know type.
+    CW_SpecificReg = CW_Okay, // Specific register operands.
+    CW_Register = CW_Good,    // Register operands.
+    CW_Memory = CW_Better,    // Memory operands.
+    CW_Constant = CW_Best,    // Constant operand.
+    CW_Default = CW_Okay      // Default or don't know type.
   };
 
   /// This contains information for each constraint that we are lowering.
@@ -4847,20 +4796,20 @@ class TargetLowering : public TargetLoweringBase {
 
   /// Examine constraint type and operand type and determine a weight value.
   /// The operand object must already have been set up with the operand type.
-  virtual ConstraintWeight getMultipleConstraintMatchWeight(
-      AsmOperandInfo &info, int maIndex) const;
+  virtual ConstraintWeight
+  getMultipleConstraintMatchWeight(AsmOperandInfo &info, int maIndex) const;
 
   /// Examine constraint string and operand type and determine a weight value.
   /// The operand object must already have been set up with the operand type.
-  virtual ConstraintWeight getSingleConstraintMatchWeight(
-      AsmOperandInfo &info, const char *constraint) const;
+  virtual ConstraintWeight
+  getSingleConstraintMatchWeight(AsmOperandInfo &info,
+                                 const char *constraint) const;
 
   /// Determines the constraint code and constraint type to use for the specific
   /// AsmOperandInfo, setting OpInfo.ConstraintCode and OpInfo.ConstraintType.
   /// If the actual operand being passed in is available, it can be passed in as
   /// Op, otherwise an empty SDValue can be passed.
-  virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo,
-                                      SDValue Op,
+  virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo, SDValue Op,
                                       SelectionDAG *DAG = nullptr) const;
 
   /// Given a constraint, return the type of constraint it is for this target.
@@ -4957,9 +4906,7 @@ class TargetLowering : public TargetLoweringBase {
   /// divisor. If the transform should never be done, return zero. If the
   /// transform should be done, return the minimum number of divisor uses
   /// that must exist.
-  virtual unsigned combineRepeatedFPDivisors() const {
-    return 0;
-  }
+  virtual unsigned combineRepeatedFPDivisors() const { return 0; }
 
   /// Hooks for building estimates in place of slower divisions and square
   /// roots.
@@ -5275,6 +5222,10 @@ class TargetLowering : public TargetLoweringBase {
   /// method accepts integers as its arguments.
   SDValue expandAddSubSat(SDNode *Node, SelectionDAG &DAG) const;
 
+  /// Method for building the DAG expansion of ISD::[US]THREEWAYCMP. This
+  /// method accepts integers as its arguments.
+  SDValue expandThreeWayCmp(SDNode *Node, SelectionDAG &DAG) const;
+
   /// Method for building the DAG expansion of ISD::[US]SHLSAT. This
   /// method accepts integers as its arguments.
   SDValue expandShlSat(SDNode *Node, SelectionDAG &DAG) const;
@@ -5287,9 +5238,9 @@ class TargetLowering : public TargetLoweringBase {
   /// method accepts integers as its arguments.
   /// Note: This method may fail if the division could not be performed
   /// within the type. Clients must retry with a wider type if this happens.
-  SDValue expandFixedPointDiv(unsigned Opcode, const SDLoc &dl,
-                              SDValue LHS, SDValue RHS,
-                              unsigned Scale, SelectionDAG &DAG) const;
+  SDValue expandFixedPointDiv(unsigned Opcode, const SDLoc &dl, SDValue LHS,
+                              SDValue RHS, unsigned Scale,
+                              SelectionDAG &DAG) const;
 
   /// Method for building the DAG expansion of ISD::U(ADD|SUB)O. Expansion
   /// always suceeds and populates the Result and Overflow arguments.
@@ -5390,9 +5341,7 @@ class TargetLowering : public TargetLoweringBase {
 
   /// If this function returns true, SelectionDAGBuilder emits a
   /// LOAD_STACK_GUARD node when it is lowering Intrinsic::stackprotector.
-  virtual bool useLoadStackGuardNode() const {
-    return false;
-  }
+  virtual bool useLoadStackGuardNode() const { return false; }
 
   virtual SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val,
                                       const SDLoc &DL) const {

>From e4ed0df5c4265540f1b6ff6c4ad60444269ca463 Mon Sep 17 00:00:00 2001
From: miguelraz <miguelraz at ciencias.unam.mx>
Date: Wed, 28 Feb 2024 00:05:54 -0600
Subject: [PATCH 3/3] add int_[us]threewaycmp def to Instrinsics.td

---
 llvm/include/llvm/IR/Intrinsics.td | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 0f13d25eb30ebf..7021849be4b9fe 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -1527,6 +1527,12 @@ def int_umin : DefaultAttrsIntrinsic<
     [llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
     [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
 
+//===------------------ Integer 3 Way Compare Intrinsics --------------------===//
+//
+def int_sthreewaycmp : 
+
+def int_uthreewaycmp : 
+
 //===------------------------- Memory Use Markers -------------------------===//
 //
 def int_lifetime_start  : DefaultAttrsIntrinsic<[],



More information about the llvm-commits mailing list