[llvm] [TTI][TLI] Support scalable immediates with isLegalAddImmediate (PR #84173)

via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 6 06:13:58 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-systemz

Author: Graham Hunter (huntergr-arm)

<details>
<summary>Changes</summary>

Adds a second parameter (default to 0) to isLegalAddImmediate, to represent a scalable immediate.

Extends the AArch64 implementation to match immediates based on vscale * base_register_size * immediate in the range [-32,31].

See the vscale-aware LSR RFC for reference: https://discourse.llvm.org/t/rfc-vscale-aware-loopstrengthreduce/77131


---
Full diff: https://github.com/llvm/llvm-project/pull/84173.diff


21 Files Affected:

- (modified) llvm/include/llvm/Analysis/TargetTransformInfo.h (+4-4) 
- (modified) llvm/include/llvm/Analysis/TargetTransformInfoImpl.h (+3-1) 
- (modified) llvm/include/llvm/CodeGen/BasicTTIImpl.h (+2-2) 
- (modified) llvm/include/llvm/CodeGen/TargetLowering.h (+2-2) 
- (modified) llvm/lib/Analysis/TargetTransformInfo.cpp (+3-2) 
- (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (+19-1) 
- (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.h (+1-1) 
- (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+2-1) 
- (modified) llvm/lib/Target/ARM/ARMISelLowering.h (+2-1) 
- (modified) llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp (+2-1) 
- (modified) llvm/lib/Target/LoongArch/LoongArchISelLowering.h (+1-1) 
- (modified) llvm/lib/Target/PowerPC/PPCISelLowering.cpp (+2-1) 
- (modified) llvm/lib/Target/PowerPC/PPCISelLowering.h (+2-1) 
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+3-2) 
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.h (+1-1) 
- (modified) llvm/lib/Target/SystemZ/SystemZISelLowering.cpp (+2-1) 
- (modified) llvm/lib/Target/SystemZ/SystemZISelLowering.h (+1-1) 
- (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+2-1) 
- (modified) llvm/lib/Target/X86/X86ISelLowering.h (+2-1) 
- (modified) llvm/unittests/Target/AArch64/CMakeLists.txt (+1) 
- (added) llvm/unittests/Target/AArch64/Immediates.cpp (+75) 


``````````diff
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h
index 4eab357f1b33b6..f9dd7bbc3dcec8 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -694,7 +694,7 @@ class TargetTransformInfo {
   /// 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.
-  bool isLegalAddImmediate(int64_t Imm) const;
+  bool isLegalAddImmediate(int64_t Imm, int64_t ScalableImm = 0) const;
 
   /// Return true if the specified immediate is legal icmp immediate,
   /// that is the target has icmp instructions which can compare a register
@@ -1834,7 +1834,7 @@ class TargetTransformInfo::Concept {
       APInt &UndefElts, APInt &UndefElts2, APInt &UndefElts3,
       std::function<void(Instruction *, unsigned, APInt, APInt &)>
           SimplifyAndSetOp) = 0;
-  virtual bool isLegalAddImmediate(int64_t Imm) = 0;
+  virtual bool isLegalAddImmediate(int64_t Imm, int64_t ScalableImm) = 0;
   virtual bool isLegalICmpImmediate(int64_t Imm) = 0;
   virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
                                      int64_t BaseOffset, bool HasBaseReg,
@@ -2292,8 +2292,8 @@ class TargetTransformInfo::Model final : public TargetTransformInfo::Concept {
         IC, II, DemandedElts, UndefElts, UndefElts2, UndefElts3,
         SimplifyAndSetOp);
   }
-  bool isLegalAddImmediate(int64_t Imm) override {
-    return Impl.isLegalAddImmediate(Imm);
+  bool isLegalAddImmediate(int64_t Imm, int64_t ScalableImm) override {
+    return Impl.isLegalAddImmediate(Imm, ScalableImm);
   }
   bool isLegalICmpImmediate(int64_t Imm) override {
     return Impl.isLegalICmpImmediate(Imm);
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index 95fb13d1c97154..7fbdfe3fc68437 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -214,7 +214,9 @@ class TargetTransformInfoImplBase {
   void getPeelingPreferences(Loop *, ScalarEvolution &,
                              TTI::PeelingPreferences &) const {}
 
-  bool isLegalAddImmediate(int64_t Imm) const { return false; }
+  bool isLegalAddImmediate(int64_t Imm, int64_t ScalableImm) const {
+    return false;
+  }
 
   bool isLegalICmpImmediate(int64_t Imm) const { return false; }
 
diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
index 61f6564e8cd79b..ac8cd28689d35a 100644
--- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
@@ -324,8 +324,8 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
     return nullptr;
   }
 
-  bool isLegalAddImmediate(int64_t imm) {
-    return getTLI()->isLegalAddImmediate(imm);
+  bool isLegalAddImmediate(int64_t Imm, int64_t ScalableImm) {
+    return getTLI()->isLegalAddImmediate(Imm, ScalableImm);
   }
 
   bool isLegalICmpImmediate(int64_t imm) {
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 2f164a460db843..57844dd82d6410 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -2766,8 +2766,8 @@ class TargetLoweringBase {
   /// 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, int64_t ScalableImm = 0) const {
+    return !ScalableImm;
   }
 
   /// Return true if the specified immediate is legal for the value input of a
diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp
index 15311be4dba277..8791ae4c3744e5 100644
--- a/llvm/lib/Analysis/TargetTransformInfo.cpp
+++ b/llvm/lib/Analysis/TargetTransformInfo.cpp
@@ -391,8 +391,9 @@ void TargetTransformInfo::getPeelingPreferences(Loop *L, ScalarEvolution &SE,
   return TTIImpl->getPeelingPreferences(L, SE, PP);
 }
 
-bool TargetTransformInfo::isLegalAddImmediate(int64_t Imm) const {
-  return TTIImpl->isLegalAddImmediate(Imm);
+bool TargetTransformInfo::isLegalAddImmediate(int64_t Imm,
+                                              int64_t ScalableImm) const {
+  return TTIImpl->isLegalAddImmediate(Imm, ScalableImm);
 }
 
 bool TargetTransformInfo::isLegalICmpImmediate(int64_t Imm) const {
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 2290223a06f8ef..e53e8ce6a3d227 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -16559,7 +16559,25 @@ LLT AArch64TargetLowering::getOptimalMemOpLLT(
 }
 
 // 12-bit optionally shifted immediates are legal for adds.
-bool AArch64TargetLowering::isLegalAddImmediate(int64_t Immed) const {
+bool AArch64TargetLowering::isLegalAddImmediate(int64_t Immed,
+                                                int64_t ScalableImm) const {
+  if (ScalableImm) {
+    // Scalable immediates require SVE support; mixed fixed + scalable
+    // immediates are not supported by the current instructions.
+    if (Immed || !Subtarget->hasSVE())
+      return false;
+
+    // addvl's immediates are in terms of the number of bytes in a register.
+    // Since there are 16 in the base supported size (128bits), we need to
+    // divide the immediate by that much to give us a useful immediate to
+    // multiply by vscale. We can't have a remainder as a result of this.
+    if (ScalableImm % 16 != 0)
+      return false;
+    int64_t Imm = ScalableImm / 16;
+
+    return Imm >= -32 && Imm <= 31;
+  }
+
   if (Immed == std::numeric_limits<int64_t>::min()) {
     LLVM_DEBUG(dbgs() << "Illegal add imm " << Immed
                       << ": avoid UB for INT64_MIN\n");
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index 68341c199e0a2a..adec93d7e6aea1 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -688,7 +688,7 @@ class AArch64TargetLowering : public TargetLowering {
   bool lowerInterleaveIntrinsicToStore(IntrinsicInst *II,
                                        StoreInst *SI) const override;
 
-  bool isLegalAddImmediate(int64_t) const override;
+  bool isLegalAddImmediate(int64_t Imm, int64_t ScalableImm = 0) const override;
   bool isLegalICmpImmediate(int64_t) const override;
 
   bool isMulAddWithConstProfitable(SDValue AddNode,
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index dc81178311b6d8..65a15f959ff4d9 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -19722,7 +19722,8 @@ bool ARMTargetLowering::isLegalICmpImmediate(int64_t Imm) const {
 /// *or sub* immediate, that is the target has add or sub instructions which can
 /// add a register with the immediate without having to materialize the
 /// immediate into a register.
-bool ARMTargetLowering::isLegalAddImmediate(int64_t Imm) const {
+bool ARMTargetLowering::isLegalAddImmediate(int64_t Imm,
+                                            int64_t ScalableImm) const {
   // Same encoding for add/sub, just flip the sign.
   int64_t AbsImm = std::abs(Imm);
   if (!Subtarget->isThumb())
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h
index b13ddf697cb806..70bbb15a1772f8 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.h
+++ b/llvm/lib/Target/ARM/ARMISelLowering.h
@@ -494,7 +494,8 @@ class VectorType;
     /// add immediate, that is the target has add instructions which can
     /// add a register and the immediate without having to materialize
     /// the immediate into a register.
-    bool isLegalAddImmediate(int64_t Imm) const override;
+    bool isLegalAddImmediate(int64_t Imm,
+                             int64_t ScalableImm = 0) const override;
 
     /// getPreIndexedAddressParts - returns true by value, base pointer and
     /// offset pointer and addressing mode by reference if the node's address
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index c8e955a23336d7..f975fc52b2f774 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -4933,7 +4933,8 @@ bool LoongArchTargetLowering::isLegalICmpImmediate(int64_t Imm) const {
   return isInt<12>(Imm);
 }
 
-bool LoongArchTargetLowering::isLegalAddImmediate(int64_t Imm) const {
+bool LoongArchTargetLowering::isLegalAddImmediate(int64_t Imm,
+                                                  int64_t ScalableImm) const {
   return isInt<12>(Imm);
 }
 
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
index 9e9ac0b8269291..b59a4dfcd9ead3 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
@@ -222,7 +222,7 @@ class LoongArchTargetLowering : public TargetLowering {
                              Instruction *I = nullptr) const override;
 
   bool isLegalICmpImmediate(int64_t Imm) const override;
-  bool isLegalAddImmediate(int64_t Imm) const override;
+  bool isLegalAddImmediate(int64_t Imm, int64_t ScalableImm = 0) const override;
   bool isZExtFree(SDValue Val, EVT VT2) const override;
   bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const override;
 
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 68c80dd9aa5c76..2aaf7b24d52544 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -17300,7 +17300,8 @@ bool PPCTargetLowering::isLegalICmpImmediate(int64_t Imm) const {
   return isInt<16>(Imm) || isUInt<16>(Imm);
 }
 
-bool PPCTargetLowering::isLegalAddImmediate(int64_t Imm) const {
+bool PPCTargetLowering::isLegalAddImmediate(int64_t Imm,
+                                            int64_t ScalableImm) const {
   return isInt<16>(Imm) || isUInt<16>(Imm);
 }
 
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index 0bdfdcd15441f4..a1b404bd655b36 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -1023,7 +1023,8 @@ namespace llvm {
     /// add immediate, that is the target has add instructions which can
     /// add a register and the immediate without having to materialize
     /// the immediate into a register.
-    bool isLegalAddImmediate(int64_t Imm) const override;
+    bool isLegalAddImmediate(int64_t Imm,
+                             int64_t ScalableImm = 0) const override;
 
     /// isTruncateFree - Return true if it's free to truncate a value of
     /// type Ty1 to type Ty2. e.g. On PPC it's free to truncate a i64 value in
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 4c3dc63afd878d..c6b02b8b26856b 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -1783,8 +1783,9 @@ bool RISCVTargetLowering::isLegalICmpImmediate(int64_t Imm) const {
   return isInt<12>(Imm);
 }
 
-bool RISCVTargetLowering::isLegalAddImmediate(int64_t Imm) const {
-  return isInt<12>(Imm);
+bool RISCVTargetLowering::isLegalAddImmediate(int64_t Imm,
+                                              int64_t ScalableImm) const {
+  return !ScalableImm && isInt<12>(Imm);
 }
 
 // On RV32, 64-bit integers are split into their high and low parts and held
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index f90cb4df604761..61fb5809c9b8dd 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -475,7 +475,7 @@ class RISCVTargetLowering : public TargetLowering {
                              unsigned AS,
                              Instruction *I = nullptr) const override;
   bool isLegalICmpImmediate(int64_t Imm) const override;
-  bool isLegalAddImmediate(int64_t Imm) const override;
+  bool isLegalAddImmediate(int64_t Imm, int64_t ScalableImm = 0) const override;
   bool isTruncateFree(Type *SrcTy, Type *DstTy) const override;
   bool isTruncateFree(EVT SrcVT, EVT DstVT) const override;
   bool isZExtFree(SDValue Val, EVT VT2) const override;
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index 3b85a6ac0371ed..a2aa33ff059489 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -944,7 +944,8 @@ bool SystemZTargetLowering::isLegalICmpImmediate(int64_t Imm) const {
   return isInt<32>(Imm) || isUInt<32>(Imm);
 }
 
-bool SystemZTargetLowering::isLegalAddImmediate(int64_t Imm) const {
+bool SystemZTargetLowering::isLegalAddImmediate(int64_t Imm,
+                                                int64_t ScalableImm) const {
   // We can use ALGFI or SLGFI.
   return isUInt<32>(Imm) || isUInt<32>(-Imm);
 }
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
index baf4ba41654879..274b23b4d28935 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
@@ -477,7 +477,7 @@ class SystemZTargetLowering : public TargetLowering {
   AtomicExpansionKind
   shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const override;
   bool isLegalICmpImmediate(int64_t Imm) const override;
-  bool isLegalAddImmediate(int64_t Imm) const override;
+  bool isLegalAddImmediate(int64_t Imm, int64_t ScalableImm = 0) const override;
   bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty,
                              unsigned AS,
                              Instruction *I = nullptr) const override;
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 6eaaec407dbb08..d5f5ef24e56d5d 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -33882,7 +33882,8 @@ bool X86TargetLowering::isLegalICmpImmediate(int64_t Imm) const {
   return isInt<32>(Imm);
 }
 
-bool X86TargetLowering::isLegalAddImmediate(int64_t Imm) const {
+bool X86TargetLowering::isLegalAddImmediate(int64_t Imm,
+                                            int64_t ScalableImm) const {
   // Can also use sub to handle negated immediates.
   return isInt<32>(Imm);
 }
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index fe1943b5760844..b3cccee0e67bf1 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -1329,7 +1329,8 @@ namespace llvm {
     /// add immediate, that is the target has add instructions which can
     /// add a register and the immediate without having to materialize
     /// the immediate into a register.
-    bool isLegalAddImmediate(int64_t Imm) const override;
+    bool isLegalAddImmediate(int64_t Imm,
+                             int64_t ScalableImm = 0) const override;
 
     bool isLegalStoreImmediate(int64_t Imm) const override;
 
diff --git a/llvm/unittests/Target/AArch64/CMakeLists.txt b/llvm/unittests/Target/AArch64/CMakeLists.txt
index dacd919ba1e33b..64ab991ac479a4 100644
--- a/llvm/unittests/Target/AArch64/CMakeLists.txt
+++ b/llvm/unittests/Target/AArch64/CMakeLists.txt
@@ -29,6 +29,7 @@ add_llvm_target_unittest(AArch64Tests
   MatrixRegisterAliasing.cpp
   SMEAttributesTest.cpp
   AArch64SVESchedPseudoTest.cpp
+  Immediates.cpp
   )
 
 set_property(TARGET AArch64Tests PROPERTY FOLDER "Tests/UnitTests/TargetTests")
diff --git a/llvm/unittests/Target/AArch64/Immediates.cpp b/llvm/unittests/Target/AArch64/Immediates.cpp
new file mode 100644
index 00000000000000..5f5895e44c6110
--- /dev/null
+++ b/llvm/unittests/Target/AArch64/Immediates.cpp
@@ -0,0 +1,75 @@
+#include "AArch64Subtarget.h"
+#include "AArch64TargetMachine.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+
+#include "gtest/gtest.h"
+#include <initializer_list>
+#include <memory>
+
+using namespace llvm;
+
+namespace {
+
+struct TestCase {
+  int64_t FixedImm;
+  int64_t ScalableImm;
+  bool Result;
+};
+
+const std::initializer_list<TestCase> Tests = {
+    // FixedImm, ScalableImm, Result
+    // No change, easily 'supported'
+    {0, 0, true},
+
+    // Simple fixed immediate cases
+    // +8
+    {8, 0, true},
+    // -16
+    {-16, 0, true},
+
+    // Scalable; addvl increments by whole registers, range [-32,31]
+    // +(16 * vscale), one register's worth
+    {0, 16, true},
+    // +(8 * vscale), half a register's worth
+    {0, 8, false},
+    // -(32 * 16 * vscale)
+    {0, -512, true},
+    // -(33 * 16 * vscale)
+    {0, -528, false},
+    // +(31 * 16 * vscale)
+    {0, 496, true},
+    // +(32 * 16 * vscale)
+    {0, 512, false},
+
+    // Mixed; not supported.
+    // +(16 + (16 * vscale)) -- one register's worth + 16
+    {16, 16, false},
+};
+} // namespace
+
+TEST(Immediates, Immediates) {
+  LLVMInitializeAArch64TargetInfo();
+  LLVMInitializeAArch64Target();
+  LLVMInitializeAArch64TargetMC();
+
+  std::string Error;
+  auto TT = Triple::normalize("aarch64");
+  const Target *T = TargetRegistry::lookupTarget(TT, Error);
+
+  std::unique_ptr<TargetMachine> TM(
+      T->createTargetMachine(TT, "generic", "+sve", TargetOptions(),
+                             std::nullopt, std::nullopt,
+                             CodeGenOptLevel::Default));
+  AArch64Subtarget ST(TM->getTargetTriple(), TM->getTargetCPU(),
+                      TM->getTargetCPU(), TM->getTargetFeatureString(), *TM,
+                      true);
+
+  auto *TLI = ST.getTargetLowering();
+
+  for (const auto &Test : Tests) {
+    ASSERT_EQ(TLI->isLegalAddImmediate(Test.FixedImm, Test.ScalableImm),
+              Test.Result);
+  }
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/84173


More information about the llvm-commits mailing list