[llvm] [RFC] TableGen-erate SDNode descriptions (PR #119709)

Sergei Barannikov via llvm-commits llvm-commits at lists.llvm.org
Sat Dec 14 04:35:20 PST 2024


https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/119709

>From be59b380c9b4a41886603cdc51ee6e6a344b9489 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Wed, 13 Nov 2024 20:29:24 +0300
Subject: [PATCH 01/27] [CodeGen] Add boilerplate SelectionDAGInfo
 implementation to some targets

---
 .../Target/AMDGPU/AMDGPUSelectionDAGInfo.cpp  | 13 +++++++++++
 .../Target/AMDGPU/AMDGPUSelectionDAGInfo.h    | 23 +++++++++++++++++++
 llvm/lib/Target/AMDGPU/CMakeLists.txt         |  1 +
 llvm/lib/Target/AMDGPU/GCNSubtarget.cpp       |  8 +++++++
 llvm/lib/Target/AMDGPU/GCNSubtarget.h         | 12 ++++------
 llvm/lib/Target/AMDGPU/R600Subtarget.cpp      |  8 +++++++
 llvm/lib/Target/AMDGPU/R600Subtarget.h        | 10 ++++----
 llvm/lib/Target/Mips/CMakeLists.txt           |  1 +
 llvm/lib/Target/Mips/MipsSelectionDAGInfo.cpp | 13 +++++++++++
 llvm/lib/Target/Mips/MipsSelectionDAGInfo.h   | 23 +++++++++++++++++++
 llvm/lib/Target/Mips/MipsSubtarget.cpp        | 22 +++++++++++++-----
 llvm/lib/Target/Mips/MipsSubtarget.h          | 10 ++++----
 llvm/lib/Target/NVPTX/CMakeLists.txt          |  1 +
 .../Target/NVPTX/NVPTXSelectionDAGInfo.cpp    | 13 +++++++++++
 llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.h | 23 +++++++++++++++++++
 llvm/lib/Target/NVPTX/NVPTXSubtarget.cpp      | 11 ++++++++-
 llvm/lib/Target/NVPTX/NVPTXSubtarget.h        | 10 ++++----
 llvm/lib/Target/PowerPC/CMakeLists.txt        |  1 +
 .../Target/PowerPC/PPCSelectionDAGInfo.cpp    | 13 +++++++++++
 llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h | 23 +++++++++++++++++++
 llvm/lib/Target/PowerPC/PPCSubtarget.cpp      |  9 ++++++++
 llvm/lib/Target/PowerPC/PPCSubtarget.h        | 14 +++++++----
 llvm/lib/Target/RISCV/CMakeLists.txt          |  1 +
 .../Target/RISCV/RISCVSelectionDAGInfo.cpp    | 13 +++++++++++
 llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h | 23 +++++++++++++++++++
 llvm/lib/Target/RISCV/RISCVSubtarget.cpp      | 11 ++++++++-
 llvm/lib/Target/RISCV/RISCVSubtarget.h        | 12 ++++++----
 llvm/lib/Target/RISCV/RISCVTargetMachine.h    |  1 -
 28 files changed, 281 insertions(+), 42 deletions(-)
 create mode 100644 llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.cpp
 create mode 100644 llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.h
 create mode 100644 llvm/lib/Target/Mips/MipsSelectionDAGInfo.cpp
 create mode 100644 llvm/lib/Target/Mips/MipsSelectionDAGInfo.h
 create mode 100644 llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.cpp
 create mode 100644 llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.h
 create mode 100644 llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
 create mode 100644 llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h
 create mode 100644 llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp
 create mode 100644 llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.cpp
new file mode 100644
index 00000000000000..1ee0b8ce5e2dcf
--- /dev/null
+++ b/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.cpp
@@ -0,0 +1,13 @@
+//===- AMDGPUSelectionDAGInfo.cpp -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "AMDGPUSelectionDAGInfo.h"
+
+using namespace llvm;
+
+AMDGPUSelectionDAGInfo::~AMDGPUSelectionDAGInfo() = default;
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.h b/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.h
new file mode 100644
index 00000000000000..6560f498114782
--- /dev/null
+++ b/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.h
@@ -0,0 +1,23 @@
+//===- AMDGPUSelectionDAGInfo.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUSELECTIONDAGINFO_H
+#define LLVM_LIB_TARGET_AMDGPU_AMDGPUSELECTIONDAGINFO_H
+
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+
+namespace llvm {
+
+class AMDGPUSelectionDAGInfo : public SelectionDAGTargetInfo {
+public:
+  ~AMDGPUSelectionDAGInfo() override;
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUSELECTIONDAGINFO_H
diff --git a/llvm/lib/Target/AMDGPU/CMakeLists.txt b/llvm/lib/Target/AMDGPU/CMakeLists.txt
index 68d141e338a882..03038caab521df 100644
--- a/llvm/lib/Target/AMDGPU/CMakeLists.txt
+++ b/llvm/lib/Target/AMDGPU/CMakeLists.txt
@@ -100,6 +100,7 @@ add_llvm_target(AMDGPUCodeGen
   AMDGPUResourceUsageAnalysis.cpp
   AMDGPURewriteOutArguments.cpp
   AMDGPURewriteUndefForPHI.cpp
+  AMDGPUSelectionDAGInfo.cpp
   AMDGPUSetWavePriority.cpp
   AMDGPUSplitModule.cpp
   AMDGPUSubtarget.cpp
diff --git a/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp b/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp
index 51361b75940560..117afc4a8e8c60 100644
--- a/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp
@@ -16,6 +16,7 @@
 #include "AMDGPUInstructionSelector.h"
 #include "AMDGPULegalizerInfo.h"
 #include "AMDGPURegisterBankInfo.h"
+#include "AMDGPUSelectionDAGInfo.h"
 #include "AMDGPUTargetMachine.h"
 #include "SIMachineFunctionInfo.h"
 #include "Utils/AMDGPUBaseInfo.h"
@@ -185,6 +186,9 @@ GCNSubtarget::GCNSubtarget(const Triple &TT, StringRef GPU, StringRef FS,
   // clang-format on
   MaxWavesPerEU = AMDGPU::IsaInfo::getMaxWavesPerEU(this);
   EUsPerCU = AMDGPU::IsaInfo::getEUsPerCU(this);
+
+  TSInfo = std::make_unique<AMDGPUSelectionDAGInfo>();
+
   CallLoweringInfo = std::make_unique<AMDGPUCallLowering>(*getTargetLowering());
   InlineAsmLoweringInfo =
       std::make_unique<InlineAsmLowering>(getTargetLowering());
@@ -194,6 +198,10 @@ GCNSubtarget::GCNSubtarget(const Triple &TT, StringRef GPU, StringRef FS,
       std::make_unique<AMDGPUInstructionSelector>(*this, *RegBankInfo, TM);
 }
 
+const SelectionDAGTargetInfo *GCNSubtarget::getSelectionDAGInfo() const {
+  return TSInfo.get();
+}
+
 unsigned GCNSubtarget::getConstantBusLimit(unsigned Opcode) const {
   if (getGeneration() < GFX10)
     return 1;
diff --git a/llvm/lib/Target/AMDGPU/GCNSubtarget.h b/llvm/lib/Target/AMDGPU/GCNSubtarget.h
index 5cecaf6349c883..3388bc3c5a8de1 100644
--- a/llvm/lib/Target/AMDGPU/GCNSubtarget.h
+++ b/llvm/lib/Target/AMDGPU/GCNSubtarget.h
@@ -21,7 +21,6 @@
 #include "SIISelLowering.h"
 #include "SIInstrInfo.h"
 #include "Utils/AMDGPUBaseInfo.h"
-#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/Support/ErrorHandling.h"
 
 #define GET_SUBTARGETINFO_HEADER
@@ -49,6 +48,9 @@ class GCNSubtarget final : public AMDGPUGenSubtargetInfo,
   };
 
 private:
+  /// SelectionDAGISel related APIs.
+  std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
+
   /// GlobalISel related APIs.
   std::unique_ptr<AMDGPUCallLowering> CallLoweringInfo;
   std::unique_ptr<InlineAsmLowering> InlineAsmLoweringInfo;
@@ -257,7 +259,6 @@ class GCNSubtarget final : public AMDGPUGenSubtargetInfo,
   // Dummy feature to use for assembler in tablegen.
   bool FeatureDisable = false;
 
-  SelectionDAGTargetInfo TSInfo;
 private:
   SIInstrInfo InstrInfo;
   SITargetLowering TLInfo;
@@ -291,6 +292,8 @@ class GCNSubtarget final : public AMDGPUGenSubtargetInfo,
     return &InstrInfo.getRegisterInfo();
   }
 
+  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
+
   const CallLowering *getCallLowering() const override {
     return CallLoweringInfo.get();
   }
@@ -315,11 +318,6 @@ class GCNSubtarget final : public AMDGPUGenSubtargetInfo,
     return TargetID;
   }
 
-  // Nothing implemented, just prevent crashes on use.
-  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
-    return &TSInfo;
-  }
-
   const InstrItineraryData *getInstrItineraryData() const override {
     return &InstrItins;
   }
diff --git a/llvm/lib/Target/AMDGPU/R600Subtarget.cpp b/llvm/lib/Target/AMDGPU/R600Subtarget.cpp
index fd5a87999cf81b..77fbd416955c23 100644
--- a/llvm/lib/Target/AMDGPU/R600Subtarget.cpp
+++ b/llvm/lib/Target/AMDGPU/R600Subtarget.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "R600Subtarget.h"
+#include "AMDGPUSelectionDAGInfo.h"
 #include "MCTargetDesc/R600MCTargetDesc.h"
 
 using namespace llvm;
@@ -30,6 +31,13 @@ R600Subtarget::R600Subtarget(const Triple &TT, StringRef GPU, StringRef FS,
       TLInfo(TM, initializeSubtargetDependencies(TT, GPU, FS)),
       InstrItins(getInstrItineraryForCPU(GPU)) {
   LocalMemorySize = AddressableLocalMemorySize;
+  TSInfo = std::make_unique<AMDGPUSelectionDAGInfo>();
+}
+
+R600Subtarget::~R600Subtarget() = default;
+
+const SelectionDAGTargetInfo *R600Subtarget::getSelectionDAGInfo() const {
+  return TSInfo.get();
 }
 
 R600Subtarget &R600Subtarget::initializeSubtargetDependencies(const Triple &TT,
diff --git a/llvm/lib/Target/AMDGPU/R600Subtarget.h b/llvm/lib/Target/AMDGPU/R600Subtarget.h
index 7f0f9305e1fa6c..22e56b66e18277 100644
--- a/llvm/lib/Target/AMDGPU/R600Subtarget.h
+++ b/llvm/lib/Target/AMDGPU/R600Subtarget.h
@@ -19,7 +19,6 @@
 #include "R600ISelLowering.h"
 #include "R600InstrInfo.h"
 #include "Utils/AMDGPUBaseInfo.h"
-#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 
 #define GET_SUBTARGETINFO_HEADER
 #include "R600GenSubtargetInfo.inc"
@@ -41,12 +40,14 @@ class R600Subtarget final : public R600GenSubtargetInfo,
   Generation Gen = R600;
   R600TargetLowering TLInfo;
   InstrItineraryData InstrItins;
-  SelectionDAGTargetInfo TSInfo;
+  std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
 
 public:
   R600Subtarget(const Triple &TT, StringRef CPU, StringRef FS,
                 const TargetMachine &TM);
 
+  ~R600Subtarget() override;
+
   const R600InstrInfo *getInstrInfo() const override { return &InstrInfo; }
 
   const R600FrameLowering *getFrameLowering() const override {
@@ -65,10 +66,7 @@ class R600Subtarget final : public R600GenSubtargetInfo,
     return &InstrItins;
   }
 
-  // Nothing implemented, just prevent crashes on use.
-  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
-    return &TSInfo;
-  }
+  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
 
   void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
 
diff --git a/llvm/lib/Target/Mips/CMakeLists.txt b/llvm/lib/Target/Mips/CMakeLists.txt
index 28f66a4ad94826..21d1765107ae6f 100644
--- a/llvm/lib/Target/Mips/CMakeLists.txt
+++ b/llvm/lib/Target/Mips/CMakeLists.txt
@@ -58,6 +58,7 @@ add_llvm_target(MipsCodeGen
   MipsSEISelDAGToDAG.cpp
   MipsSEISelLowering.cpp
   MipsSERegisterInfo.cpp
+  MipsSelectionDAGInfo.cpp
   MipsSubtarget.cpp
   MipsTargetMachine.cpp
   MipsTargetObjectFile.cpp
diff --git a/llvm/lib/Target/Mips/MipsSelectionDAGInfo.cpp b/llvm/lib/Target/Mips/MipsSelectionDAGInfo.cpp
new file mode 100644
index 00000000000000..54ec1fb2d62580
--- /dev/null
+++ b/llvm/lib/Target/Mips/MipsSelectionDAGInfo.cpp
@@ -0,0 +1,13 @@
+//===- MipsSelectionDAGInfo.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "MipsSelectionDAGInfo.h"
+
+using namespace llvm;
+
+MipsSelectionDAGInfo::~MipsSelectionDAGInfo() = default;
diff --git a/llvm/lib/Target/Mips/MipsSelectionDAGInfo.h b/llvm/lib/Target/Mips/MipsSelectionDAGInfo.h
new file mode 100644
index 00000000000000..8e65ccf58ea87d
--- /dev/null
+++ b/llvm/lib/Target/Mips/MipsSelectionDAGInfo.h
@@ -0,0 +1,23 @@
+//===- MipsSelectionDAGInfo.h -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_MIPS_MIPSSELECTIONDAGINFO_H
+#define LLVM_LIB_TARGET_MIPS_MIPSSELECTIONDAGINFO_H
+
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+
+namespace llvm {
+
+class MipsSelectionDAGInfo : public SelectionDAGTargetInfo {
+public:
+  ~MipsSelectionDAGInfo() override;
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_MIPS_MIPSSELECTIONDAGINFO_H
diff --git a/llvm/lib/Target/Mips/MipsSubtarget.cpp b/llvm/lib/Target/Mips/MipsSubtarget.cpp
index cafb20f983f1f5..2210eca9eb1051 100644
--- a/llvm/lib/Target/Mips/MipsSubtarget.cpp
+++ b/llvm/lib/Target/Mips/MipsSubtarget.cpp
@@ -16,6 +16,7 @@
 #include "MipsLegalizerInfo.h"
 #include "MipsRegisterBankInfo.h"
 #include "MipsRegisterInfo.h"
+#include "MipsSelectionDAGInfo.h"
 #include "MipsTargetMachine.h"
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/Function.h"
@@ -78,13 +79,14 @@ MipsSubtarget::MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
       HasMips3_32(false), HasMips3_32r2(false), HasMips4_32(false),
       HasMips4_32r2(false), HasMips5_32r2(false), InMips16Mode(false),
       InMips16HardFloat(Mips16HardFloat), InMicroMipsMode(false), HasDSP(false),
-      HasDSPR2(false), HasDSPR3(false), AllowMixed16_32(Mixed16_32 || Mips_Os16),
-      Os16(Mips_Os16), HasMSA(false), UseTCCInDIV(false), HasSym32(false),
-      HasEVA(false), DisableMadd4(false), HasMT(false), HasCRC(false),
-      HasVirt(false), HasGINV(false), UseIndirectJumpsHazard(false), StrictAlign(false),
+      HasDSPR2(false), HasDSPR3(false),
+      AllowMixed16_32(Mixed16_32 || Mips_Os16), Os16(Mips_Os16), HasMSA(false),
+      UseTCCInDIV(false), HasSym32(false), HasEVA(false), DisableMadd4(false),
+      HasMT(false), HasCRC(false), HasVirt(false), HasGINV(false),
+      UseIndirectJumpsHazard(false), StrictAlign(false),
       StackAlignOverride(StackAlignOverride), TM(TM), TargetTriple(TT),
-      TSInfo(), InstrInfo(MipsInstrInfo::create(
-                    initializeSubtargetDependencies(CPU, FS, TM))),
+      InstrInfo(
+          MipsInstrInfo::create(initializeSubtargetDependencies(CPU, FS, TM))),
       FrameLowering(MipsFrameLowering::create(*this)),
       TLInfo(MipsTargetLowering::create(TM, *this)) {
 
@@ -211,6 +213,8 @@ MipsSubtarget::MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
     GINVWarningPrinted = true;
   }
 
+  TSInfo = std::make_unique<MipsSelectionDAGInfo>();
+
   CallLoweringInfo.reset(new MipsCallLowering(*getTargetLowering()));
   Legalizer.reset(new MipsLegalizerInfo(*this));
 
@@ -219,6 +223,8 @@ MipsSubtarget::MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
   InstSelector.reset(createMipsInstructionSelector(TM, *this, *RBI));
 }
 
+MipsSubtarget::~MipsSubtarget() = default;
+
 bool MipsSubtarget::isPositionIndependent() const {
   return TM.isPositionIndependent();
 }
@@ -280,6 +286,10 @@ bool MipsSubtarget::isABI_N32() const { return getABI().IsN32(); }
 bool MipsSubtarget::isABI_O32() const { return getABI().IsO32(); }
 const MipsABIInfo &MipsSubtarget::getABI() const { return TM.getABI(); }
 
+const SelectionDAGTargetInfo *MipsSubtarget::getSelectionDAGInfo() const {
+  return TSInfo.get();
+}
+
 const CallLowering *MipsSubtarget::getCallLowering() const {
   return CallLoweringInfo.get();
 }
diff --git a/llvm/lib/Target/Mips/MipsSubtarget.h b/llvm/lib/Target/Mips/MipsSubtarget.h
index fea7f11fd07054..c048ab29d5f9b2 100644
--- a/llvm/lib/Target/Mips/MipsSubtarget.h
+++ b/llvm/lib/Target/Mips/MipsSubtarget.h
@@ -21,7 +21,6 @@
 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
 #include "llvm/CodeGen/RegisterBankInfo.h"
-#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/MC/MCInstrItineraries.h"
@@ -220,7 +219,7 @@ class MipsSubtarget : public MipsGenSubtargetInfo {
 
   Triple TargetTriple;
 
-  const SelectionDAGTargetInfo TSInfo;
+  std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
   std::unique_ptr<const MipsInstrInfo> InstrInfo;
   std::unique_ptr<const MipsFrameLowering> FrameLowering;
   std::unique_ptr<const MipsTargetLowering> TLInfo;
@@ -243,6 +242,8 @@ class MipsSubtarget : public MipsGenSubtargetInfo {
   MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS, bool little,
                 const MipsTargetMachine &TM, MaybeAlign StackAlignOverride);
 
+  ~MipsSubtarget() override;
+
   /// ParseSubtargetFeatures - Parses features string setting specified
   /// subtarget options.  Definition of function is auto generated by tblgen.
   void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
@@ -383,9 +384,8 @@ class MipsSubtarget : public MipsGenSubtargetInfo {
   void setHelperClassesMips16();
   void setHelperClassesMipsSE();
 
-  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
-    return &TSInfo;
-  }
+  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
+
   const MipsInstrInfo *getInstrInfo() const override { return InstrInfo.get(); }
   const TargetFrameLowering *getFrameLowering() const override {
     return FrameLowering.get();
diff --git a/llvm/lib/Target/NVPTX/CMakeLists.txt b/llvm/lib/Target/NVPTX/CMakeLists.txt
index 693365161330f5..dfbda845347322 100644
--- a/llvm/lib/Target/NVPTX/CMakeLists.txt
+++ b/llvm/lib/Target/NVPTX/CMakeLists.txt
@@ -31,6 +31,7 @@ set(NVPTXCodeGen_sources
   NVPTXPrologEpilogPass.cpp
   NVPTXRegisterInfo.cpp
   NVPTXReplaceImageHandles.cpp
+  NVPTXSelectionDAGInfo.cpp
   NVPTXSubtarget.cpp
   NVPTXTargetMachine.cpp
   NVPTXTargetTransformInfo.cpp
diff --git a/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.cpp b/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.cpp
new file mode 100644
index 00000000000000..4f789cb61990f5
--- /dev/null
+++ b/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.cpp
@@ -0,0 +1,13 @@
+//===- NVPTXSelectionDAGInfo.cpp ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "NVPTXSelectionDAGInfo.h"
+
+using namespace llvm;
+
+NVPTXSelectionDAGInfo::~NVPTXSelectionDAGInfo() = default;
diff --git a/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.h b/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.h
new file mode 100644
index 00000000000000..7dc56155c2750c
--- /dev/null
+++ b/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.h
@@ -0,0 +1,23 @@
+//===- NVPTXSelectionDAGInfo.h ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_NVPTX_NVPTXSELECTIONDAGINFO_H
+#define LLVM_LIB_TARGET_NVPTX_NVPTXSELECTIONDAGINFO_H
+
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+
+namespace llvm {
+
+class NVPTXSelectionDAGInfo : public SelectionDAGTargetInfo {
+public:
+  ~NVPTXSelectionDAGInfo() override;
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_NVPTX_NVPTXSELECTIONDAGINFO_H
diff --git a/llvm/lib/Target/NVPTX/NVPTXSubtarget.cpp b/llvm/lib/Target/NVPTX/NVPTXSubtarget.cpp
index 0e6b75e622c6ad..34571465aea6f0 100644
--- a/llvm/lib/Target/NVPTX/NVPTXSubtarget.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXSubtarget.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "NVPTXSubtarget.h"
+#include "NVPTXSelectionDAGInfo.h"
 #include "NVPTXTargetMachine.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FormatVariadic.h"
@@ -56,7 +57,15 @@ NVPTXSubtarget::NVPTXSubtarget(const Triple &TT, const std::string &CPU,
                                const NVPTXTargetMachine &TM)
     : NVPTXGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), PTXVersion(0),
       FullSmVersion(200), SmVersion(getSmVersion()), TM(TM),
-      TLInfo(TM, initializeSubtargetDependencies(CPU, FS)) {}
+      TLInfo(TM, initializeSubtargetDependencies(CPU, FS)) {
+  TSInfo = std::make_unique<NVPTXSelectionDAGInfo>();
+}
+
+NVPTXSubtarget::~NVPTXSubtarget() = default;
+
+const SelectionDAGTargetInfo *NVPTXSubtarget::getSelectionDAGInfo() const {
+  return TSInfo.get();
+}
 
 bool NVPTXSubtarget::hasImageHandles() const {
   // Enable handles for Kepler+, where CUDA supports indirect surfaces and
diff --git a/llvm/lib/Target/NVPTX/NVPTXSubtarget.h b/llvm/lib/Target/NVPTX/NVPTXSubtarget.h
index e785bbf830da62..2a2b98dd4fb6af 100644
--- a/llvm/lib/Target/NVPTX/NVPTXSubtarget.h
+++ b/llvm/lib/Target/NVPTX/NVPTXSubtarget.h
@@ -18,7 +18,6 @@
 #include "NVPTXISelLowering.h"
 #include "NVPTXInstrInfo.h"
 #include "NVPTXRegisterInfo.h"
-#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/IR/DataLayout.h"
 #include <string>
@@ -46,7 +45,7 @@ class NVPTXSubtarget : public NVPTXGenSubtargetInfo {
   const NVPTXTargetMachine &TM;
   NVPTXInstrInfo InstrInfo;
   NVPTXTargetLowering TLInfo;
-  SelectionDAGTargetInfo TSInfo;
+  std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
 
   // NVPTX does not have any call stack frame, but need a NVPTX specific
   // FrameLowering class because TargetFrameLowering is abstract.
@@ -59,6 +58,8 @@ class NVPTXSubtarget : public NVPTXGenSubtargetInfo {
   NVPTXSubtarget(const Triple &TT, const std::string &CPU,
                  const std::string &FS, const NVPTXTargetMachine &TM);
 
+  ~NVPTXSubtarget() override;
+
   const TargetFrameLowering *getFrameLowering() const override {
     return &FrameLowering;
   }
@@ -69,9 +70,8 @@ class NVPTXSubtarget : public NVPTXGenSubtargetInfo {
   const NVPTXTargetLowering *getTargetLowering() const override {
     return &TLInfo;
   }
-  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
-    return &TSInfo;
-  }
+
+  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
 
   bool hasAtomAddF64() const { return SmVersion >= 60; }
   bool hasAtomScope() const { return SmVersion >= 60; }
diff --git a/llvm/lib/Target/PowerPC/CMakeLists.txt b/llvm/lib/Target/PowerPC/CMakeLists.txt
index 8f7b53b622065d..3808a26a0b92a0 100644
--- a/llvm/lib/Target/PowerPC/CMakeLists.txt
+++ b/llvm/lib/Target/PowerPC/CMakeLists.txt
@@ -43,6 +43,7 @@ add_llvm_target(PowerPCCodeGen
   PPCMacroFusion.cpp
   PPCMIPeephole.cpp
   PPCRegisterInfo.cpp
+  PPCSelectionDAGInfo.cpp
   PPCSubtarget.cpp
   PPCTargetMachine.cpp
   PPCTargetObjectFile.cpp
diff --git a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
new file mode 100644
index 00000000000000..fff83ae2852702
--- /dev/null
+++ b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
@@ -0,0 +1,13 @@
+//===- PPCSelectionDAGInfo.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "PPCSelectionDAGInfo.h"
+
+using namespace llvm;
+
+PPCSelectionDAGInfo::~PPCSelectionDAGInfo() = default;
diff --git a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h
new file mode 100644
index 00000000000000..e7d3ec58686f94
--- /dev/null
+++ b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h
@@ -0,0 +1,23 @@
+//===- PPCSelectionDAGInfo.h ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_POWERPC_PPCSELECTIONDAGINFO_H
+#define LLVM_LIB_TARGET_POWERPC_PPCSELECTIONDAGINFO_H
+
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+
+namespace llvm {
+
+class PPCSelectionDAGInfo : public SelectionDAGTargetInfo {
+public:
+  ~PPCSelectionDAGInfo() override;
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_POWERPC_PPCSELECTIONDAGINFO_H
diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp
index 57b650575a8984..75a0272af7c312 100644
--- a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp
+++ b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp
@@ -16,6 +16,7 @@
 #include "GISel/PPCRegisterBankInfo.h"
 #include "PPC.h"
 #include "PPCRegisterInfo.h"
+#include "PPCSelectionDAGInfo.h"
 #include "PPCTargetMachine.h"
 #include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
@@ -59,6 +60,8 @@ PPCSubtarget::PPCSubtarget(const Triple &TT, const std::string &CPU,
               TargetTriple.getArch() == Triple::ppc64le),
       TM(TM), FrameLowering(initializeSubtargetDependencies(CPU, TuneCPU, FS)),
       InstrInfo(*this), TLInfo(TM, *this) {
+  TSInfo = std::make_unique<PPCSelectionDAGInfo>();
+
   CallLoweringInfo.reset(new PPCCallLowering(*getTargetLowering()));
   Legalizer.reset(new PPCLegalizerInfo(*this));
   auto *RBI = new PPCRegisterBankInfo(*getRegisterInfo());
@@ -67,6 +70,12 @@ PPCSubtarget::PPCSubtarget(const Triple &TT, const std::string &CPU,
   InstSelector.reset(createPPCInstructionSelector(TM, *this, *RBI));
 }
 
+PPCSubtarget::~PPCSubtarget() = default;
+
+const SelectionDAGTargetInfo *PPCSubtarget::getSelectionDAGInfo() const {
+  return TSInfo.get();
+}
+
 void PPCSubtarget::initializeEnvironment() {
   StackAlignment = Align(16);
   CPUDirective = PPC::DIR_NONE;
diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.h b/llvm/lib/Target/PowerPC/PPCSubtarget.h
index f6ace4daa336bf..b8714f8f587e6f 100644
--- a/llvm/lib/Target/PowerPC/PPCSubtarget.h
+++ b/llvm/lib/Target/PowerPC/PPCSubtarget.h
@@ -19,7 +19,6 @@
 #include "llvm/CodeGen/GlobalISel/CallLowering.h"
 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
 #include "llvm/CodeGen/RegisterBankInfo.h"
-#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/MC/MCInstrItineraries.h"
@@ -33,6 +32,7 @@
 #undef PPC
 
 namespace llvm {
+class SelectionDAGTargetInfo;
 class StringRef;
 
 namespace PPC {
@@ -105,7 +105,9 @@ class PPCSubtarget : public PPCGenSubtargetInfo {
   PPCFrameLowering FrameLowering;
   PPCInstrInfo InstrInfo;
   PPCTargetLowering TLInfo;
-  SelectionDAGTargetInfo TSInfo;
+
+  // SelectionDAGISel related APIs.
+  std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
 
   /// GlobalISel related APIs.
   std::unique_ptr<CallLowering> CallLoweringInfo;
@@ -121,6 +123,8 @@ class PPCSubtarget : public PPCGenSubtargetInfo {
                const std::string &TuneCPU, const std::string &FS,
                const PPCTargetMachine &TM);
 
+  ~PPCSubtarget();
+
   /// ParseSubtargetFeatures - Parses features string setting specified
   /// subtarget options.  Definition of function is auto generated by tblgen.
   void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
@@ -147,9 +151,9 @@ class PPCSubtarget : public PPCGenSubtargetInfo {
   const PPCTargetLowering *getTargetLowering() const override {
     return &TLInfo;
   }
-  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
-    return &TSInfo;
-  }
+
+  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
+
   const PPCRegisterInfo *getRegisterInfo() const override {
     return &getInstrInfo()->getRegisterInfo();
   }
diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt
index b95ad9dd428cc9..44661647a86310 100644
--- a/llvm/lib/Target/RISCV/CMakeLists.txt
+++ b/llvm/lib/Target/RISCV/CMakeLists.txt
@@ -54,6 +54,7 @@ add_llvm_target(RISCVCodeGen
   RISCVMoveMerger.cpp
   RISCVPushPopOptimizer.cpp
   RISCVRegisterInfo.cpp
+  RISCVSelectionDAGInfo.cpp
   RISCVSubtarget.cpp
   RISCVTargetMachine.cpp
   RISCVTargetObjectFile.cpp
diff --git a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp
new file mode 100644
index 00000000000000..c9ca8c0fb23e2b
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp
@@ -0,0 +1,13 @@
+//===- RISCVSelectionDAGInfo.cpp ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "RISCVSelectionDAGInfo.h"
+
+using namespace llvm;
+
+RISCVSelectionDAGInfo::~RISCVSelectionDAGInfo() = default;
diff --git a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h
new file mode 100644
index 00000000000000..2f6e4bedc248aa
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h
@@ -0,0 +1,23 @@
+//===- RISCVSelectionDAGInfo.h ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_RISCV_RISCVSELECTIONDAGINFO_H
+#define LLVM_LIB_TARGET_RISCV_RISCVSELECTIONDAGINFO_H
+
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+
+namespace llvm {
+
+class RISCVSelectionDAGInfo : public SelectionDAGTargetInfo {
+public:
+  ~RISCVSelectionDAGInfo() override;
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_RISCV_RISCVSELECTIONDAGINFO_H
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
index 38443e8646de40..6bd7a1245bf6dd 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
@@ -15,6 +15,7 @@
 #include "GISel/RISCVLegalizerInfo.h"
 #include "RISCV.h"
 #include "RISCVFrameLowering.h"
+#include "RISCVSelectionDAGInfo.h"
 #include "RISCVTargetMachine.h"
 #include "llvm/CodeGen/MachineScheduler.h"
 #include "llvm/CodeGen/MacroFusion.h"
@@ -97,7 +98,15 @@ RISCVSubtarget::RISCVSubtarget(const Triple &TT, StringRef CPU,
       RVVVectorBitsMin(RVVVectorBitsMin), RVVVectorBitsMax(RVVVectorBitsMax),
       FrameLowering(
           initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
-      InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {}
+      InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {
+  TSInfo = std::make_unique<RISCVSelectionDAGInfo>();
+}
+
+RISCVSubtarget::~RISCVSubtarget() = default;
+
+const SelectionDAGTargetInfo *RISCVSubtarget::getSelectionDAGInfo() const {
+  return TSInfo.get();
+}
 
 const CallLowering *RISCVSubtarget::getCallLowering() const {
   if (!CallLoweringInfo)
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h
index 9a1881c2d39837..c93b06c3e0d5a7 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -21,7 +21,6 @@
 #include "llvm/CodeGen/GlobalISel/CallLowering.h"
 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
-#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/Target/TargetMachine.h"
@@ -102,7 +101,6 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
   RISCVInstrInfo InstrInfo;
   RISCVRegisterInfo RegInfo;
   RISCVTargetLowering TLInfo;
-  SelectionDAGTargetInfo TSInfo;
 
   /// Initializes using the passed in CPU and feature strings so that we can
   /// use initializer lists for subtarget initialization.
@@ -118,6 +116,8 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
                  StringRef FS, StringRef ABIName, unsigned RVVVectorBitsMin,
                  unsigned RVVVectorLMULMax, const TargetMachine &TM);
 
+  ~RISCVSubtarget() override;
+
   // Parses features string setting specified subtarget options. The
   // definition of this function is auto-generated by tblgen.
   void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
@@ -132,9 +132,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
   const RISCVTargetLowering *getTargetLowering() const override {
     return &TLInfo;
   }
-  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
-    return &TSInfo;
-  }
+
   bool enableMachineScheduler() const override { return true; }
 
   bool enablePostRAScheduler() const override { return UsePostRAScheduler; }
@@ -284,6 +282,9 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
   }
 
 protected:
+  // SelectionDAGISel related APIs.
+  std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
+
   // GlobalISel related APIs.
   mutable std::unique_ptr<CallLowering> CallLoweringInfo;
   mutable std::unique_ptr<InstructionSelector> InstSelector;
@@ -298,6 +299,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
   unsigned getMinRVVVectorSizeInBits() const;
 
 public:
+  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
   const CallLowering *getCallLowering() const override;
   InstructionSelector *getInstructionSelector() const override;
   const LegalizerInfo *getLegalizerInfo() const override;
diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.h b/llvm/lib/Target/RISCV/RISCVTargetMachine.h
index 5506196c3c7e86..b1610e3f81eba7 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetMachine.h
+++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.h
@@ -16,7 +16,6 @@
 #include "MCTargetDesc/RISCVMCTargetDesc.h"
 #include "RISCVSubtarget.h"
 #include "llvm/CodeGen/CodeGenTargetMachineImpl.h"
-#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/IR/DataLayout.h"
 #include <optional>
 

>From abd507186d6eb64506b03c0c3ce4a42537e56010 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Wed, 13 Nov 2024 21:26:38 +0300
Subject: [PATCH 02/27] [CodeGen] Virtualize isTargetStrictFPOpcode /
 isTargetMemoryOpcode

---
 llvm/include/llvm/CodeGen/ISDOpcodes.h        | 11 ------
 llvm/include/llvm/CodeGen/SelectionDAG.h      |  4 +-
 llvm/include/llvm/CodeGen/SelectionDAGNodes.h | 29 ++-------------
 .../llvm/CodeGen/SelectionDAGTargetInfo.h     | 13 +++++++
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 12 +++---
 .../CodeGen/SelectionDAG/SelectionDAGISel.cpp |  7 +++-
 .../SelectionDAG/SelectionDAGTargetInfo.cpp   |  6 +++
 llvm/lib/Target/AArch64/AArch64ISelLowering.h |  6 ++-
 .../AArch64/AArch64SelectionDAGInfo.cpp       | 20 ++++++++++
 .../Target/AArch64/AArch64SelectionDAGInfo.h  |  4 ++
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp |  1 -
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h   |  6 ++-
 .../Target/AMDGPU/AMDGPUSelectionDAGInfo.cpp  |  8 ++++
 .../Target/AMDGPU/AMDGPUSelectionDAGInfo.h    |  2 +
 llvm/lib/Target/ARM/ARMISelLowering.h         |  6 ++-
 llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp   |  7 ++++
 llvm/lib/Target/ARM/ARMSelectionDAGInfo.h     |  2 +
 llvm/lib/Target/Mips/MipsISelLowering.h       |  2 +-
 llvm/lib/Target/Mips/MipsSelectionDAGInfo.cpp | 18 +++++++++
 llvm/lib/Target/Mips/MipsSelectionDAGInfo.h   |  2 +
 llvm/lib/Target/NVPTX/NVPTXISelLowering.h     |  6 ++-
 .../Target/NVPTX/NVPTXSelectionDAGInfo.cpp    |  8 ++++
 llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.h |  2 +
 llvm/lib/Target/PowerPC/PPCISelLowering.h     | 21 +++++------
 .../Target/PowerPC/PPCSelectionDAGInfo.cpp    | 26 +++++++++++++
 llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h |  4 ++
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   | 37 +++++++++----------
 llvm/lib/Target/RISCV/RISCVISelLowering.h     | 11 ++----
 .../Target/RISCV/RISCVSelectionDAGInfo.cpp    | 22 +++++++++++
 llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h |  4 ++
 llvm/lib/Target/SystemZ/SystemZISelLowering.h |  8 ++--
 .../SystemZ/SystemZSelectionDAGInfo.cpp       | 26 +++++++++++++
 .../Target/SystemZ/SystemZSelectionDAGInfo.h  |  4 ++
 .../lib/Target/WebAssembly/WebAssemblyISD.def |  8 ++--
 .../WebAssembly/WebAssemblyISelLowering.cpp   |  3 --
 .../WebAssembly/WebAssemblyISelLowering.h     |  8 ----
 .../WebAssemblySelectionDAGInfo.cpp           | 13 +++++++
 .../WebAssembly/WebAssemblySelectionDAGInfo.h |  3 ++
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  8 +++-
 llvm/lib/Target/X86/X86ISelLowering.h         | 15 +++-----
 llvm/lib/Target/X86/X86SelectionDAGInfo.cpp   | 14 +++++++
 llvm/lib/Target/X86/X86SelectionDAGInfo.h     |  4 ++
 42 files changed, 299 insertions(+), 122 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h
index 0b6d155b6d161e..69820aed2137b5 100644
--- a/llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -1490,17 +1490,6 @@ enum NodeType {
   BUILTIN_OP_END
 };
 
-/// FIRST_TARGET_STRICTFP_OPCODE - Target-specific pre-isel operations
-/// which cannot raise FP exceptions should be less than this value.
-/// Those that do must not be less than this value.
-static const int FIRST_TARGET_STRICTFP_OPCODE = BUILTIN_OP_END + 400;
-
-/// FIRST_TARGET_MEMORY_OPCODE - Target-specific pre-isel operations
-/// which do not reference a specific memory location should be less than
-/// this value. Those that do must not be less than this value, and can
-/// be used with SelectionDAG::getMemIntrinsicNode.
-static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END + 500;
-
 /// Whether this is bitwise logic opcode.
 inline bool isBitwiseLogicOp(unsigned Opcode) {
   return Opcode == ISD::AND || Opcode == ISD::OR || Opcode == ISD::XOR;
diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
index e97e01839f73b4..27cc1a2f963519 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -1327,8 +1327,8 @@ class SelectionDAG {
 
   /// Creates a MemIntrinsicNode that may produce a
   /// result and takes a list of operands. Opcode may be INTRINSIC_VOID,
-  /// INTRINSIC_W_CHAIN, or a target-specific opcode with a value not
-  /// less than FIRST_TARGET_MEMORY_OPCODE.
+  /// INTRINSIC_W_CHAIN, or a target-specific memory-referencing opcode
+  // (see `SelectionDAGTargetInfo::isTargetMemoryOpcode`).
   SDValue getMemIntrinsicNode(
       unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef<SDValue> Ops,
       EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment,
diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
index 61f3c6329efce8..46d8ae442bf2a2 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -210,7 +210,6 @@ class SDValue {
   inline const SDValue &getOperand(unsigned i) const;
   inline uint64_t getConstantOperandVal(unsigned i) const;
   inline const APInt &getConstantOperandAPInt(unsigned i) const;
-  inline bool isTargetMemoryOpcode() const;
   inline bool isTargetOpcode() const;
   inline bool isMachineOpcode() const;
   inline bool isUndef() const;
@@ -688,22 +687,6 @@ END_TWO_BYTE_PACK()
   /// \<target\>ISD namespace).
   bool isTargetOpcode() const { return NodeType >= ISD::BUILTIN_OP_END; }
 
-  /// Test if this node has a target-specific opcode that may raise
-  /// FP exceptions (in the \<target\>ISD namespace and greater than
-  /// FIRST_TARGET_STRICTFP_OPCODE).  Note that all target memory
-  /// opcode are currently automatically considered to possibly raise
-  /// FP exceptions as well.
-  bool isTargetStrictFPOpcode() const {
-    return NodeType >= ISD::FIRST_TARGET_STRICTFP_OPCODE;
-  }
-
-  /// Test if this node has a target-specific
-  /// memory-referencing opcode (in the \<target\>ISD namespace and
-  /// greater than FIRST_TARGET_MEMORY_OPCODE).
-  bool isTargetMemoryOpcode() const {
-    return NodeType >= ISD::FIRST_TARGET_MEMORY_OPCODE;
-  }
-
   /// Return true if the type of the node type undefined.
   bool isUndef() const { return NodeType == ISD::UNDEF; }
 
@@ -1214,10 +1197,6 @@ inline bool SDValue::isTargetOpcode() const {
   return Node->isTargetOpcode();
 }
 
-inline bool SDValue::isTargetMemoryOpcode() const {
-  return Node->isTargetMemoryOpcode();
-}
-
 inline bool SDValue::isMachineOpcode() const {
   return Node->isMachineOpcode();
 }
@@ -1571,10 +1550,10 @@ class AtomicSDNode : public MemSDNode {
   }
 };
 
-/// This SDNode is used for target intrinsics that touch
-/// memory and need an associated MachineMemOperand. Its opcode may be
-/// INTRINSIC_VOID, INTRINSIC_W_CHAIN, PREFETCH, or a target-specific opcode
-/// with a value not less than FIRST_TARGET_MEMORY_OPCODE.
+/// This SDNode is used for target intrinsics that touch memory and need
+/// an associated MachineMemOperand. Its opcode may be INTRINSIC_VOID,
+/// INTRINSIC_W_CHAIN, PREFETCH, or a target-specific memory-referencing
+/// opcode (see `SelectionDAGTargetInfo::isTargetMemoryOpcode`).
 class MemIntrinsicSDNode : public MemSDNode {
 public:
   MemIntrinsicSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl,
diff --git a/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h b/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h
index 720c9463867c34..ef5ae5dba58de4 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h
@@ -35,6 +35,19 @@ class SelectionDAGTargetInfo {
   SelectionDAGTargetInfo &operator=(const SelectionDAGTargetInfo &) = delete;
   virtual ~SelectionDAGTargetInfo();
 
+  /// Returns true if a node with the given target-specific opcode has
+  /// a memory operand. Nodes with such opcodes can only be created with
+  /// `SelectionDAG::getMemIntrinsicNode`.
+  virtual bool isTargetMemoryOpcode(unsigned Opcode) const { return false; }
+
+  /// Returns true if a node with the given target-specific opcode has
+  /// strict floating-point semantics.
+  virtual bool isTargetStrictFPOpcode(unsigned Opcode) const { return false; }
+
+  /// Returns true if a node with the given target-specific opcode
+  /// may raise a floating-point exception.
+  virtual bool mayRaiseFPException(unsigned Opcode) const;
+
   /// Emit target-specific code that performs a memcpy.
   /// This can be used by targets to provide code sequences for cases
   /// that don't fit the target's parameters for simple loads/stores and can be
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 34214550f3a12b..9d6430e697f241 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -8978,12 +8978,12 @@ SDValue SelectionDAG::getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl,
                                           SDVTList VTList,
                                           ArrayRef<SDValue> Ops, EVT MemVT,
                                           MachineMemOperand *MMO) {
-  assert((Opcode == ISD::INTRINSIC_VOID ||
-          Opcode == ISD::INTRINSIC_W_CHAIN ||
-          Opcode == ISD::PREFETCH ||
-          (Opcode <= (unsigned)std::numeric_limits<int>::max() &&
-           (int)Opcode >= ISD::FIRST_TARGET_MEMORY_OPCODE)) &&
-         "Opcode is not a memory-accessing opcode!");
+  assert(
+      (Opcode == ISD::INTRINSIC_VOID || Opcode == ISD::INTRINSIC_W_CHAIN ||
+       Opcode == ISD::PREFETCH ||
+       (Opcode <= (unsigned)std::numeric_limits<int>::max() &&
+        Opcode >= ISD::BUILTIN_OP_END && TSI->isTargetMemoryOpcode(Opcode))) &&
+      "Opcode is not a memory-accessing opcode!");
 
   // Memoize the node unless it returns a glue result.
   MemIntrinsicSDNode *N;
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 3000dfda1bea03..e897b4fac9af9a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -51,6 +51,7 @@
 #include "llvm/CodeGen/SchedulerRegistry.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/CodeGen/StackMaps.h"
 #include "llvm/CodeGen/StackProtector.h"
 #include "llvm/CodeGen/SwiftErrorValueTracking.h"
@@ -4394,8 +4395,10 @@ bool SelectionDAGISel::mayRaiseFPException(SDNode *N) const {
 
   // For ISD opcodes, only StrictFP opcodes may raise an FP
   // exception.
-  if (N->isTargetOpcode())
-    return N->isTargetStrictFPOpcode();
+  if (N->isTargetOpcode()) {
+    const SelectionDAGTargetInfo &TSI = CurDAG->getSelectionDAGInfo();
+    return TSI.mayRaiseFPException(N->getOpcode());
+  }
   return N->isStrictFPOpcode();
 }
 
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGTargetInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGTargetInfo.cpp
index 3a2df6f60593a9..0f3b36658f10ad 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGTargetInfo.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGTargetInfo.cpp
@@ -15,3 +15,9 @@
 using namespace llvm;
 
 SelectionDAGTargetInfo::~SelectionDAGTargetInfo() = default;
+
+bool SelectionDAGTargetInfo::mayRaiseFPException(unsigned Opcode) const {
+  // FIXME: All target memory opcodes are currently automatically considered
+  //  to possibly raise FP exceptions. See rev. 63336795.
+  return isTargetStrictFPOpcode(Opcode) || isTargetMemoryOpcode(Opcode);
+}
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index d51b36f7e49946..835c9381834724 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -477,7 +477,7 @@ enum NodeType : unsigned {
   MSRR,
 
   // Strict (exception-raising) floating point comparison
-  STRICT_FCMP = ISD::FIRST_TARGET_STRICTFP_OPCODE,
+  STRICT_FCMP,
   STRICT_FCMPE,
 
   // SME ZA loads and stores
@@ -485,7 +485,8 @@ enum NodeType : unsigned {
   SME_ZA_STR,
 
   // NEON Load/Store with post-increment base updates
-  LD2post = ISD::FIRST_TARGET_MEMORY_OPCODE,
+  FIRST_MEMORY_OPCODE,
+  LD2post = FIRST_MEMORY_OPCODE,
   LD3post,
   LD4post,
   ST2post,
@@ -520,6 +521,7 @@ enum NodeType : unsigned {
   STP,
   STILP,
   STNP,
+  LAST_MEMORY_OPCODE = STNP,
 };
 
 } // end namespace AArch64ISD
diff --git a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
index c4d60a0cb4a118..f06c15ccb50755 100644
--- a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
@@ -23,6 +23,26 @@ static cl::opt<bool>
                                 "to lower to librt functions"),
                        cl::init(true));
 
+bool AArch64SelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
+  if (Opcode >= AArch64ISD::FIRST_MEMORY_OPCODE &&
+      Opcode <= AArch64ISD::LAST_MEMORY_OPCODE)
+    return true;
+  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+}
+
+bool AArch64SelectionDAGInfo::isTargetStrictFPOpcode(unsigned Opcode) const {
+  switch (static_cast<AArch64ISD::NodeType>(Opcode)) {
+  default:
+    break;
+  case AArch64ISD::STRICT_FCMP:
+  case AArch64ISD::STRICT_FCMPE:
+  case AArch64ISD::SME_ZA_LDR:
+  case AArch64ISD::SME_ZA_STR:
+    return true;
+  }
+  return SelectionDAGTargetInfo::isTargetStrictFPOpcode(Opcode);
+}
+
 SDValue AArch64SelectionDAGInfo::EmitMOPS(unsigned Opcode, SelectionDAG &DAG,
                                           const SDLoc &DL, SDValue Chain,
                                           SDValue Dst, SDValue SrcOrValue,
diff --git a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.h b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.h
index 9d1f2e9cba846a..7efe49c7206555 100644
--- a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.h
@@ -19,6 +19,10 @@ namespace llvm {
 
 class AArch64SelectionDAGInfo : public SelectionDAGTargetInfo {
 public:
+  bool isTargetMemoryOpcode(unsigned Opcode) const override;
+
+  bool isTargetStrictFPOpcode(unsigned Opcode) const override;
+
   SDValue EmitMOPS(unsigned Opcode, SelectionDAG &DAG, const SDLoc &DL,
                    SDValue Chain, SDValue Dst, SDValue SrcOrValue, SDValue Size,
                    Align Alignment, bool isVolatile,
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 48e9af9fe507fb..f76acfe12e2953 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -5555,7 +5555,6 @@ const char* AMDGPUTargetLowering::getTargetNodeName(unsigned Opcode) const {
   NODE_NAME_CASE(PC_ADD_REL_OFFSET)
   NODE_NAME_CASE(LDS)
   NODE_NAME_CASE(DUMMY_CHAIN)
-  case AMDGPUISD::FIRST_MEM_OPCODE_NUMBER: break;
   NODE_NAME_CASE(LOAD_D16_HI)
   NODE_NAME_CASE(LOAD_D16_LO)
   NODE_NAME_CASE(LOAD_D16_HI_I8)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h
index 33991239a41209..c74dc7942f52c0 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h
@@ -546,8 +546,9 @@ enum NodeType : unsigned {
   LDS,
 
   DUMMY_CHAIN,
-  FIRST_MEM_OPCODE_NUMBER = ISD::FIRST_TARGET_MEMORY_OPCODE,
-  LOAD_D16_HI,
+
+  FIRST_MEMORY_OPCODE,
+  LOAD_D16_HI = FIRST_MEMORY_OPCODE,
   LOAD_D16_LO,
   LOAD_D16_HI_I8,
   LOAD_D16_HI_U8,
@@ -603,6 +604,7 @@ enum NodeType : unsigned {
   BUFFER_ATOMIC_FMIN,
   BUFFER_ATOMIC_FMAX,
   BUFFER_ATOMIC_COND_SUB_U32,
+  LAST_MEMORY_OPCODE = BUFFER_ATOMIC_COND_SUB_U32,
 };
 
 } // End namespace AMDGPUISD
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.cpp
index 1ee0b8ce5e2dcf..97705ca89f3d2c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.cpp
@@ -7,7 +7,15 @@
 //===----------------------------------------------------------------------===//
 
 #include "AMDGPUSelectionDAGInfo.h"
+#include "AMDGPUISelLowering.h"
 
 using namespace llvm;
 
 AMDGPUSelectionDAGInfo::~AMDGPUSelectionDAGInfo() = default;
+
+bool AMDGPUSelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
+  if (Opcode >= AMDGPUISD::FIRST_MEMORY_OPCODE &&
+      Opcode <= AMDGPUISD::LAST_MEMORY_OPCODE)
+    return true;
+  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.h b/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.h
index 6560f498114782..a4f3488ab7a1fa 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.h
@@ -16,6 +16,8 @@ namespace llvm {
 class AMDGPUSelectionDAGInfo : public SelectionDAGTargetInfo {
 public:
   ~AMDGPUSelectionDAGInfo() override;
+
+  bool isTargetMemoryOpcode(unsigned Opcode) const override;
 };
 
 } // namespace llvm
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h
index 4fa600e0cfcc40..cd663cebeab01f 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.h
+++ b/llvm/lib/Target/ARM/ARMISelLowering.h
@@ -321,7 +321,8 @@ class VectorType;
     CSINC, // Conditional select increment.
 
     // Vector load N-element structure to all lanes:
-    VLD1DUP = ISD::FIRST_TARGET_MEMORY_OPCODE,
+    FIRST_MEMORY_OPCODE,
+    VLD1DUP = FIRST_MEMORY_OPCODE,
     VLD2DUP,
     VLD3DUP,
     VLD4DUP,
@@ -356,7 +357,8 @@ class VectorType;
 
     // Load/Store of dual registers
     LDRD,
-    STRD
+    STRD,
+    LAST_MEMORY_OPCODE = STRD,
   };
 
   } // end namespace ARMISD
diff --git a/llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp b/llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp
index e7ea10ff971a0c..24972636adb960 100644
--- a/llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp
@@ -30,6 +30,13 @@ cl::opt<TPLoop::MemTransfer> EnableMemtransferTPLoop(
                           "Allow (may be subject to certain conditions) "
                           "conversion of memcpy to TP loop.")));
 
+bool ARMSelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
+  if (Opcode >= ARMISD::FIRST_MEMORY_OPCODE &&
+      Opcode <= ARMISD::LAST_MEMORY_OPCODE)
+    return true;
+  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+}
+
 // Emit, if possible, a specialized version of the given Libcall. Typically this
 // means selecting the appropriately aligned version, but we also convert memset
 // of 0 into memclr.
diff --git a/llvm/lib/Target/ARM/ARMSelectionDAGInfo.h b/llvm/lib/Target/ARM/ARMSelectionDAGInfo.h
index 275b1c0f8dc017..d68150e66567ce 100644
--- a/llvm/lib/Target/ARM/ARMSelectionDAGInfo.h
+++ b/llvm/lib/Target/ARM/ARMSelectionDAGInfo.h
@@ -37,6 +37,8 @@ namespace ARM_AM {
 
 class ARMSelectionDAGInfo : public SelectionDAGTargetInfo {
 public:
+  bool isTargetMemoryOpcode(unsigned Opcode) const override;
+
   SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &dl,
                                   SDValue Chain, SDValue Dst, SDValue Src,
                                   SDValue Size, Align Alignment,
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h
index e245c056de6491..ae56bf7c8a2e72 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -247,7 +247,7 @@ class TargetRegisterClass;
       DOUBLE_SELECT_I64,
 
       // Load/Store Left/Right nodes.
-      LWL = ISD::FIRST_TARGET_MEMORY_OPCODE,
+      LWL,
       LWR,
       SWL,
       SWR,
diff --git a/llvm/lib/Target/Mips/MipsSelectionDAGInfo.cpp b/llvm/lib/Target/Mips/MipsSelectionDAGInfo.cpp
index 54ec1fb2d62580..03132c66b9273f 100644
--- a/llvm/lib/Target/Mips/MipsSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsSelectionDAGInfo.cpp
@@ -7,7 +7,25 @@
 //===----------------------------------------------------------------------===//
 
 #include "MipsSelectionDAGInfo.h"
+#include "MipsISelLowering.h"
 
 using namespace llvm;
 
 MipsSelectionDAGInfo::~MipsSelectionDAGInfo() = default;
+
+bool MipsSelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
+  switch (static_cast<MipsISD::NodeType>(Opcode)) {
+  default:
+    break;
+  case MipsISD::LWL:
+  case MipsISD::LWR:
+  case MipsISD::SWL:
+  case MipsISD::SWR:
+  case MipsISD::LDL:
+  case MipsISD::LDR:
+  case MipsISD::SDL:
+  case MipsISD::SDR:
+    return true;
+  }
+  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+}
diff --git a/llvm/lib/Target/Mips/MipsSelectionDAGInfo.h b/llvm/lib/Target/Mips/MipsSelectionDAGInfo.h
index 8e65ccf58ea87d..cdf203774a29d1 100644
--- a/llvm/lib/Target/Mips/MipsSelectionDAGInfo.h
+++ b/llvm/lib/Target/Mips/MipsSelectionDAGInfo.h
@@ -16,6 +16,8 @@ namespace llvm {
 class MipsSelectionDAGInfo : public SelectionDAGTargetInfo {
 public:
   ~MipsSelectionDAGInfo() override;
+
+  bool isTargetMemoryOpcode(unsigned Opcode) const override;
 };
 
 } // namespace llvm
diff --git a/llvm/lib/Target/NVPTX/NVPTXISelLowering.h b/llvm/lib/Target/NVPTX/NVPTXISelLowering.h
index c8b589ae39413e..f7c59973f8d1a5 100644
--- a/llvm/lib/Target/NVPTX/NVPTXISelLowering.h
+++ b/llvm/lib/Target/NVPTX/NVPTXISelLowering.h
@@ -70,7 +70,8 @@ enum NodeType : unsigned {
   BrxEnd,
   Dummy,
 
-  LoadV2 = ISD::FIRST_TARGET_MEMORY_OPCODE,
+  FIRST_MEMORY_OPCODE,
+  LoadV2 = FIRST_MEMORY_OPCODE,
   LoadV4,
   LDUV2, // LDU.v2
   LDUV4, // LDU.v4
@@ -443,7 +444,8 @@ enum NodeType : unsigned {
   Suld3DV2I64Zero,
   Suld3DV4I8Zero,
   Suld3DV4I16Zero,
-  Suld3DV4I32Zero
+  Suld3DV4I32Zero,
+  LAST_MEMORY_OPCODE = Suld3DV4I32Zero,
 };
 }
 
diff --git a/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.cpp b/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.cpp
index 4f789cb61990f5..c0941cc5738fa5 100644
--- a/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.cpp
@@ -7,7 +7,15 @@
 //===----------------------------------------------------------------------===//
 
 #include "NVPTXSelectionDAGInfo.h"
+#include "NVPTXISelLowering.h"
 
 using namespace llvm;
 
 NVPTXSelectionDAGInfo::~NVPTXSelectionDAGInfo() = default;
+
+bool NVPTXSelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
+  if (Opcode >= NVPTXISD::FIRST_MEMORY_OPCODE &&
+      Opcode <= NVPTXISD::LAST_MEMORY_OPCODE)
+    return true;
+  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+}
diff --git a/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.h b/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.h
index 7dc56155c2750c..bf743e12318606 100644
--- a/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.h
+++ b/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.h
@@ -16,6 +16,8 @@ namespace llvm {
 class NVPTXSelectionDAGInfo : public SelectionDAGTargetInfo {
 public:
   ~NVPTXSelectionDAGInfo() override;
+
+  bool isTargetMemoryOpcode(unsigned Opcode) const override;
 };
 
 } // namespace llvm
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index 8f41fc107a6918..7ee1b9bbbce511 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -36,14 +36,11 @@ namespace llvm {
 
   namespace PPCISD {
 
-    // When adding a NEW PPCISD node please add it to the correct position in
-    // the enum. The order of elements in this enum matters!
-    // Values that are added after this entry:
-    //     STBRX = ISD::FIRST_TARGET_MEMORY_OPCODE
-    // are considered memory opcodes and are treated differently than entries
-    // that come before it. For example, ADD or MUL should be placed before
-    // the ISD::FIRST_TARGET_MEMORY_OPCODE while a LOAD or STORE should come
-    // after it.
+  // When adding a NEW PPCISD node please add it to the correct position in
+  // the enum. The order of elements in this enum matters!
+  // Values that are added between FIRST_MEMORY_OPCODE and LAST_MEMORY_OPCODE
+  // are considered memory opcodes and are treated differently than other
+  // entries.
   enum NodeType : unsigned {
     // Start the numbering where the builtin ops and target ops leave off.
     FIRST_NUMBER = ISD::BUILTIN_OP_END,
@@ -487,7 +484,7 @@ namespace llvm {
     XXMFACC,
 
     // Constrained conversion from floating point to int
-    STRICT_FCTIDZ = ISD::FIRST_TARGET_STRICTFP_OPCODE,
+    STRICT_FCTIDZ,
     STRICT_FCTIWZ,
     STRICT_FCTIDUZ,
     STRICT_FCTIWUZ,
@@ -516,7 +513,8 @@ namespace llvm {
     /// byte-swapping store instruction.  It byte-swaps the low "Type" bits of
     /// the GPRC input, then stores it through Ptr.  Type can be either i16 or
     /// i32.
-    STBRX = ISD::FIRST_TARGET_MEMORY_OPCODE,
+    FIRST_MEMORY_OPCODE,
+    STBRX = FIRST_MEMORY_OPCODE,
 
     /// GPRC, CHAIN = LBRX CHAIN, Ptr, Type - This is a
     /// byte-swapping load instruction.  It loads "Type" bits, byte swaps it,
@@ -607,7 +605,8 @@ namespace llvm {
     /// GPRC = TOC_ENTRY GA, TOC
     /// Loads the entry for GA from the TOC, where the TOC base is given by
     /// the last operand.
-    TOC_ENTRY
+    TOC_ENTRY,
+    LAST_MEMORY_OPCODE = TOC_ENTRY,
   };
 
   } // end namespace PPCISD
diff --git a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
index fff83ae2852702..2ef6b07b9f7bf9 100644
--- a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
@@ -7,7 +7,33 @@
 //===----------------------------------------------------------------------===//
 
 #include "PPCSelectionDAGInfo.h"
+#include "PPCISelLowering.h"
 
 using namespace llvm;
 
 PPCSelectionDAGInfo::~PPCSelectionDAGInfo() = default;
+
+bool PPCSelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
+  if (Opcode >= PPCISD::FIRST_MEMORY_OPCODE &&
+      Opcode <= PPCISD::LAST_MEMORY_OPCODE)
+    return true;
+  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+}
+
+bool PPCSelectionDAGInfo::isTargetStrictFPOpcode(unsigned Opcode) const {
+  switch (static_cast<PPCISD::NodeType>(Opcode)) {
+  default:
+    break;
+  case PPCISD::STRICT_FCTIDZ:
+  case PPCISD::STRICT_FCTIWZ:
+  case PPCISD::STRICT_FCTIDUZ:
+  case PPCISD::STRICT_FCTIWUZ:
+  case PPCISD::STRICT_FCFID:
+  case PPCISD::STRICT_FCFIDU:
+  case PPCISD::STRICT_FCFIDS:
+  case PPCISD::STRICT_FCFIDUS:
+  case PPCISD::STRICT_FADDRTZ:
+    return true;
+  }
+  return SelectionDAGTargetInfo::isTargetStrictFPOpcode(Opcode);
+}
diff --git a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h
index e7d3ec58686f94..6d37c50fa6c1be 100644
--- a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h
+++ b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h
@@ -16,6 +16,10 @@ namespace llvm {
 class PPCSelectionDAGInfo : public SelectionDAGTargetInfo {
 public:
   ~PPCSelectionDAGInfo() override;
+
+  bool isTargetMemoryOpcode(unsigned Opcode) const override;
+
+  bool isTargetStrictFPOpcode(unsigned Opcode) const override;
 };
 
 } // namespace llvm
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 096b9fa79173fe..3b38737a4e48a5 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -17,6 +17,7 @@
 #include "RISCVConstantPoolValue.h"
 #include "RISCVMachineFunctionInfo.h"
 #include "RISCVRegisterInfo.h"
+#include "RISCVSelectionDAGInfo.h"
 #include "RISCVSubtarget.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/Statistic.h"
@@ -6392,14 +6393,12 @@ static unsigned getRISCVVLOp(SDValue Op) {
 /// Return true if a RISC-V target specified op has a passthru operand.
 static bool hasPassthruOp(unsigned Opcode) {
   assert(Opcode > RISCVISD::FIRST_NUMBER &&
-         Opcode <= RISCVISD::LAST_RISCV_STRICTFP_OPCODE &&
+         Opcode <= RISCVISD::LAST_STRICTFP_OPCODE &&
          "not a RISC-V target specific op");
-  static_assert(RISCVISD::LAST_VL_VECTOR_OP - RISCVISD::FIRST_VL_VECTOR_OP ==
-                    127 &&
-                RISCVISD::LAST_RISCV_STRICTFP_OPCODE -
-                        ISD::FIRST_TARGET_STRICTFP_OPCODE ==
-                    21 &&
-                "adding target specific op should update this function");
+  static_assert(
+      RISCVISD::LAST_VL_VECTOR_OP - RISCVISD::FIRST_VL_VECTOR_OP == 127 &&
+      RISCVISD::LAST_STRICTFP_OPCODE - RISCVISD::FIRST_STRICTFP_OPCODE == 21 &&
+      "adding target specific op should update this function");
   if (Opcode >= RISCVISD::ADD_VL && Opcode <= RISCVISD::VFMAX_VL)
     return true;
   if (Opcode == RISCVISD::FCOPYSIGN_VL)
@@ -6418,14 +6417,12 @@ static bool hasPassthruOp(unsigned Opcode) {
 /// Return true if a RISC-V target specified op has a mask operand.
 static bool hasMaskOp(unsigned Opcode) {
   assert(Opcode > RISCVISD::FIRST_NUMBER &&
-         Opcode <= RISCVISD::LAST_RISCV_STRICTFP_OPCODE &&
+         Opcode <= RISCVISD::LAST_STRICTFP_OPCODE &&
          "not a RISC-V target specific op");
-  static_assert(RISCVISD::LAST_VL_VECTOR_OP - RISCVISD::FIRST_VL_VECTOR_OP ==
-                    127 &&
-                RISCVISD::LAST_RISCV_STRICTFP_OPCODE -
-                        ISD::FIRST_TARGET_STRICTFP_OPCODE ==
-                    21 &&
-                "adding target specific op should update this function");
+  static_assert(
+      RISCVISD::LAST_VL_VECTOR_OP - RISCVISD::FIRST_VL_VECTOR_OP == 127 &&
+      RISCVISD::LAST_STRICTFP_OPCODE - RISCVISD::FIRST_STRICTFP_OPCODE == 21 &&
+      "adding target specific op should update this function");
   if (Opcode >= RISCVISD::TRUNCATE_VECTOR_VL && Opcode <= RISCVISD::SETCC_VL)
     return true;
   if (Opcode >= RISCVISD::VRGATHER_VX_VL && Opcode <= RISCVISD::VFIRST_VL)
@@ -15920,7 +15917,7 @@ static SDValue performFP_TO_INTCombine(SDNode *N,
   SDValue Src = N->getOperand(0);
 
   // Don't do this for strict-fp Src.
-  if (Src->isStrictFPOpcode() || Src->isTargetStrictFPOpcode())
+  if (Src->isStrictFPOpcode())
     return SDValue();
 
   // Ensure the FP type is legal.
@@ -16025,7 +16022,7 @@ static SDValue performFP_TO_INT_SATCombine(SDNode *N,
   SDValue Src = N->getOperand(0);
 
   // Don't do this for strict-fp Src.
-  if (Src->isStrictFPOpcode() || Src->isTargetStrictFPOpcode())
+  if (Src->isStrictFPOpcode())
     return SDValue();
 
   // Ensure the FP type is also legal.
@@ -16133,7 +16130,9 @@ static unsigned negateFMAOpcode(unsigned Opcode, bool NegMul, bool NegAcc) {
 static SDValue combineVFMADD_VLWithVFNEG_VL(SDNode *N, SelectionDAG &DAG) {
   // Fold FNEG_VL into FMA opcodes.
   // The first operand of strict-fp is chain.
-  unsigned Offset = N->isTargetStrictFPOpcode();
+  bool IsStrict =
+      DAG.getSelectionDAGInfo().isTargetStrictFPOpcode(N->getOpcode());
+  unsigned Offset = IsStrict ? 1 : 0;
   SDValue A = N->getOperand(0 + Offset);
   SDValue B = N->getOperand(1 + Offset);
   SDValue C = N->getOperand(2 + Offset);
@@ -16160,7 +16159,7 @@ static SDValue combineVFMADD_VLWithVFNEG_VL(SDNode *N, SelectionDAG &DAG) {
     return SDValue();
 
   unsigned NewOpcode = negateFMAOpcode(N->getOpcode(), NegA != NegB, NegC);
-  if (N->isTargetStrictFPOpcode())
+  if (IsStrict)
     return DAG.getNode(NewOpcode, SDLoc(N), N->getVTList(),
                        {N->getOperand(0), A, B, C, Mask, VL});
   return DAG.getNode(NewOpcode, SDLoc(N), N->getValueType(0), A, B, C, Mask,
@@ -16176,7 +16175,7 @@ static SDValue performVFMADD_VLCombine(SDNode *N,
     return V;
 
   // FIXME: Ignore strict opcodes for now.
-  if (N->isTargetStrictFPOpcode())
+  if (DAG.getSelectionDAGInfo().isTargetStrictFPOpcode(N->getOpcode()))
     return SDValue();
 
   return combineOp_VLToVWOp_VL(N, DCI, Subtarget);
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index 778e38a1a834ee..3e9e2ca67f645b 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -467,7 +467,8 @@ enum NodeType : unsigned {
 
   // FP to 32 bit int conversions for RV64. These are used to keep track of the
   // result being sign extended to 64 bit. These saturate out of range inputs.
-  STRICT_FCVT_W_RV64 = ISD::FIRST_TARGET_STRICTFP_OPCODE,
+  FIRST_STRICTFP_OPCODE,
+  STRICT_FCVT_W_RV64 = FIRST_STRICTFP_OPCODE,
   STRICT_FCVT_WU_RV64,
   STRICT_FADD_VL,
   STRICT_FSUB_VL,
@@ -489,13 +490,9 @@ enum NodeType : unsigned {
   STRICT_FSETCC_VL,
   STRICT_FSETCCS_VL,
   STRICT_VFROUND_NOEXCEPT_VL,
-  LAST_RISCV_STRICTFP_OPCODE = STRICT_VFROUND_NOEXCEPT_VL,
+  LAST_STRICTFP_OPCODE = STRICT_VFROUND_NOEXCEPT_VL,
 
-  // WARNING: Do not add anything in the end unless you want the node to
-  // have memop! In fact, starting from FIRST_TARGET_MEMORY_OPCODE all
-  // opcodes will be thought as target memory ops!
-
-  TH_LWD = ISD::FIRST_TARGET_MEMORY_OPCODE,
+  TH_LWD,
   TH_LWUD,
   TH_LDD,
   TH_SWD,
diff --git a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp
index c9ca8c0fb23e2b..8f2c7a013ec228 100644
--- a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp
@@ -7,7 +7,29 @@
 //===----------------------------------------------------------------------===//
 
 #include "RISCVSelectionDAGInfo.h"
+#include "RISCVISelLowering.h"
 
 using namespace llvm;
 
 RISCVSelectionDAGInfo::~RISCVSelectionDAGInfo() = default;
+
+bool RISCVSelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
+  switch (static_cast<RISCVISD::NodeType>(Opcode)) {
+  default:
+    break;
+  case RISCVISD::TH_LWD:
+  case RISCVISD::TH_LWUD:
+  case RISCVISD::TH_LDD:
+  case RISCVISD::TH_SWD:
+  case RISCVISD::TH_SDD:
+    return true;
+  }
+  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+}
+
+bool RISCVSelectionDAGInfo::isTargetStrictFPOpcode(unsigned Opcode) const {
+  if (Opcode >= RISCVISD::FIRST_STRICTFP_OPCODE &&
+      Opcode <= RISCVISD::LAST_STRICTFP_OPCODE)
+    return true;
+  return SelectionDAGTargetInfo::isTargetStrictFPOpcode(Opcode);
+}
diff --git a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h
index 2f6e4bedc248aa..a64f1b27eda3da 100644
--- a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h
@@ -16,6 +16,10 @@ namespace llvm {
 class RISCVSelectionDAGInfo : public SelectionDAGTargetInfo {
 public:
   ~RISCVSelectionDAGInfo() override;
+
+  bool isTargetMemoryOpcode(unsigned Opcode) const override;
+
+  bool isTargetStrictFPOpcode(unsigned Opcode) const override;
 };
 
 } // namespace llvm
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
index 0a899e861c73bf..4f418eceef8bbe 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
@@ -307,7 +307,7 @@ enum NodeType : unsigned {
 
   // Strict variants of scalar floating-point comparisons.
   // Quiet and signaling versions.
-  STRICT_FCMP = ISD::FIRST_TARGET_STRICTFP_OPCODE,
+  STRICT_FCMP,
   STRICT_FCMPS,
 
   // Strict variants of vector floating-point comparisons.
@@ -333,7 +333,8 @@ enum NodeType : unsigned {
   //            operand into the high bits
   // Operand 3: the negative of operand 2, for rotating the other way
   // Operand 4: the width of the field in bits (8 or 16)
-  ATOMIC_SWAPW = ISD::FIRST_TARGET_MEMORY_OPCODE,
+  FIRST_MEMORY_OPCODE,
+  ATOMIC_SWAPW = FIRST_MEMORY_OPCODE,
   ATOMIC_LOADW_ADD,
   ATOMIC_LOADW_SUB,
   ATOMIC_LOADW_AND,
@@ -384,7 +385,8 @@ enum NodeType : unsigned {
   // Prefetch from the second operand using the 4-bit control code in
   // the first operand.  The code is 1 for a load prefetch and 2 for
   // a store prefetch.
-  PREFETCH
+  PREFETCH,
+  LAST_MEMORY_OPCODE = PREFETCH,
 };
 
 // Return true if OPCODE is some kind of PC-relative address.
diff --git a/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp b/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp
index c182c9890509fb..552bf1a24a74c6 100644
--- a/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp
@@ -17,6 +17,32 @@ using namespace llvm;
 
 #define DEBUG_TYPE "systemz-selectiondag-info"
 
+bool SystemZSelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
+  if (Opcode >= SystemZISD::FIRST_MEMORY_OPCODE &&
+      Opcode <= SystemZISD::LAST_MEMORY_OPCODE)
+    return true;
+  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+}
+
+bool SystemZSelectionDAGInfo::isTargetStrictFPOpcode(unsigned Opcode) const {
+  switch (static_cast<SystemZISD::NodeType>(Opcode)) {
+  default:
+    break;
+  case SystemZISD::STRICT_FCMP:
+  case SystemZISD::STRICT_FCMPS:
+  case SystemZISD::STRICT_VFCMPE:
+  case SystemZISD::STRICT_VFCMPH:
+  case SystemZISD::STRICT_VFCMPHE:
+  case SystemZISD::STRICT_VFCMPES:
+  case SystemZISD::STRICT_VFCMPHS:
+  case SystemZISD::STRICT_VFCMPHES:
+  case SystemZISD::STRICT_VEXTEND:
+  case SystemZISD::STRICT_VROUND:
+    return true;
+  }
+  return SelectionDAGTargetInfo::isTargetStrictFPOpcode(Opcode);
+}
+
 static unsigned getMemMemLenAdj(unsigned Op) {
   return Op == SystemZISD::MEMSET_MVC ? 2 : 1;
 }
diff --git a/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.h b/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.h
index 6ac5bf8c6c1a37..c928f343e57103 100644
--- a/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.h
+++ b/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.h
@@ -21,6 +21,10 @@ class SystemZSelectionDAGInfo : public SelectionDAGTargetInfo {
 public:
   explicit SystemZSelectionDAGInfo() = default;
 
+  bool isTargetMemoryOpcode(unsigned Opcode) const override;
+
+  bool isTargetStrictFPOpcode(unsigned Opcode) const override;
+
   SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &DL,
                                   SDValue Chain, SDValue Dst, SDValue Src,
                                   SDValue Size, Align Alignment,
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISD.def b/llvm/lib/Target/WebAssembly/WebAssemblyISD.def
index 3502c47016c6b6..1cf0d13df1ff6b 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISD.def
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISD.def
@@ -48,10 +48,10 @@ HANDLE_NODETYPE(I64_MUL_WIDE_S)
 HANDLE_NODETYPE(I64_MUL_WIDE_U)
 
 // Memory intrinsics
-HANDLE_MEM_NODETYPE(GLOBAL_GET)
-HANDLE_MEM_NODETYPE(GLOBAL_SET)
-HANDLE_MEM_NODETYPE(TABLE_GET)
-HANDLE_MEM_NODETYPE(TABLE_SET)
+HANDLE_NODETYPE(GLOBAL_GET)
+HANDLE_NODETYPE(GLOBAL_SET)
+HANDLE_NODETYPE(TABLE_GET)
+HANDLE_NODETYPE(TABLE_SET)
 
 // Bulk memory instructions. These follow LLVM's expected semantics of
 // supporting out-of-bounds pointers if the length is zero, by inserting
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index 7712570869ff6c..084aed6eed46d3 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -871,14 +871,11 @@ const char *
 WebAssemblyTargetLowering::getTargetNodeName(unsigned Opcode) const {
   switch (static_cast<WebAssemblyISD::NodeType>(Opcode)) {
   case WebAssemblyISD::FIRST_NUMBER:
-  case WebAssemblyISD::FIRST_MEM_OPCODE:
     break;
 #define HANDLE_NODETYPE(NODE)                                                  \
   case WebAssemblyISD::NODE:                                                   \
     return "WebAssemblyISD::" #NODE;
-#define HANDLE_MEM_NODETYPE(NODE) HANDLE_NODETYPE(NODE)
 #include "WebAssemblyISD.def"
-#undef HANDLE_MEM_NODETYPE
 #undef HANDLE_NODETYPE
   }
   return nullptr;
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
index 82b33b6d1933d2..454432728ca871 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
@@ -24,16 +24,8 @@ namespace WebAssemblyISD {
 enum NodeType : unsigned {
   FIRST_NUMBER = ISD::BUILTIN_OP_END,
 #define HANDLE_NODETYPE(NODE) NODE,
-#define HANDLE_MEM_NODETYPE(NODE)
 #include "WebAssemblyISD.def"
-  FIRST_MEM_OPCODE = ISD::FIRST_TARGET_MEMORY_OPCODE,
 #undef HANDLE_NODETYPE
-#undef HANDLE_MEM_NODETYPE
-#define HANDLE_NODETYPE(NODE)
-#define HANDLE_MEM_NODETYPE(NODE) NODE,
-#include "WebAssemblyISD.def"
-#undef HANDLE_NODETYPE
-#undef HANDLE_MEM_NODETYPE
 };
 
 } // end namespace WebAssemblyISD
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.cpp
index 6f37dab4095349..b94cd46c9c141e 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.cpp
@@ -18,6 +18,19 @@ using namespace llvm;
 
 WebAssemblySelectionDAGInfo::~WebAssemblySelectionDAGInfo() = default; // anchor
 
+bool WebAssemblySelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
+  switch (static_cast<WebAssemblyISD::NodeType>(Opcode)) {
+  default:
+    break;
+  case WebAssemblyISD::GLOBAL_GET:
+  case WebAssemblyISD::GLOBAL_SET:
+  case WebAssemblyISD::TABLE_GET:
+  case WebAssemblyISD::TABLE_SET:
+    return true;
+  }
+  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+}
+
 SDValue WebAssemblySelectionDAGInfo::EmitTargetCodeForMemcpy(
     SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Dst, SDValue Src,
     SDValue Size, Align Alignment, bool IsVolatile, bool AlwaysInline,
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.h b/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.h
index fd517b238715b5..69c9af09663081 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.h
@@ -22,6 +22,9 @@ namespace llvm {
 class WebAssemblySelectionDAGInfo final : public SelectionDAGTargetInfo {
 public:
   ~WebAssemblySelectionDAGInfo() override;
+
+  bool isTargetMemoryOpcode(unsigned Opcode) const override;
+
   SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &dl,
                                   SDValue Chain, SDValue Op1, SDValue Op2,
                                   SDValue Op3, Align Alignment, bool isVolatile,
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 290c41a5bf032d..2956800ee3a147 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -54494,7 +54494,8 @@ static SDValue combineX86INT_TO_FP(SDNode *N, SelectionDAG &DAG,
 
 static SDValue combineCVTP2I_CVTTP2I(SDNode *N, SelectionDAG &DAG,
                                      TargetLowering::DAGCombinerInfo &DCI) {
-  bool IsStrict = N->isTargetStrictFPOpcode();
+  const SelectionDAGTargetInfo &TSI = DAG.getSelectionDAGInfo();
+  bool IsStrict = TSI.isTargetStrictFPOpcode(N->getOpcode());
   EVT VT = N->getValueType(0);
 
   // Convert a full vector load into vzload when not all bits are needed.
@@ -55114,7 +55115,10 @@ static SDValue combineFMA(SDNode *N, SelectionDAG &DAG,
                           const X86Subtarget &Subtarget) {
   SDLoc dl(N);
   EVT VT = N->getValueType(0);
-  bool IsStrict = N->isStrictFPOpcode() || N->isTargetStrictFPOpcode();
+  const SelectionDAGTargetInfo &TSI = DAG.getSelectionDAGInfo();
+  bool IsStrict = N->isTargetOpcode()
+                      ? TSI.isTargetStrictFPOpcode(N->getOpcode())
+                      : N->isStrictFPOpcode();
 
   // Let legalize expand this if it isn't a legal type yet.
   const TargetLowering &TLI = DAG.getTargetLoweringInfo();
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index d154ee9745b978..2b7a8eaf249d83 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -809,7 +809,8 @@ namespace llvm {
     CTEST,
 
     /// X86 strict FP compare instructions.
-    STRICT_FCMP = ISD::FIRST_TARGET_STRICTFP_OPCODE,
+    FIRST_STRICTFP_OPCODE,
+    STRICT_FCMP = FIRST_STRICTFP_OPCODE,
     STRICT_FCMPS,
 
     // Vector packed double/float comparison.
@@ -853,12 +854,11 @@ namespace llvm {
     /// Floating point max and min.
     STRICT_FMAX,
     STRICT_FMIN,
-
-    // WARNING: Only add nodes here if they are strict FP nodes. Non-memory and
-    // non-strict FP nodes should be above FIRST_TARGET_STRICTFP_OPCODE.
+    LAST_STRICTFP_OPCODE = STRICT_FMIN,
 
     // Compare and swap.
-    LCMPXCHG_DAG = ISD::FIRST_TARGET_MEMORY_OPCODE,
+    FIRST_MEMORY_OPCODE,
+    LCMPXCHG_DAG = FIRST_MEMORY_OPCODE,
     LCMPXCHG8_DAG,
     LCMPXCHG16_DAG,
     LCMPXCHG16_SAVE_RBX_DAG,
@@ -979,10 +979,7 @@ namespace llvm {
     // Conditional load/store instructions
     CLOAD,
     CSTORE,
-
-    // WARNING: Do not add anything in the end unless you want the node to
-    // have memop! In fact, starting from FIRST_TARGET_MEMORY_OPCODE all
-    // opcodes will be thought as target memory ops!
+    LAST_MEMORY_OPCODE = CSTORE,
   };
   } // end namespace X86ISD
 
diff --git a/llvm/lib/Target/X86/X86SelectionDAGInfo.cpp b/llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
index 3f88bcf9ce5ec5..a21c4d714311e4 100644
--- a/llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
+++ b/llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
@@ -27,6 +27,20 @@ static cl::opt<bool>
     UseFSRMForMemcpy("x86-use-fsrm-for-memcpy", cl::Hidden, cl::init(false),
                      cl::desc("Use fast short rep mov in memcpy lowering"));
 
+bool X86SelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
+  if (Opcode >= X86ISD::FIRST_MEMORY_OPCODE &&
+      Opcode <= X86ISD::LAST_MEMORY_OPCODE)
+    return true;
+  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+}
+
+bool X86SelectionDAGInfo::isTargetStrictFPOpcode(unsigned Opcode) const {
+  if (Opcode >= X86ISD::FIRST_STRICTFP_OPCODE &&
+      Opcode <= X86ISD::LAST_STRICTFP_OPCODE)
+    return true;
+  return SelectionDAGTargetInfo::isTargetStrictFPOpcode(Opcode);
+}
+
 /// Returns the best type to use with repmovs/repstos depending on alignment.
 static MVT getOptimalRepType(const X86Subtarget &Subtarget, Align Alignment) {
   uint64_t Align = Alignment.value();
diff --git a/llvm/lib/Target/X86/X86SelectionDAGInfo.h b/llvm/lib/Target/X86/X86SelectionDAGInfo.h
index 19136ca4f6f586..e77e16bab830d5 100644
--- a/llvm/lib/Target/X86/X86SelectionDAGInfo.h
+++ b/llvm/lib/Target/X86/X86SelectionDAGInfo.h
@@ -26,6 +26,10 @@ class X86SelectionDAGInfo : public SelectionDAGTargetInfo {
 public:
   explicit X86SelectionDAGInfo() = default;
 
+  bool isTargetMemoryOpcode(unsigned Opcode) const override;
+
+  bool isTargetStrictFPOpcode(unsigned Opcode) const override;
+
   SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, const SDLoc &dl,
                                   SDValue Chain, SDValue Dst, SDValue Src,
                                   SDValue Size, Align Alignment,

>From ec9e447fd66eee9ae8d1c16f02c79175e4387f02 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 00:53:08 +0300
Subject: [PATCH 03/27] TableGen backend & support classes

---
 llvm/include/llvm/CodeGen/SDNodeInfo.h        | 126 +++++++
 .../llvm/CodeGen/SelectionDAGTargetInfo.h     |  47 ++-
 llvm/include/llvm/CodeGen/TargetLowering.h    |   5 -
 .../include/llvm/Target/TargetSelectionDAG.td |   2 +
 llvm/lib/CodeGen/SelectionDAG/CMakeLists.txt  |   1 +
 llvm/lib/CodeGen/SelectionDAG/SDNodeInfo.cpp  | 129 ++++++++
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |   6 +-
 .../SelectionDAG/SelectionDAGDumper.cpp       |   4 +
 .../SelectionDAG/SelectionDAGTargetInfo.cpp   |   6 +
 .../Target/AArch64/AArch64ISelLowering.cpp    |  80 -----
 llvm/lib/Target/AArch64/AArch64ISelLowering.h |   4 -
 llvm/utils/TableGen/CMakeLists.txt            |   1 +
 .../TableGen/Common/CodeGenDAGPatterns.cpp    |  61 ++++
 .../TableGen/Common/CodeGenDAGPatterns.h      |  16 +-
 llvm/utils/TableGen/SDNodeInfoEmitter.cpp     | 308 ++++++++++++++++++
 15 files changed, 700 insertions(+), 96 deletions(-)
 create mode 100644 llvm/include/llvm/CodeGen/SDNodeInfo.h
 create mode 100644 llvm/lib/CodeGen/SelectionDAG/SDNodeInfo.cpp
 create mode 100644 llvm/utils/TableGen/SDNodeInfoEmitter.cpp

diff --git a/llvm/include/llvm/CodeGen/SDNodeInfo.h b/llvm/include/llvm/CodeGen/SDNodeInfo.h
new file mode 100644
index 00000000000000..b9519c479df281
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/SDNodeInfo.h
@@ -0,0 +1,126 @@
+//==------------------------------------------------------------------------==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INCLUDE_LLVM_CODEGEN_SDNODEINFO_H
+#define LLVM_INCLUDE_LLVM_CODEGEN_SDNODEINFO_H
+
+#include "ISDOpcodes.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/CodeGenTypes/MachineValueType.h"
+
+namespace llvm {
+
+class SDNode;
+class SelectionDAG;
+
+// SDNode Properties
+enum SDNP {
+  SDNPCommutative,
+  SDNPAssociative,
+  SDNPHasChain,
+  SDNPOutGlue,
+  SDNPInGlue,
+  SDNPOptInGlue,
+  SDNPMayLoad,
+  SDNPMayStore,
+  SDNPSideEffect,
+  SDNPMemOperand,
+  SDNPVariadic,
+};
+
+// SDNode Type Constraint kinds
+enum SDTC {
+  SDTCisVT,
+  SDTCisPtrTy,
+  SDTCisInt,
+  SDTCisFP,
+  SDTCisVec,
+  SDTCisSameAs,
+  SDTCisVTSmallerThanOp,
+  SDTCisOpSmallerThanOp,
+  SDTCisEltOfVec,
+  SDTCisSubVecOfVec,
+  SDTCVecEltisVT,
+  SDTCisSameNumEltsAs,
+  SDTCisSameSizeAs,
+};
+
+// SDNode Flags
+enum SDNF {
+  SDNFIsStrictFP,
+};
+
+struct SDTypeConstraint {
+  unsigned OpNo;
+  SDTC Kind;
+  unsigned OtherOpNo;
+  MVT::SimpleValueType VT;
+};
+
+struct SDNodeDesc {
+  unsigned NumResults;
+  int NumOperands;
+  uint32_t Properties;
+  uint32_t Flags;
+  uint32_t TSFlags;
+
+  bool hasProperty(SDNP Property) const { return Properties & (1 << Property); }
+
+  bool hasFlag(SDNF Flag) const { return Flags & (1 << Flag); }
+};
+
+class SDNodeInfo final {
+  const unsigned NumOpcodes;
+  const SDNodeDesc *Descs;
+  const char *const Names;
+  const unsigned *const NameOffsets;
+  const SDTypeConstraint *const Constraints;
+  const std::pair<unsigned, unsigned> *const ConstraintOffsets;
+
+public:
+  constexpr SDNodeInfo(unsigned NumOpcodes, const SDNodeDesc *Descs,
+                       const char *Names, const unsigned *NameOffsets,
+                       const SDTypeConstraint *Constraints,
+                       const std::pair<unsigned, unsigned> *ConstraintOffsets)
+      : NumOpcodes(NumOpcodes), Descs(Descs), Names(Names),
+        NameOffsets(NameOffsets), Constraints(Constraints),
+        ConstraintOffsets(ConstraintOffsets) {}
+
+  /// Returns true if there is a generated description for the given
+  /// target-specific opcode.
+  bool hasDesc(unsigned Opcode) const {
+    assert(Opcode >= ISD::BUILTIN_OP_END && "Expected target-specific opcode");
+    return Opcode < ISD::BUILTIN_OP_END + NumOpcodes;
+  }
+
+  /// Returns the description of a node with the given opcode.
+  const SDNodeDesc &getDesc(unsigned Opcode) const {
+    assert(hasDesc(Opcode));
+    return Descs[Opcode - ISD::BUILTIN_OP_END];
+  }
+
+  /// Returns operand constraints for a node with the given opcode.
+  ArrayRef<SDTypeConstraint> getConstraints(unsigned Opcode) const {
+    assert(hasDesc(Opcode));
+    auto [Offset, Count] = ConstraintOffsets[Opcode - ISD::BUILTIN_OP_END];
+    return ArrayRef(&Constraints[Offset], Count);
+  }
+
+  /// Returns the name of the given target-specific opcode, suitable for
+  /// debug printing.
+  StringRef getName(unsigned Opcode) const {
+    assert(hasDesc(Opcode));
+    return &Names[NameOffsets[Opcode - ISD::BUILTIN_OP_END]];
+  }
+
+  void verifyNode(const SelectionDAG &DAG, const SDNode *N) const;
+};
+
+} // namespace llvm
+
+#endif // LLVM_INCLUDE_LLVM_CODEGEN_SDNODEINFO_H
diff --git a/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h b/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h
index ef5ae5dba58de4..7f328a26fd9dd5 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CODEGEN_SELECTIONDAGTARGETINFO_H
 #define LLVM_CODEGEN_SELECTIONDAGTARGETINFO_H
 
+#include "SDNodeInfo.h"
 #include "llvm/CodeGen/MachineMemOperand.h"
 #include "llvm/CodeGen/SelectionDAGNodes.h"
 #include "llvm/Support/CodeGen.h"
@@ -35,6 +36,8 @@ class SelectionDAGTargetInfo {
   SelectionDAGTargetInfo &operator=(const SelectionDAGTargetInfo &) = delete;
   virtual ~SelectionDAGTargetInfo();
 
+  virtual const char *getTargetNodeName(unsigned Opcode) const;
+
   /// Returns true if a node with the given target-specific opcode has
   /// a memory operand. Nodes with such opcodes can only be created with
   /// `SelectionDAG::getMemIntrinsicNode`.
@@ -48,6 +51,9 @@ class SelectionDAGTargetInfo {
   /// may raise a floating-point exception.
   virtual bool mayRaiseFPException(unsigned Opcode) const;
 
+  virtual void verifyTargetNode(const SelectionDAG &DAG,
+                                const SDNode *N) const {}
+
   /// Emit target-specific code that performs a memcpy.
   /// This can be used by targets to provide code sequences for cases
   /// that don't fit the target's parameters for simple loads/stores and can be
@@ -100,8 +106,8 @@ class SelectionDAGTargetInfo {
     return SDValue();
   }
 
-  /// Emit target-specific code that performs a memcmp/bcmp, in cases where that is
-  /// faster than a libcall. The first returned SDValue is the result of the
+  /// Emit target-specific code that performs a memcmp/bcmp, in cases where that
+  /// is faster than a libcall. The first returned SDValue is the result of the
   /// memcmp and the second is the chain. Both SDValues can be null if a normal
   /// libcall should be used.
   virtual std::pair<SDValue, SDValue>
@@ -176,6 +182,41 @@ class SelectionDAGTargetInfo {
   }
 };
 
-} // end namespace llvm
+class SelectionDAGGenTargetInfo : public SelectionDAGTargetInfo {
+protected:
+  const SDNodeInfo &GenNodeInfo;
+
+  explicit SelectionDAGGenTargetInfo(const SDNodeInfo &GenNodeInfo)
+      : GenNodeInfo(GenNodeInfo) {}
+
+public:
+  ~SelectionDAGGenTargetInfo() override;
+
+  const char *getTargetNodeName(unsigned Opcode) const override {
+    assert(GenNodeInfo.hasDesc(Opcode) && "Should be handled by derived class");
+    return GenNodeInfo.getName(Opcode).data();
+  }
+
+  bool isTargetMemoryOpcode(unsigned Opcode) const override {
+    if (GenNodeInfo.hasDesc(Opcode))
+      return GenNodeInfo.getDesc(Opcode).hasProperty(SDNPMemOperand);
+    return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+  }
+
+  bool isTargetStrictFPOpcode(unsigned Opcode) const override {
+    if (GenNodeInfo.hasDesc(Opcode))
+      return GenNodeInfo.getDesc(Opcode).hasFlag(SDNFIsStrictFP);
+    return SelectionDAGTargetInfo::isTargetStrictFPOpcode(Opcode);
+  }
+
+  void verifyTargetNode(const SelectionDAG &DAG,
+                        const SDNode *N) const override {
+    if (GenNodeInfo.hasDesc(N->getOpcode()))
+      GenNodeInfo.verifyNode(DAG, N);
+    SelectionDAGTargetInfo::verifyTargetNode(DAG, N);
+  }
+};
+
+} // namespace llvm
 
 #endif // LLVM_CODEGEN_SELECTIONDAGTARGETINFO_H
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 3751aac4df8ead..0b691a2d9ed505 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -4930,11 +4930,6 @@ class TargetLowering : public TargetLoweringBase {
   bool verifyReturnAddressArgumentIsConstant(SDValue Op,
                                              SelectionDAG &DAG) const;
 
-#ifndef NDEBUG
-  /// Check the given SDNode.  Aborts if it is invalid.
-  virtual void verifyTargetSDNode(const SDNode *N) const {};
-#endif
-
   //===--------------------------------------------------------------------===//
   // Inline Asm Support hooks
   //
diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index 2c58eedce1de0b..f698da6642f2a0 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -353,6 +353,8 @@ class SDNode<string opcode, SDTypeProfile typeprof,
   string SDClass = sdclass;
   let Properties = props;
   SDTypeProfile TypeProfile = typeprof;
+  bit IsStrictFP = false;
+  bits<64> TSFlags = 0;
 }
 
 // Special TableGen-recognized dag nodes
diff --git a/llvm/lib/CodeGen/SelectionDAG/CMakeLists.txt b/llvm/lib/CodeGen/SelectionDAG/CMakeLists.txt
index cbfbfa3a321bcf..93a742a19aa793 100644
--- a/llvm/lib/CodeGen/SelectionDAG/CMakeLists.txt
+++ b/llvm/lib/CodeGen/SelectionDAG/CMakeLists.txt
@@ -11,6 +11,7 @@ add_llvm_component_library(LLVMSelectionDAG
   LegalizeVectorOps.cpp
   LegalizeVectorTypes.cpp
   ResourcePriorityQueue.cpp
+  SDNodeInfo.cpp
   ScheduleDAGFast.cpp
   ScheduleDAGRRList.cpp
   ScheduleDAGSDNodes.cpp
diff --git a/llvm/lib/CodeGen/SelectionDAG/SDNodeInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/SDNodeInfo.cpp
new file mode 100644
index 00000000000000..9935f984b1f6a0
--- /dev/null
+++ b/llvm/lib/CodeGen/SelectionDAG/SDNodeInfo.cpp
@@ -0,0 +1,129 @@
+//==------------------------------------------------------------------------==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/SDNodeInfo.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+
+using namespace llvm;
+
+[[noreturn]]
+static void reportNodeError(const SelectionDAG &DAG, const SDNode *N,
+                            const Twine &Msg) {
+  std::string S;
+  raw_string_ostream SS(S);
+  SS << "invalid node: " << Msg << '\n';
+  N->printrWithDepth(SS, &DAG, 2);
+  report_fatal_error(StringRef(S));
+}
+
+static void checkResultValueType(const SelectionDAG &DAG, const SDNode *N,
+                                 unsigned ResIdx, EVT ExpectedVT) {
+  EVT ActualVT = N->getValueType(ResIdx);
+  if (ActualVT != ExpectedVT)
+    reportNodeError(
+        DAG, N,
+        "result #" + Twine(ResIdx) + " has invalid type; expected " +
+            ExpectedVT.getEVTString() + ", got " + ActualVT.getEVTString());
+}
+
+static void checkOperandValueType(const SelectionDAG &DAG, const SDNode *N,
+                                  unsigned OpIdx, EVT ExpectedVT) {
+  EVT ActualVT = N->getOperand(OpIdx).getValueType();
+  if (ActualVT != ExpectedVT)
+    reportNodeError(
+        DAG, N,
+        "operand #" + Twine(OpIdx) + " has invalid type; expected " +
+            ExpectedVT.getEVTString() + ", got " + ActualVT.getEVTString());
+}
+
+void SDNodeInfo::verifyNode(const SelectionDAG &DAG, const SDNode *N) const {
+  const SDNodeDesc &Desc = getDesc(N->getOpcode());
+  bool HasChain = Desc.hasProperty(SDNPHasChain);
+  bool HasOutGlue = Desc.hasProperty(SDNPOutGlue);
+  bool HasInGlue = Desc.hasProperty(SDNPInGlue);
+  bool HasOptInGlue = Desc.hasProperty(SDNPOptInGlue);
+  bool IsVariadic = Desc.hasProperty(SDNPVariadic);
+
+  unsigned ActualNumResults = N->getNumValues();
+  unsigned ExpectedNumResults = Desc.NumResults + HasChain + HasOutGlue;
+
+  if (ActualNumResults != ExpectedNumResults)
+    reportNodeError(DAG, N,
+                    "invalid number of results; expected " +
+                        Twine(ExpectedNumResults) + ", got " +
+                        Twine(ActualNumResults));
+
+  // Chain result comes after all normal results.
+  if (HasChain) {
+    unsigned ChainResIdx = Desc.NumResults;
+    checkResultValueType(DAG, N, ChainResIdx, MVT::Other);
+  }
+
+  // Glue result comes last.
+  if (HasOutGlue) {
+    unsigned GlueResIdx = Desc.NumResults + HasChain;
+    checkResultValueType(DAG, N, GlueResIdx, MVT::Glue);
+  }
+
+  // In the most general case, the operands of a node go in the following order:
+  //   chain, fix#0, ..., fix#M-1, var#0, ... var#N-1, glue
+  // If the number of operands is < 0, M can be any;
+  // If the node has SDNPVariadic property, N can be any.
+  bool HasOptionalOperands = Desc.NumOperands < 0 || IsVariadic;
+
+  unsigned ActualNumOperands = N->getNumOperands();
+  unsigned ExpectedMinNumOperands =
+      (Desc.NumOperands >= 0 ? Desc.NumOperands : 0) + HasChain + HasInGlue;
+
+  // Check the lower bound.
+  if (ActualNumOperands < ExpectedMinNumOperands) {
+    StringRef How = HasOptionalOperands ? "at least " : "";
+    reportNodeError(DAG, N,
+                    "invalid number of operands; expected " + How +
+                        Twine(ExpectedMinNumOperands) + ", got " +
+                        Twine(ActualNumOperands));
+  }
+
+  // Check the upper bound. We can only do this if the number of fixed operands
+  // is known and there are no variadic operands.
+  if (Desc.NumOperands >= 0 && !IsVariadic) {
+    // Account for optional input glue.
+    unsigned ExpectedMaxNumOperands = ExpectedMinNumOperands + HasOptInGlue;
+    if (ActualNumOperands > ExpectedMaxNumOperands) {
+      StringRef How = HasOptInGlue ? "at most " : "";
+      reportNodeError(DAG, N,
+                      "invalid number of operands; expected " + How +
+                          Twine(ExpectedMaxNumOperands) + ", got " +
+                          Twine(ActualNumOperands));
+    }
+  }
+
+  // Chain operand comes first.
+  if (HasChain)
+    checkOperandValueType(DAG, N, 0, MVT::Other);
+
+  // Glue operand comes last.
+  if (HasInGlue)
+    checkOperandValueType(DAG, N, ActualNumOperands - 1, MVT::Glue);
+  if (HasOptInGlue && ActualNumOperands >= 1 &&
+      N->getOperand(ActualNumOperands - 1).getValueType() == MVT::Glue)
+    HasInGlue = true;
+
+  // Check variadic operands.
+  if (IsVariadic && Desc.NumOperands >= 0) {
+    unsigned VarOpStart = HasChain + Desc.NumOperands;
+    unsigned VarOpEnd = ActualNumOperands - HasInGlue;
+    for (unsigned OpIdx = VarOpStart; OpIdx != VarOpEnd; ++OpIdx) {
+      unsigned OpOpcode = N->getOperand(OpIdx).getOpcode();
+      if (OpOpcode != ISD::Register && OpOpcode != ISD::RegisterMask)
+        reportNodeError(DAG, N,
+                        "variadic operand #" + Twine(OpIdx) +
+                            " must be Register or RegisterMask");
+    }
+  }
+}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 9d6430e697f241..528f92d68a7144 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -1127,11 +1127,11 @@ void SelectionDAG::DeallocateNode(SDNode *N) {
 
 #ifndef NDEBUG
 /// VerifySDNode - Check the given SDNode.  Aborts if it is invalid.
-static void VerifySDNode(SDNode *N, const TargetLowering *TLI) {
+static void VerifySDNode(const SelectionDAG &DAG, SDNode *N) {
   switch (N->getOpcode()) {
   default:
     if (N->getOpcode() > ISD::BUILTIN_OP_END)
-      TLI->verifyTargetSDNode(N);
+      DAG.getSelectionDAGInfo().verifyTargetNode(DAG, N);
     break;
   case ISD::BUILD_PAIR: {
     EVT VT = N->getValueType(0);
@@ -1175,7 +1175,7 @@ void SelectionDAG::InsertNode(SDNode *N) {
   AllNodes.push_back(N);
 #ifndef NDEBUG
   N->PersistentId = NextPersistentId++;
-  VerifySDNode(N, TLI);
+  VerifySDNode(*this, N);
 #endif
   for (DAGUpdateListener *DUL = UpdateListeners; DUL; DUL = DUL->Next)
     DUL->NodeInserted(N);
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index 580ff19065557b..4eab613b2188c4 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -21,6 +21,7 @@
 #include "llvm/CodeGen/MachineMemOperand.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/CodeGen/TargetInstrInfo.h"
 #include "llvm/CodeGen/TargetLowering.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
@@ -68,6 +69,9 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
       return "<<Unknown Machine Node #" + utostr(getOpcode()) + ">>";
     }
     if (G) {
+      const SelectionDAGTargetInfo &TSI = G->getSelectionDAGInfo();
+      if (const char *Name = TSI.getTargetNodeName(getOpcode()))
+        return Name;
       const TargetLowering &TLI = G->getTargetLoweringInfo();
       const char *Name = TLI.getTargetNodeName(getOpcode());
       if (Name) return Name;
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGTargetInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGTargetInfo.cpp
index 0f3b36658f10ad..bbfcd244a4d185 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGTargetInfo.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGTargetInfo.cpp
@@ -16,6 +16,12 @@ using namespace llvm;
 
 SelectionDAGTargetInfo::~SelectionDAGTargetInfo() = default;
 
+SelectionDAGGenTargetInfo::~SelectionDAGGenTargetInfo() = default;
+
+const char *SelectionDAGTargetInfo::getTargetNodeName(unsigned Opcode) const {
+  return nullptr;
+}
+
 bool SelectionDAGTargetInfo::mayRaiseFPException(unsigned Opcode) const {
   // FIXME: All target memory opcodes are currently automatically considered
   //  to possibly raise FP exceptions. See rev. 63336795.
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 41e0214dab6c73..23274574c838c5 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -29726,83 +29726,3 @@ bool AArch64TargetLowering::isTypeDesirableForOp(unsigned Opc, EVT VT) const {
 
   return TargetLowering::isTypeDesirableForOp(Opc, VT);
 }
-
-#ifndef NDEBUG
-void AArch64TargetLowering::verifyTargetSDNode(const SDNode *N) const {
-  switch (N->getOpcode()) {
-  default:
-    break;
-  case AArch64ISD::SADDWT:
-  case AArch64ISD::SADDWB:
-  case AArch64ISD::UADDWT:
-  case AArch64ISD::UADDWB: {
-    assert(N->getNumValues() == 1 && "Expected one result!");
-    assert(N->getNumOperands() == 2 && "Expected two operands!");
-    EVT VT = N->getValueType(0);
-    EVT Op0VT = N->getOperand(0).getValueType();
-    EVT Op1VT = N->getOperand(1).getValueType();
-    assert(VT.isVector() && Op0VT.isVector() && Op1VT.isVector() &&
-           VT.isInteger() && Op0VT.isInteger() && Op1VT.isInteger() &&
-           "Expected integer vectors!");
-    assert(VT == Op0VT &&
-           "Expected result and first input to have the same type!");
-    assert(Op0VT.getSizeInBits() == Op1VT.getSizeInBits() &&
-           "Expected vectors of equal size!");
-    assert(Op0VT.getVectorElementCount() * 2 == Op1VT.getVectorElementCount() &&
-           "Expected result vector and first input vector to have half the "
-           "lanes of the second input vector!");
-    break;
-  }
-  case AArch64ISD::SUNPKLO:
-  case AArch64ISD::SUNPKHI:
-  case AArch64ISD::UUNPKLO:
-  case AArch64ISD::UUNPKHI: {
-    assert(N->getNumValues() == 1 && "Expected one result!");
-    assert(N->getNumOperands() == 1 && "Expected one operand!");
-    EVT VT = N->getValueType(0);
-    EVT OpVT = N->getOperand(0).getValueType();
-    assert(OpVT.isVector() && VT.isVector() && OpVT.isInteger() &&
-           VT.isInteger() && "Expected integer vectors!");
-    assert(OpVT.getSizeInBits() == VT.getSizeInBits() &&
-           "Expected vectors of equal size!");
-    assert(OpVT.getVectorElementCount() == VT.getVectorElementCount() * 2 &&
-           "Expected result vector with half the lanes of its input!");
-    break;
-  }
-  case AArch64ISD::TRN1:
-  case AArch64ISD::TRN2:
-  case AArch64ISD::UZP1:
-  case AArch64ISD::UZP2:
-  case AArch64ISD::ZIP1:
-  case AArch64ISD::ZIP2: {
-    assert(N->getNumValues() == 1 && "Expected one result!");
-    assert(N->getNumOperands() == 2 && "Expected two operands!");
-    EVT VT = N->getValueType(0);
-    EVT Op0VT = N->getOperand(0).getValueType();
-    EVT Op1VT = N->getOperand(1).getValueType();
-    assert(VT.isVector() && Op0VT.isVector() && Op1VT.isVector() &&
-           "Expected vectors!");
-    assert(VT == Op0VT && VT == Op1VT && "Expected matching vectors!");
-    break;
-  }
-  case AArch64ISD::RSHRNB_I: {
-    assert(N->getNumValues() == 1 && "Expected one result!");
-    assert(N->getNumOperands() == 2 && "Expected two operands!");
-    EVT VT = N->getValueType(0);
-    EVT Op0VT = N->getOperand(0).getValueType();
-    EVT Op1VT = N->getOperand(1).getValueType();
-    assert(VT.isVector() && VT.isInteger() &&
-           "Expected integer vector result type!");
-    assert(Op0VT.isVector() && Op0VT.isInteger() &&
-           "Expected first operand to be an integer vector!");
-    assert(VT.getSizeInBits() == Op0VT.getSizeInBits() &&
-           "Expected vectors of equal size!");
-    assert(VT.getVectorElementCount() == Op0VT.getVectorElementCount() * 2 &&
-           "Expected input vector with half the lanes of its result!");
-    assert(Op1VT == MVT::i32 && isa<ConstantSDNode>(N->getOperand(1)) &&
-           "Expected second operand to be a constant i32!");
-    break;
-  }
-  }
-}
-#endif
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index 835c9381834724..8d0c30ecacfc40 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -1019,10 +1019,6 @@ class AArch64TargetLowering : public TargetLowering {
   /// True if stack clash protection is enabled for this functions.
   bool hasInlineStackProbe(const MachineFunction &MF) const override;
 
-#ifndef NDEBUG
-  void verifyTargetSDNode(const SDNode *N) const override;
-#endif
-
 private:
   /// Keep a pointer to the AArch64Subtarget around so that we can
   /// make the right decision when generating code for different targets.
diff --git a/llvm/utils/TableGen/CMakeLists.txt b/llvm/utils/TableGen/CMakeLists.txt
index ba1e4aa01b48d6..e5b53dc4926dac 100644
--- a/llvm/utils/TableGen/CMakeLists.txt
+++ b/llvm/utils/TableGen/CMakeLists.txt
@@ -65,6 +65,7 @@ add_tablegen(llvm-tblgen LLVM
   RegisterBankEmitter.cpp
   RegisterInfoEmitter.cpp
   RISCVTargetDefEmitter.cpp
+  SDNodeInfoEmitter.cpp
   SearchableTableEmitter.cpp
   SubtargetEmitter.cpp
   TableGen.cpp
diff --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
index 31bf9a98943e56..6db924dfccaf25 100644
--- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
@@ -1707,6 +1707,60 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode &N,
   llvm_unreachable("Invalid ConstraintType!");
 }
 
+bool llvm::operator==(const SDTypeConstraint &LHS,
+                      const SDTypeConstraint &RHS) {
+  if (std::tie(LHS.OperandNo, LHS.ConstraintType) !=
+      std::tie(RHS.OperandNo, RHS.ConstraintType))
+    return false;
+  switch (LHS.ConstraintType) {
+  case SDTypeConstraint::SDTCisVT:
+  case SDTypeConstraint::SDTCVecEltisVT:
+    return LHS.VVT == RHS.VVT;
+  case SDTypeConstraint::SDTCisPtrTy:
+  case SDTypeConstraint::SDTCisInt:
+  case SDTypeConstraint::SDTCisFP:
+  case SDTypeConstraint::SDTCisVec:
+    break;
+  case SDTypeConstraint::SDTCisSameAs:
+  case SDTypeConstraint::SDTCisVTSmallerThanOp:
+  case SDTypeConstraint::SDTCisOpSmallerThanOp:
+  case SDTypeConstraint::SDTCisEltOfVec:
+  case SDTypeConstraint::SDTCisSubVecOfVec:
+  case SDTypeConstraint::SDTCisSameNumEltsAs:
+  case SDTypeConstraint::SDTCisSameSizeAs:
+    return LHS.x.SDTCisSameSizeAs_Info.OtherOperandNum ==
+           RHS.x.SDTCisSameSizeAs_Info.OtherOperandNum;
+  }
+  return true;
+}
+
+bool llvm::operator<(const SDTypeConstraint &LHS, const SDTypeConstraint &RHS) {
+  if (std::tie(LHS.OperandNo, LHS.ConstraintType) !=
+      std::tie(RHS.OperandNo, RHS.ConstraintType))
+    return std::tie(LHS.OperandNo, LHS.ConstraintType) <
+           std::tie(RHS.OperandNo, RHS.ConstraintType);
+  switch (LHS.ConstraintType) {
+  case SDTypeConstraint::SDTCisVT:
+  case SDTypeConstraint::SDTCVecEltisVT:
+    return LHS.VVT < RHS.VVT;
+  case SDTypeConstraint::SDTCisPtrTy:
+  case SDTypeConstraint::SDTCisInt:
+  case SDTypeConstraint::SDTCisFP:
+  case SDTypeConstraint::SDTCisVec:
+    break;
+  case SDTypeConstraint::SDTCisSameAs:
+  case SDTypeConstraint::SDTCisVTSmallerThanOp:
+  case SDTypeConstraint::SDTCisOpSmallerThanOp:
+  case SDTypeConstraint::SDTCisEltOfVec:
+  case SDTypeConstraint::SDTCisSubVecOfVec:
+  case SDTypeConstraint::SDTCisSameNumEltsAs:
+  case SDTypeConstraint::SDTCisSameSizeAs:
+    return LHS.x.SDTCisSameSizeAs_Info.OtherOperandNum <
+           RHS.x.SDTCisSameSizeAs_Info.OtherOperandNum;
+  }
+  return false;
+}
+
 // Update the node type to match an instruction operand or result as specified
 // in the ins or outs lists on the instruction definition. Return true if the
 // type was actually changed.
@@ -1797,6 +1851,13 @@ SDNodeInfo::SDNodeInfo(const Record *R, const CodeGenHwModes &CGH) : Def(R) {
 
   // Parse the properties.
   Properties = parseSDPatternOperatorProperties(R);
+  IsStrictFP = R->getValueAsBit("IsStrictFP");
+
+  std::optional<uint64_t> MaybeTSFlags =
+      R->getValueAsBitsInit("TSFlags")->convertInitializerToInt();
+  if (!MaybeTSFlags)
+    PrintFatalError(R->getLoc(), "Invalid TSFlags");
+  TSFlags = *MaybeTSFlags;
 
   // Parse the type constraints.
   for (const Record *R : TypeProfile->getValueAsListOfDefs("Constraints"))
diff --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
index f8c39172938256..121504e95954da 100644
--- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
+++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
@@ -354,6 +354,7 @@ typedef StringSet<> MultipleUseVarSet;
 /// SDTypeConstraint - This is a discriminated union of constraints,
 /// corresponding to the SDTypeConstraint tablegen class in Target.td.
 struct SDTypeConstraint {
+  SDTypeConstraint() = default;
   SDTypeConstraint(const Record *R, const CodeGenHwModes &CGH);
 
   unsigned OperandNo; // The operand # this constraint applies to.
@@ -407,6 +408,11 @@ struct SDTypeConstraint {
   /// is flagged.
   bool ApplyTypeConstraint(TreePatternNode &N, const SDNodeInfo &NodeInfo,
                            TreePattern &TP) const;
+
+  friend bool operator==(const SDTypeConstraint &LHS,
+                         const SDTypeConstraint &RHS);
+  friend bool operator<(const SDTypeConstraint &LHS,
+                        const SDTypeConstraint &RHS);
 };
 
 /// ScopedName - A name of a node associated with a "scope" that indicates
@@ -438,9 +444,11 @@ class SDNodeInfo {
   const Record *Def;
   StringRef EnumName;
   StringRef SDClassName;
-  unsigned Properties;
   unsigned NumResults;
   int NumOperands;
+  unsigned Properties;
+  bool IsStrictFP;
+  uint64_t TSFlags;
   std::vector<SDTypeConstraint> TypeConstraints;
 
 public:
@@ -465,10 +473,16 @@ class SDNodeInfo {
   /// MVT::SimpleValueType.  Otherwise, return MVT::Other.
   MVT::SimpleValueType getKnownType(unsigned ResNo) const;
 
+  unsigned getProperties() const { return Properties; }
+
   /// hasProperty - Return true if this node has the specified property.
   ///
   bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); }
 
+  bool isStrictFP() const { return IsStrictFP; }
+
+  uint64_t getTSFlags() const { return TSFlags; }
+
   /// ApplyTypeConstraints - Given a node in a pattern, apply the type
   /// constraints for this node to the operands of the node.  This returns
   /// true if it makes a change, false otherwise.  If a type contradiction is
diff --git a/llvm/utils/TableGen/SDNodeInfoEmitter.cpp b/llvm/utils/TableGen/SDNodeInfoEmitter.cpp
new file mode 100644
index 00000000000000..b0257554430ff4
--- /dev/null
+++ b/llvm/utils/TableGen/SDNodeInfoEmitter.cpp
@@ -0,0 +1,308 @@
+#include "Basic/SequenceToOffsetTable.h"
+#include "Common/CodeGenDAGPatterns.h" // For SDNodeInfo.
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TableGen/StringToOffsetTable.h"
+#include "llvm/TableGen/TableGenBackend.h"
+
+using namespace llvm;
+
+static cl::OptionCategory SDNodeInfoEmitterCat("Options for -gen-sdnode-info");
+
+static cl::opt<std::string> TargetSDNodeNamespace(
+    "sdnode-namespace", cl::cat(SDNodeInfoEmitterCat),
+    cl::desc("Specify target SDNode namespace (default=<Target>ISD)"));
+
+namespace {
+
+class SDNodeInfoEmitter {
+  const RecordKeeper &RK;
+  const CodeGenTarget Target;
+  std::vector<SDNodeInfo> AllNodes;
+  std::map<StringRef, SmallVector<const SDNodeInfo *, 2>> TargetNodesByName;
+
+public:
+  explicit SDNodeInfoEmitter(const RecordKeeper &RK);
+
+  void run(raw_ostream &OS) const;
+
+private:
+  void emitNodeEnum(raw_ostream &OS) const;
+  void emitNodeNames(raw_ostream &OS) const;
+  void emitTypeConstraints(raw_ostream &OS) const;
+  void emitNodeDescs(raw_ostream &OS) const;
+};
+
+} // namespace
+
+SDNodeInfoEmitter::SDNodeInfoEmitter(const RecordKeeper &RK)
+    : RK(RK), Target(RK) {
+  const CodeGenHwModes &HwModes = Target.getHwModes();
+
+  if (!TargetSDNodeNamespace.getNumOccurrences())
+    TargetSDNodeNamespace = Target.getName().str() + "ISD";
+
+  for (const Record *R : RK.getAllDerivedDefinitions("SDNode"))
+    AllNodes.emplace_back(R, HwModes);
+
+  for (const SDNodeInfo &Node : AllNodes) {
+    StringRef QualifiedName = Node.getEnumName();
+    auto [NS, Name] = QualifiedName.split("::");
+
+    if (NS == TargetSDNodeNamespace)
+      TargetNodesByName[Name].push_back(&Node);
+  }
+}
+
+void SDNodeInfoEmitter::emitNodeEnum(raw_ostream &OS) const {
+  OS << "#ifdef GET_SDNODE_ENUM\n";
+  OS << "#undef GET_SDNODE_ENUM\n\n";
+  OS << "namespace llvm::" << TargetSDNodeNamespace << " {\n\n";
+
+  OS << "enum GenNodeType : unsigned {\n";
+
+  if (!TargetNodesByName.empty()) {
+    StringRef FirstName = TargetNodesByName.begin()->first;
+    OS << "  " << FirstName << " = ISD::BUILTIN_OP_END,\n";
+    for (StringRef Name : make_first_range(drop_begin(TargetNodesByName)))
+      OS << "  " << Name << ",\n";
+  }
+
+  OS << "};\n\n";
+
+  if (!TargetNodesByName.empty()) {
+    StringRef LastName = TargetNodesByName.rbegin()->first;
+    OS << "static constexpr unsigned GENERATED_OPCODE_END = " << LastName
+       << " + 1;\n\n";
+  }
+
+  OS << "} // namespace llvm::" << TargetSDNodeNamespace << "\n\n";
+  OS << "#endif // GET_SDNODE_ENUM\n\n";
+}
+
+void SDNodeInfoEmitter::emitNodeNames(raw_ostream &OS) const {
+  StringRef TargetName = Target.getName();
+  StringToOffsetTable NodeNameTable;
+
+  OS << "static const unsigned " << TargetName << "NodeNameOffsets["
+     << TargetNodesByName.size() << "] = {";
+
+  std::string DebugName;
+  for (auto [Idx, Name] : enumerate(make_first_range(TargetNodesByName))) {
+    // Newline every 8 entries.
+    OS << (Idx % 8 == 0 ? "\n    " : " ");
+    DebugName = (TargetSDNodeNamespace + "::" + Name).str();
+    OS << NodeNameTable.GetOrAddStringOffset(DebugName) << ",";
+  }
+
+  OS << "\n};\n";
+
+  NodeNameTable.EmitStringLiteralDef(
+      OS, "static const char " + TargetName + "NodeNames[]", /*Indent=*/"");
+
+  OS << "\n";
+}
+
+static void emitConstraint(raw_ostream &OS, SDTypeConstraint C) {
+  StringRef Name;
+  unsigned OtherOpNo = 0;
+  MVT VT;
+
+  switch (C.ConstraintType) {
+  case SDTypeConstraint::SDTCisVT:
+    Name = "SDTCisVT";
+    if (C.VVT.isSimple())
+      VT = C.VVT.getSimple();
+    break;
+  case SDTypeConstraint::SDTCisPtrTy:
+    Name = "SDTCisPtrTy";
+    break;
+  case SDTypeConstraint::SDTCisInt:
+    Name = "SDTCisInt";
+    break;
+  case SDTypeConstraint::SDTCisFP:
+    Name = "SDTCisFP";
+    break;
+  case SDTypeConstraint::SDTCisVec:
+    Name = "SDTCisVec";
+    break;
+  case SDTypeConstraint::SDTCisSameAs:
+    Name = "SDTCisSameAs";
+    OtherOpNo = C.x.SDTCisSameAs_Info.OtherOperandNum;
+    break;
+  case SDTypeConstraint::SDTCisVTSmallerThanOp:
+    Name = "SDTCisVTSmallerThanOp";
+    OtherOpNo = C.x.SDTCisVTSmallerThanOp_Info.OtherOperandNum;
+    break;
+  case SDTypeConstraint::SDTCisOpSmallerThanOp:
+    Name = "SDTCisOpSmallerThanOp";
+    OtherOpNo = C.x.SDTCisOpSmallerThanOp_Info.BigOperandNum;
+    break;
+  case SDTypeConstraint::SDTCisEltOfVec:
+    Name = "SDTCisEltOfVec";
+    OtherOpNo = C.x.SDTCisEltOfVec_Info.OtherOperandNum;
+    break;
+  case SDTypeConstraint::SDTCisSubVecOfVec:
+    Name = "SDTCisSubVecOfVec";
+    OtherOpNo = C.x.SDTCisSubVecOfVec_Info.OtherOperandNum;
+    break;
+  case SDTypeConstraint::SDTCVecEltisVT:
+    Name = "SDTCVecEltisVT";
+    if (C.VVT.isSimple())
+      VT = C.VVT.getSimple();
+    break;
+  case SDTypeConstraint::SDTCisSameNumEltsAs:
+    Name = "SDTCisSameNumEltsAs";
+    OtherOpNo = C.x.SDTCisSameNumEltsAs_Info.OtherOperandNum;
+    break;
+  case SDTypeConstraint::SDTCisSameSizeAs:
+    Name = "SDTCisSameSizeAs";
+    OtherOpNo = C.x.SDTCisSameSizeAs_Info.OtherOperandNum;
+    break;
+  }
+
+  StringRef VTName = VT.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE
+                         ? "MVT::INVALID_SIMPLE_VALUE_TYPE"
+                         : getEnumName(VT.SimpleTy);
+  OS << '{' << C.OperandNo << ", " << Name << ", " << OtherOpNo << ", "
+     << VTName << '}';
+}
+
+void SDNodeInfoEmitter::emitTypeConstraints(raw_ostream &OS) const {
+  SequenceToOffsetTable<SmallVector<SDTypeConstraint, 0>> ConstraintTable(
+      /*Terminator=*/std::nullopt);
+  SmallVector<StringRef> SkippedNodes;
+
+  for (const auto &[Name, Nodes] : TargetNodesByName) {
+    const SDNodeInfo *N = Nodes.front();
+    ArrayRef<SDTypeConstraint> Constraints = N->getTypeConstraints();
+
+    bool IsAmbiguous = any_of(drop_begin(Nodes), [&](const SDNodeInfo *Other) {
+      return ArrayRef(Other->getTypeConstraints()) != Constraints;
+    });
+
+    if (IsAmbiguous) {
+      SkippedNodes.push_back(Name);
+      continue;
+    }
+
+    // Reversing the order increases the likelihood of reusing storage.
+    SmallVector<SDTypeConstraint, 0> RevConstraints(reverse(Constraints));
+    ConstraintTable.add(RevConstraints);
+  }
+
+  ConstraintTable.layout();
+
+  OS << "static const SDTypeConstraint " << Target.getName()
+     << "SDTypeConstraints[" << ConstraintTable.size() << "] = {\n";
+  ConstraintTable.emit(OS, emitConstraint);
+  OS << "};\n\n";
+
+  unsigned NumOpcodes = TargetNodesByName.size();
+  OS << "static const std::pair<unsigned, unsigned> " << Target.getName()
+     << "SDTypeConstraintOffsets[" << NumOpcodes << "] = {";
+
+  unsigned Idx = 0;
+  for (const auto &[Name, Nodes] : TargetNodesByName) {
+    // Newline every 8 entries.
+    OS << (Idx++ % 8 == 0 ? "\n    " : " ");
+
+    if (is_contained(SkippedNodes, Name)) {
+      OS << "{0, 0},";
+      continue;
+    }
+
+    ArrayRef<SDTypeConstraint> Constraints = Nodes[0]->getTypeConstraints();
+    SmallVector<SDTypeConstraint, 0> RevConstraints(reverse(Constraints));
+    OS << '{' << ConstraintTable.get(RevConstraints) << ", "
+       << Constraints.size() << "},";
+  }
+
+  OS << "};\n\n";
+}
+
+static void emitDesc(raw_ostream &OS, StringRef Name,
+                     ArrayRef<const SDNodeInfo *> Nodes) {
+  const SDNodeInfo *N = Nodes.front();
+
+  // We're only interested in a subset of node properties. Properties like
+  // SDNPAssociative and SDNPCommutative do not impose constraints on nodes,
+  // and sometimes differ between nodes using the same enum name.
+  constexpr unsigned InterestingProperties =
+      (1 << SDNPHasChain) | (1 << SDNPOutGlue) | (1 << SDNPInGlue) |
+      (1 << SDNPOptInGlue) | (1 << SDNPMemOperand) | (1 << SDNPVariadic);
+
+  unsigned NumResults = N->getNumResults();
+  int NumOperands = N->getNumOperands();
+  unsigned Properties = N->getProperties();
+  bool IsStrictFP = N->isStrictFP();
+  uint64_t TSFlags = N->getTSFlags();
+
+  assert(all_of(drop_begin(Nodes), [&](const SDNodeInfo *Other) {
+    return Other->getNumResults() == NumResults &&
+           Other->getNumOperands() == NumOperands &&
+           (Other->getProperties() & InterestingProperties) ==
+               (Properties & InterestingProperties) &&
+           Other->isStrictFP() == IsStrictFP && Other->getTSFlags() == TSFlags;
+  }));
+
+  OS << "    {" << NumResults;
+  OS << ", " << NumOperands;
+
+  OS << ", 0";
+  if (Properties & (1 << SDNPHasChain))
+    OS << "|1<<SDNPHasChain";
+  if (Properties & (1 << SDNPOutGlue))
+    OS << "|1<<SDNPOutGlue";
+  if (Properties & (1 << SDNPInGlue))
+    OS << "|1<<SDNPInGlue";
+  if (Properties & (1 << SDNPOptInGlue))
+    OS << "|1<<SDNPOptInGlue";
+  if (Properties & (1 << SDNPVariadic))
+    OS << "|1<<SDNPVariadic";
+  if (Properties & (1 << SDNPMemOperand))
+    OS << "|1<<SDNPMemOperand";
+
+  OS << ", 0";
+  if (IsStrictFP)
+    OS << "|1<<SDNFIsStrictFP";
+
+  OS << ", " << TSFlags;
+  OS << "}," << " // " << Name << '\n';
+}
+
+void SDNodeInfoEmitter::emitNodeDescs(raw_ostream &OS) const {
+  StringRef TargetName = Target.getName();
+
+  OS << "#ifdef GET_SDNODE_DESC\n";
+  OS << "#undef GET_SDNODE_DESC\n\n";
+  OS << "namespace llvm {\n\n";
+
+  emitNodeNames(OS);
+  emitTypeConstraints(OS);
+
+  unsigned NumOpcodes = TargetNodesByName.size();
+  OS << "static const SDNodeDesc " << TargetName << "NodeDescs[" << NumOpcodes
+     << "] = {\n";
+
+  for (const auto &[Name, Nodes] : TargetNodesByName)
+    emitDesc(OS, Name, Nodes);
+
+  OS << "};\n\n";
+
+  OS << "static const SDNodeInfo " << TargetName << "GenSDNodeInfo(\n    "
+     << NumOpcodes << ", " << TargetName << "NodeDescs,\n    " << TargetName
+     << "NodeNames, " << TargetName << "NodeNameOffsets,\n    " << TargetName
+     << "SDTypeConstraints, " << TargetName << "SDTypeConstraintOffsets);\n\n";
+
+  OS << "} // namespace llvm\n\n";
+  OS << "#endif // GET_SDNODE_DESC\n\n";
+}
+
+void SDNodeInfoEmitter::run(raw_ostream &OS) const {
+  emitSourceFileHeader("Target SDNode descriptions", OS, RK);
+  emitNodeEnum(OS);
+  emitNodeDescs(OS);
+}
+
+static TableGen::Emitter::OptClass<SDNodeInfoEmitter>
+    X("gen-sd-node-info", "Generate target SDNode descriptions");

>From 4e6747f22924e6f7747b518def5d807dd3b7867c Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 01:00:33 +0300
Subject: [PATCH 04/27] AArch64

---
 .../Target/AArch64/AArch64ISelLowering.cpp    | 343 ------------
 llvm/lib/Target/AArch64/AArch64ISelLowering.h | 505 ------------------
 llvm/lib/Target/AArch64/AArch64InstrInfo.td   |  12 +-
 .../AArch64/AArch64SelectionDAGInfo.cpp       | 132 ++++-
 .../Target/AArch64/AArch64SelectionDAGInfo.h  |  88 ++-
 llvm/lib/Target/AArch64/CMakeLists.txt        |   1 +
 llvm/lib/Target/AArch64/SMEInstrFormats.td    |   7 +-
 llvm/unittests/CodeGen/CMakeLists.txt         |   1 -
 .../AArch64}/AArch64SelectionDAGTest.cpp      |  14 +-
 llvm/unittests/Target/AArch64/CMakeLists.txt  |   2 +
 10 files changed, 223 insertions(+), 882 deletions(-)
 rename llvm/unittests/{CodeGen => Target/AArch64}/AArch64SelectionDAGTest.cpp (98%)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 23274574c838c5..d645d3c18416f0 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -2622,343 +2622,6 @@ AArch64TargetLowering::createFastISel(FunctionLoweringInfo &funcInfo,
   return AArch64::createFastISel(funcInfo, libInfo);
 }
 
-const char *AArch64TargetLowering::getTargetNodeName(unsigned Opcode) const {
-#define MAKE_CASE(V)                                                           \
-  case V:                                                                      \
-    return #V;
-  switch ((AArch64ISD::NodeType)Opcode) {
-  case AArch64ISD::FIRST_NUMBER:
-    break;
-    MAKE_CASE(AArch64ISD::ALLOCATE_ZA_BUFFER)
-    MAKE_CASE(AArch64ISD::INIT_TPIDR2OBJ)
-    MAKE_CASE(AArch64ISD::COALESCER_BARRIER)
-    MAKE_CASE(AArch64ISD::VG_SAVE)
-    MAKE_CASE(AArch64ISD::VG_RESTORE)
-    MAKE_CASE(AArch64ISD::SMSTART)
-    MAKE_CASE(AArch64ISD::SMSTOP)
-    MAKE_CASE(AArch64ISD::RESTORE_ZA)
-    MAKE_CASE(AArch64ISD::RESTORE_ZT)
-    MAKE_CASE(AArch64ISD::SAVE_ZT)
-    MAKE_CASE(AArch64ISD::CALL)
-    MAKE_CASE(AArch64ISD::ADRP)
-    MAKE_CASE(AArch64ISD::ADR)
-    MAKE_CASE(AArch64ISD::ADDlow)
-    MAKE_CASE(AArch64ISD::AUTH_CALL)
-    MAKE_CASE(AArch64ISD::AUTH_TC_RETURN)
-    MAKE_CASE(AArch64ISD::AUTH_CALL_RVMARKER)
-    MAKE_CASE(AArch64ISD::LOADgot)
-    MAKE_CASE(AArch64ISD::RET_GLUE)
-    MAKE_CASE(AArch64ISD::BRCOND)
-    MAKE_CASE(AArch64ISD::CSEL)
-    MAKE_CASE(AArch64ISD::CSINV)
-    MAKE_CASE(AArch64ISD::CSNEG)
-    MAKE_CASE(AArch64ISD::CSINC)
-    MAKE_CASE(AArch64ISD::THREAD_POINTER)
-    MAKE_CASE(AArch64ISD::TLSDESC_CALLSEQ)
-    MAKE_CASE(AArch64ISD::PROBED_ALLOCA)
-    MAKE_CASE(AArch64ISD::ABDS_PRED)
-    MAKE_CASE(AArch64ISD::ABDU_PRED)
-    MAKE_CASE(AArch64ISD::HADDS_PRED)
-    MAKE_CASE(AArch64ISD::HADDU_PRED)
-    MAKE_CASE(AArch64ISD::MUL_PRED)
-    MAKE_CASE(AArch64ISD::MULHS_PRED)
-    MAKE_CASE(AArch64ISD::MULHU_PRED)
-    MAKE_CASE(AArch64ISD::RHADDS_PRED)
-    MAKE_CASE(AArch64ISD::RHADDU_PRED)
-    MAKE_CASE(AArch64ISD::SDIV_PRED)
-    MAKE_CASE(AArch64ISD::SHL_PRED)
-    MAKE_CASE(AArch64ISD::SMAX_PRED)
-    MAKE_CASE(AArch64ISD::SMIN_PRED)
-    MAKE_CASE(AArch64ISD::SRA_PRED)
-    MAKE_CASE(AArch64ISD::SRL_PRED)
-    MAKE_CASE(AArch64ISD::UDIV_PRED)
-    MAKE_CASE(AArch64ISD::UMAX_PRED)
-    MAKE_CASE(AArch64ISD::UMIN_PRED)
-    MAKE_CASE(AArch64ISD::SRAD_MERGE_OP1)
-    MAKE_CASE(AArch64ISD::FNEG_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::FCEIL_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::FFLOOR_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::FNEARBYINT_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::FRINT_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::FROUND_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::FROUNDEVEN_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::FTRUNC_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::FP_ROUND_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::FP_EXTEND_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::SINT_TO_FP_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::UINT_TO_FP_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::FCVTX_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::FCVTZU_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::FCVTZS_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::FSQRT_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::FRECPX_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::FABS_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::ABS_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::NEG_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::SETCC_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::ADC)
-    MAKE_CASE(AArch64ISD::SBC)
-    MAKE_CASE(AArch64ISD::ADDS)
-    MAKE_CASE(AArch64ISD::SUBS)
-    MAKE_CASE(AArch64ISD::ADCS)
-    MAKE_CASE(AArch64ISD::SBCS)
-    MAKE_CASE(AArch64ISD::ANDS)
-    MAKE_CASE(AArch64ISD::CCMP)
-    MAKE_CASE(AArch64ISD::CCMN)
-    MAKE_CASE(AArch64ISD::FCCMP)
-    MAKE_CASE(AArch64ISD::FCMP)
-    MAKE_CASE(AArch64ISD::STRICT_FCMP)
-    MAKE_CASE(AArch64ISD::STRICT_FCMPE)
-    MAKE_CASE(AArch64ISD::FCVTXN)
-    MAKE_CASE(AArch64ISD::SME_ZA_LDR)
-    MAKE_CASE(AArch64ISD::SME_ZA_STR)
-    MAKE_CASE(AArch64ISD::DUP)
-    MAKE_CASE(AArch64ISD::DUPLANE8)
-    MAKE_CASE(AArch64ISD::DUPLANE16)
-    MAKE_CASE(AArch64ISD::DUPLANE32)
-    MAKE_CASE(AArch64ISD::DUPLANE64)
-    MAKE_CASE(AArch64ISD::DUPLANE128)
-    MAKE_CASE(AArch64ISD::MOVI)
-    MAKE_CASE(AArch64ISD::MOVIshift)
-    MAKE_CASE(AArch64ISD::MOVIedit)
-    MAKE_CASE(AArch64ISD::MOVImsl)
-    MAKE_CASE(AArch64ISD::FMOV)
-    MAKE_CASE(AArch64ISD::MVNIshift)
-    MAKE_CASE(AArch64ISD::MVNImsl)
-    MAKE_CASE(AArch64ISD::BICi)
-    MAKE_CASE(AArch64ISD::ORRi)
-    MAKE_CASE(AArch64ISD::BSP)
-    MAKE_CASE(AArch64ISD::ZIP1)
-    MAKE_CASE(AArch64ISD::ZIP2)
-    MAKE_CASE(AArch64ISD::UZP1)
-    MAKE_CASE(AArch64ISD::UZP2)
-    MAKE_CASE(AArch64ISD::TRN1)
-    MAKE_CASE(AArch64ISD::TRN2)
-    MAKE_CASE(AArch64ISD::REV16)
-    MAKE_CASE(AArch64ISD::REV32)
-    MAKE_CASE(AArch64ISD::REV64)
-    MAKE_CASE(AArch64ISD::EXT)
-    MAKE_CASE(AArch64ISD::SPLICE)
-    MAKE_CASE(AArch64ISD::VSHL)
-    MAKE_CASE(AArch64ISD::VLSHR)
-    MAKE_CASE(AArch64ISD::VASHR)
-    MAKE_CASE(AArch64ISD::VSLI)
-    MAKE_CASE(AArch64ISD::VSRI)
-    MAKE_CASE(AArch64ISD::CMEQ)
-    MAKE_CASE(AArch64ISD::CMGE)
-    MAKE_CASE(AArch64ISD::CMGT)
-    MAKE_CASE(AArch64ISD::CMHI)
-    MAKE_CASE(AArch64ISD::CMHS)
-    MAKE_CASE(AArch64ISD::FCMEQ)
-    MAKE_CASE(AArch64ISD::FCMGE)
-    MAKE_CASE(AArch64ISD::FCMGT)
-    MAKE_CASE(AArch64ISD::CMEQz)
-    MAKE_CASE(AArch64ISD::CMGEz)
-    MAKE_CASE(AArch64ISD::CMGTz)
-    MAKE_CASE(AArch64ISD::CMLEz)
-    MAKE_CASE(AArch64ISD::CMLTz)
-    MAKE_CASE(AArch64ISD::FCMEQz)
-    MAKE_CASE(AArch64ISD::FCMGEz)
-    MAKE_CASE(AArch64ISD::FCMGTz)
-    MAKE_CASE(AArch64ISD::FCMLEz)
-    MAKE_CASE(AArch64ISD::FCMLTz)
-    MAKE_CASE(AArch64ISD::SADDV)
-    MAKE_CASE(AArch64ISD::UADDV)
-    MAKE_CASE(AArch64ISD::UADDLV)
-    MAKE_CASE(AArch64ISD::SADDLV)
-    MAKE_CASE(AArch64ISD::SADDWT)
-    MAKE_CASE(AArch64ISD::SADDWB)
-    MAKE_CASE(AArch64ISD::UADDWT)
-    MAKE_CASE(AArch64ISD::UADDWB)
-    MAKE_CASE(AArch64ISD::SDOT)
-    MAKE_CASE(AArch64ISD::UDOT)
-    MAKE_CASE(AArch64ISD::USDOT)
-    MAKE_CASE(AArch64ISD::SMINV)
-    MAKE_CASE(AArch64ISD::UMINV)
-    MAKE_CASE(AArch64ISD::SMAXV)
-    MAKE_CASE(AArch64ISD::UMAXV)
-    MAKE_CASE(AArch64ISD::SADDV_PRED)
-    MAKE_CASE(AArch64ISD::UADDV_PRED)
-    MAKE_CASE(AArch64ISD::SMAXV_PRED)
-    MAKE_CASE(AArch64ISD::UMAXV_PRED)
-    MAKE_CASE(AArch64ISD::SMINV_PRED)
-    MAKE_CASE(AArch64ISD::UMINV_PRED)
-    MAKE_CASE(AArch64ISD::ORV_PRED)
-    MAKE_CASE(AArch64ISD::EORV_PRED)
-    MAKE_CASE(AArch64ISD::ANDV_PRED)
-    MAKE_CASE(AArch64ISD::CLASTA_N)
-    MAKE_CASE(AArch64ISD::CLASTB_N)
-    MAKE_CASE(AArch64ISD::LASTA)
-    MAKE_CASE(AArch64ISD::LASTB)
-    MAKE_CASE(AArch64ISD::REINTERPRET_CAST)
-    MAKE_CASE(AArch64ISD::LS64_BUILD)
-    MAKE_CASE(AArch64ISD::LS64_EXTRACT)
-    MAKE_CASE(AArch64ISD::TBL)
-    MAKE_CASE(AArch64ISD::FADD_PRED)
-    MAKE_CASE(AArch64ISD::FADDA_PRED)
-    MAKE_CASE(AArch64ISD::FADDV_PRED)
-    MAKE_CASE(AArch64ISD::FDIV_PRED)
-    MAKE_CASE(AArch64ISD::FMA_PRED)
-    MAKE_CASE(AArch64ISD::FMAX_PRED)
-    MAKE_CASE(AArch64ISD::FMAXV_PRED)
-    MAKE_CASE(AArch64ISD::FMAXNM_PRED)
-    MAKE_CASE(AArch64ISD::FMAXNMV_PRED)
-    MAKE_CASE(AArch64ISD::FMIN_PRED)
-    MAKE_CASE(AArch64ISD::FMINV_PRED)
-    MAKE_CASE(AArch64ISD::FMINNM_PRED)
-    MAKE_CASE(AArch64ISD::FMINNMV_PRED)
-    MAKE_CASE(AArch64ISD::FMUL_PRED)
-    MAKE_CASE(AArch64ISD::FSUB_PRED)
-    MAKE_CASE(AArch64ISD::RDSVL)
-    MAKE_CASE(AArch64ISD::BIC)
-    MAKE_CASE(AArch64ISD::CBZ)
-    MAKE_CASE(AArch64ISD::CBNZ)
-    MAKE_CASE(AArch64ISD::TBZ)
-    MAKE_CASE(AArch64ISD::TBNZ)
-    MAKE_CASE(AArch64ISD::TC_RETURN)
-    MAKE_CASE(AArch64ISD::PREFETCH)
-    MAKE_CASE(AArch64ISD::SITOF)
-    MAKE_CASE(AArch64ISD::UITOF)
-    MAKE_CASE(AArch64ISD::NVCAST)
-    MAKE_CASE(AArch64ISD::MRS)
-    MAKE_CASE(AArch64ISD::SQSHL_I)
-    MAKE_CASE(AArch64ISD::UQSHL_I)
-    MAKE_CASE(AArch64ISD::SRSHR_I)
-    MAKE_CASE(AArch64ISD::URSHR_I)
-    MAKE_CASE(AArch64ISD::SQSHLU_I)
-    MAKE_CASE(AArch64ISD::WrapperLarge)
-    MAKE_CASE(AArch64ISD::LD2post)
-    MAKE_CASE(AArch64ISD::LD3post)
-    MAKE_CASE(AArch64ISD::LD4post)
-    MAKE_CASE(AArch64ISD::ST2post)
-    MAKE_CASE(AArch64ISD::ST3post)
-    MAKE_CASE(AArch64ISD::ST4post)
-    MAKE_CASE(AArch64ISD::LD1x2post)
-    MAKE_CASE(AArch64ISD::LD1x3post)
-    MAKE_CASE(AArch64ISD::LD1x4post)
-    MAKE_CASE(AArch64ISD::ST1x2post)
-    MAKE_CASE(AArch64ISD::ST1x3post)
-    MAKE_CASE(AArch64ISD::ST1x4post)
-    MAKE_CASE(AArch64ISD::LD1DUPpost)
-    MAKE_CASE(AArch64ISD::LD2DUPpost)
-    MAKE_CASE(AArch64ISD::LD3DUPpost)
-    MAKE_CASE(AArch64ISD::LD4DUPpost)
-    MAKE_CASE(AArch64ISD::LD1LANEpost)
-    MAKE_CASE(AArch64ISD::LD2LANEpost)
-    MAKE_CASE(AArch64ISD::LD3LANEpost)
-    MAKE_CASE(AArch64ISD::LD4LANEpost)
-    MAKE_CASE(AArch64ISD::ST2LANEpost)
-    MAKE_CASE(AArch64ISD::ST3LANEpost)
-    MAKE_CASE(AArch64ISD::ST4LANEpost)
-    MAKE_CASE(AArch64ISD::SMULL)
-    MAKE_CASE(AArch64ISD::UMULL)
-    MAKE_CASE(AArch64ISD::PMULL)
-    MAKE_CASE(AArch64ISD::FRECPE)
-    MAKE_CASE(AArch64ISD::FRECPS)
-    MAKE_CASE(AArch64ISD::FRSQRTE)
-    MAKE_CASE(AArch64ISD::FRSQRTS)
-    MAKE_CASE(AArch64ISD::STG)
-    MAKE_CASE(AArch64ISD::STZG)
-    MAKE_CASE(AArch64ISD::ST2G)
-    MAKE_CASE(AArch64ISD::STZ2G)
-    MAKE_CASE(AArch64ISD::SUNPKHI)
-    MAKE_CASE(AArch64ISD::SUNPKLO)
-    MAKE_CASE(AArch64ISD::UUNPKHI)
-    MAKE_CASE(AArch64ISD::UUNPKLO)
-    MAKE_CASE(AArch64ISD::INSR)
-    MAKE_CASE(AArch64ISD::PTEST)
-    MAKE_CASE(AArch64ISD::PTEST_ANY)
-    MAKE_CASE(AArch64ISD::PTRUE)
-    MAKE_CASE(AArch64ISD::LD1_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::LD1S_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::LDNF1_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::LDNF1S_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::LDFF1_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::LDFF1S_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::LD1RQ_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::LD1RO_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::SVE_LD2_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::SVE_LD3_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::SVE_LD4_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLD1_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLD1_SCALED_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLD1_SXTW_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLD1_UXTW_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLD1_SXTW_SCALED_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLD1_UXTW_SCALED_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLD1_IMM_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLD1Q_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLD1Q_INDEX_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLD1S_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLD1S_SCALED_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLD1S_SXTW_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLD1S_UXTW_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLD1S_SXTW_SCALED_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLD1S_UXTW_SCALED_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLD1S_IMM_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLDFF1_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLDFF1_SCALED_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLDFF1_SXTW_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLDFF1_UXTW_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLDFF1_SXTW_SCALED_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLDFF1_UXTW_SCALED_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLDFF1_IMM_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLDFF1S_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLDFF1S_SCALED_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLDFF1S_SXTW_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLDFF1S_UXTW_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLDFF1S_SXTW_SCALED_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLDFF1S_UXTW_SCALED_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLDFF1S_IMM_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLDNT1_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLDNT1_INDEX_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::GLDNT1S_MERGE_ZERO)
-    MAKE_CASE(AArch64ISD::SST1Q_PRED)
-    MAKE_CASE(AArch64ISD::SST1Q_INDEX_PRED)
-    MAKE_CASE(AArch64ISD::ST1_PRED)
-    MAKE_CASE(AArch64ISD::SST1_PRED)
-    MAKE_CASE(AArch64ISD::SST1_SCALED_PRED)
-    MAKE_CASE(AArch64ISD::SST1_SXTW_PRED)
-    MAKE_CASE(AArch64ISD::SST1_UXTW_PRED)
-    MAKE_CASE(AArch64ISD::SST1_SXTW_SCALED_PRED)
-    MAKE_CASE(AArch64ISD::SST1_UXTW_SCALED_PRED)
-    MAKE_CASE(AArch64ISD::SST1_IMM_PRED)
-    MAKE_CASE(AArch64ISD::SSTNT1_PRED)
-    MAKE_CASE(AArch64ISD::SSTNT1_INDEX_PRED)
-    MAKE_CASE(AArch64ISD::LDP)
-    MAKE_CASE(AArch64ISD::LDIAPP)
-    MAKE_CASE(AArch64ISD::LDNP)
-    MAKE_CASE(AArch64ISD::STP)
-    MAKE_CASE(AArch64ISD::STILP)
-    MAKE_CASE(AArch64ISD::STNP)
-    MAKE_CASE(AArch64ISD::BITREVERSE_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::BSWAP_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::REVH_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::REVW_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::REVD_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::CTLZ_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::CTPOP_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::DUP_MERGE_PASSTHRU)
-    MAKE_CASE(AArch64ISD::INDEX_VECTOR)
-    MAKE_CASE(AArch64ISD::ADDP)
-    MAKE_CASE(AArch64ISD::SADDLP)
-    MAKE_CASE(AArch64ISD::UADDLP)
-    MAKE_CASE(AArch64ISD::CALL_RVMARKER)
-    MAKE_CASE(AArch64ISD::ASSERT_ZEXT_BOOL)
-    MAKE_CASE(AArch64ISD::CALL_BTI)
-    MAKE_CASE(AArch64ISD::MRRS)
-    MAKE_CASE(AArch64ISD::MSRR)
-    MAKE_CASE(AArch64ISD::RSHRNB_I)
-    MAKE_CASE(AArch64ISD::CTTZ_ELTS)
-    MAKE_CASE(AArch64ISD::CALL_ARM64EC_TO_X64)
-    MAKE_CASE(AArch64ISD::URSHR_I_PRED)
-  }
-#undef MAKE_CASE
-  return nullptr;
-}
-
 MachineBasicBlock *
 AArch64TargetLowering::EmitF128CSEL(MachineInstr &MI,
                                     MachineBasicBlock *MBB) const {
@@ -23195,12 +22858,6 @@ static SDValue performUzpCombine(SDNode *N, SelectionDAG &DAG,
 static SDValue performGLD1Combine(SDNode *N, SelectionDAG &DAG) {
   unsigned Opc = N->getOpcode();
 
-  assert(((Opc >= AArch64ISD::GLD1_MERGE_ZERO && // unsigned gather loads
-           Opc <= AArch64ISD::GLD1_IMM_MERGE_ZERO) ||
-          (Opc >= AArch64ISD::GLD1S_MERGE_ZERO && // signed gather loads
-           Opc <= AArch64ISD::GLD1S_IMM_MERGE_ZERO)) &&
-         "Invalid opcode.");
-
   const bool Scaled = Opc == AArch64ISD::GLD1_SCALED_MERGE_ZERO ||
                       Opc == AArch64ISD::GLD1S_SCALED_MERGE_ZERO;
   const bool Signed = Opc == AArch64ISD::GLD1S_MERGE_ZERO ||
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index 8d0c30ecacfc40..55cce6ceef66dd 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -23,509 +23,6 @@
 
 namespace llvm {
 
-namespace AArch64ISD {
-
-// For predicated nodes where the result is a vector, the operation is
-// controlled by a governing predicate and the inactive lanes are explicitly
-// defined with a value, please stick the following naming convention:
-//
-//    _MERGE_OP<n>        The result value is a vector with inactive lanes equal
-//                        to source operand OP<n>.
-//
-//    _MERGE_ZERO         The result value is a vector with inactive lanes
-//                        actively zeroed.
-//
-//    _MERGE_PASSTHRU     The result value is a vector with inactive lanes equal
-//                        to the last source operand which only purpose is being
-//                        a passthru value.
-//
-// For other cases where no explicit action is needed to set the inactive lanes,
-// or when the result is not a vector and it is needed or helpful to
-// distinguish a node from similar unpredicated nodes, use:
-//
-//    _PRED
-//
-enum NodeType : unsigned {
-  FIRST_NUMBER = ISD::BUILTIN_OP_END,
-  WrapperLarge, // 4-instruction MOVZ/MOVK sequence for 64-bit addresses.
-  CALL,         // Function call.
-
-  // Pseudo for a OBJC call that gets emitted together with a special `mov
-  // x29, x29` marker instruction.
-  CALL_RVMARKER,
-
-  CALL_BTI, // Function call followed by a BTI instruction.
-
-  // Function call, authenticating the callee value first:
-  // AUTH_CALL chain, callee, auth key #, int disc, addr disc, operands.
-  AUTH_CALL,
-  // AUTH_TC_RETURN chain, callee, fpdiff, auth key #, int disc, addr disc,
-  // operands.
-  AUTH_TC_RETURN,
-
-  // Authenticated variant of CALL_RVMARKER.
-  AUTH_CALL_RVMARKER,
-
-  COALESCER_BARRIER,
-
-  VG_SAVE,
-  VG_RESTORE,
-
-  SMSTART,
-  SMSTOP,
-  RESTORE_ZA,
-  RESTORE_ZT,
-  SAVE_ZT,
-
-  // A call with the callee in x16, i.e. "blr x16".
-  CALL_ARM64EC_TO_X64,
-
-  // Produces the full sequence of instructions for getting the thread pointer
-  // offset of a variable into X0, using the TLSDesc model.
-  TLSDESC_CALLSEQ,
-  ADRP,     // Page address of a TargetGlobalAddress operand.
-  ADR,      // ADR
-  ADDlow,   // Add the low 12 bits of a TargetGlobalAddress operand.
-  LOADgot,  // Load from automatically generated descriptor (e.g. Global
-            // Offset Table, TLS record).
-  RET_GLUE, // Return with a glue operand. Operand 0 is the chain operand.
-  BRCOND,   // Conditional branch instruction; "b.cond".
-  CSEL,
-  CSINV, // Conditional select invert.
-  CSNEG, // Conditional select negate.
-  CSINC, // Conditional select increment.
-
-  // Pointer to the thread's local storage area. Materialised from TPIDR_EL0 on
-  // ELF.
-  THREAD_POINTER,
-  ADC,
-  SBC, // adc, sbc instructions
-
-  // To avoid stack clash, allocation is performed by block and each block is
-  // probed.
-  PROBED_ALLOCA,
-
-  // Predicated instructions where inactive lanes produce undefined results.
-  ABDS_PRED,
-  ABDU_PRED,
-  FADD_PRED,
-  FDIV_PRED,
-  FMA_PRED,
-  FMAX_PRED,
-  FMAXNM_PRED,
-  FMIN_PRED,
-  FMINNM_PRED,
-  FMUL_PRED,
-  FSUB_PRED,
-  HADDS_PRED,
-  HADDU_PRED,
-  MUL_PRED,
-  MULHS_PRED,
-  MULHU_PRED,
-  RHADDS_PRED,
-  RHADDU_PRED,
-  SDIV_PRED,
-  SHL_PRED,
-  SMAX_PRED,
-  SMIN_PRED,
-  SRA_PRED,
-  SRL_PRED,
-  UDIV_PRED,
-  UMAX_PRED,
-  UMIN_PRED,
-
-  // Unpredicated vector instructions
-  BIC,
-
-  SRAD_MERGE_OP1,
-
-  // Predicated instructions with the result of inactive lanes provided by the
-  // last operand.
-  FABS_MERGE_PASSTHRU,
-  FCEIL_MERGE_PASSTHRU,
-  FFLOOR_MERGE_PASSTHRU,
-  FNEARBYINT_MERGE_PASSTHRU,
-  FNEG_MERGE_PASSTHRU,
-  FRECPX_MERGE_PASSTHRU,
-  FRINT_MERGE_PASSTHRU,
-  FROUND_MERGE_PASSTHRU,
-  FROUNDEVEN_MERGE_PASSTHRU,
-  FSQRT_MERGE_PASSTHRU,
-  FTRUNC_MERGE_PASSTHRU,
-  FP_ROUND_MERGE_PASSTHRU,
-  FP_EXTEND_MERGE_PASSTHRU,
-  UINT_TO_FP_MERGE_PASSTHRU,
-  SINT_TO_FP_MERGE_PASSTHRU,
-  FCVTX_MERGE_PASSTHRU,
-  FCVTZU_MERGE_PASSTHRU,
-  FCVTZS_MERGE_PASSTHRU,
-  SIGN_EXTEND_INREG_MERGE_PASSTHRU,
-  ZERO_EXTEND_INREG_MERGE_PASSTHRU,
-  ABS_MERGE_PASSTHRU,
-  NEG_MERGE_PASSTHRU,
-
-  SETCC_MERGE_ZERO,
-
-  // Arithmetic instructions which write flags.
-  ADDS,
-  SUBS,
-  ADCS,
-  SBCS,
-  ANDS,
-
-  // Conditional compares. Operands: left,right,falsecc,cc,flags
-  CCMP,
-  CCMN,
-  FCCMP,
-
-  // Floating point comparison
-  FCMP,
-
-  // Scalar-to-vector duplication
-  DUP,
-  DUPLANE8,
-  DUPLANE16,
-  DUPLANE32,
-  DUPLANE64,
-  DUPLANE128,
-
-  // Vector immedate moves
-  MOVI,
-  MOVIshift,
-  MOVIedit,
-  MOVImsl,
-  FMOV,
-  MVNIshift,
-  MVNImsl,
-
-  // Vector immediate ops
-  BICi,
-  ORRi,
-
-  // Vector bitwise select: similar to ISD::VSELECT but not all bits within an
-  // element must be identical.
-  BSP,
-
-  // Vector shuffles
-  ZIP1,
-  ZIP2,
-  UZP1,
-  UZP2,
-  TRN1,
-  TRN2,
-  REV16,
-  REV32,
-  REV64,
-  EXT,
-  SPLICE,
-
-  // Vector shift by scalar
-  VSHL,
-  VLSHR,
-  VASHR,
-
-  // Vector shift by scalar (again)
-  SQSHL_I,
-  UQSHL_I,
-  SQSHLU_I,
-  SRSHR_I,
-  URSHR_I,
-  URSHR_I_PRED,
-
-  // Vector narrowing shift by immediate (bottom)
-  RSHRNB_I,
-
-  // Vector shift by constant and insert
-  VSLI,
-  VSRI,
-
-  // Vector comparisons
-  CMEQ,
-  CMGE,
-  CMGT,
-  CMHI,
-  CMHS,
-  FCMEQ,
-  FCMGE,
-  FCMGT,
-
-  // Vector zero comparisons
-  CMEQz,
-  CMGEz,
-  CMGTz,
-  CMLEz,
-  CMLTz,
-  FCMEQz,
-  FCMGEz,
-  FCMGTz,
-  FCMLEz,
-  FCMLTz,
-
-  // Round wide FP to narrow FP with inexact results to odd.
-  FCVTXN,
-
-  // Vector across-lanes addition
-  // Only the lower result lane is defined.
-  SADDV,
-  UADDV,
-
-  // Unsigned sum Long across Vector
-  UADDLV,
-  SADDLV,
-
-  // Wide adds
-  SADDWT,
-  SADDWB,
-  UADDWT,
-  UADDWB,
-
-  // Add Pairwise of two vectors
-  ADDP,
-  // Add Long Pairwise
-  SADDLP,
-  UADDLP,
-
-  // udot/sdot/usdot instructions
-  UDOT,
-  SDOT,
-  USDOT,
-
-  // Vector across-lanes min/max
-  // Only the lower result lane is defined.
-  SMINV,
-  UMINV,
-  SMAXV,
-  UMAXV,
-
-  SADDV_PRED,
-  UADDV_PRED,
-  SMAXV_PRED,
-  UMAXV_PRED,
-  SMINV_PRED,
-  UMINV_PRED,
-  ORV_PRED,
-  EORV_PRED,
-  ANDV_PRED,
-
-  // Compare-and-branch
-  CBZ,
-  CBNZ,
-  TBZ,
-  TBNZ,
-
-  // Tail calls
-  TC_RETURN,
-
-  // Custom prefetch handling
-  PREFETCH,
-
-  // {s|u}int to FP within a FP register.
-  SITOF,
-  UITOF,
-
-  /// Natural vector cast. ISD::BITCAST is not natural in the big-endian
-  /// world w.r.t vectors; which causes additional REV instructions to be
-  /// generated to compensate for the byte-swapping. But sometimes we do
-  /// need to re-interpret the data in SIMD vector registers in big-endian
-  /// mode without emitting such REV instructions.
-  NVCAST,
-
-  MRS, // MRS, also sets the flags via a glue.
-
-  SMULL,
-  UMULL,
-
-  PMULL,
-
-  // Reciprocal estimates and steps.
-  FRECPE,
-  FRECPS,
-  FRSQRTE,
-  FRSQRTS,
-
-  SUNPKHI,
-  SUNPKLO,
-  UUNPKHI,
-  UUNPKLO,
-
-  CLASTA_N,
-  CLASTB_N,
-  LASTA,
-  LASTB,
-  TBL,
-
-  // Floating-point reductions.
-  FADDA_PRED,
-  FADDV_PRED,
-  FMAXV_PRED,
-  FMAXNMV_PRED,
-  FMINV_PRED,
-  FMINNMV_PRED,
-
-  INSR,
-  PTEST,
-  PTEST_ANY,
-  PTRUE,
-
-  CTTZ_ELTS,
-
-  BITREVERSE_MERGE_PASSTHRU,
-  BSWAP_MERGE_PASSTHRU,
-  REVH_MERGE_PASSTHRU,
-  REVW_MERGE_PASSTHRU,
-  CTLZ_MERGE_PASSTHRU,
-  CTPOP_MERGE_PASSTHRU,
-  DUP_MERGE_PASSTHRU,
-  INDEX_VECTOR,
-
-  // Cast between vectors of the same element type but differ in length.
-  REINTERPRET_CAST,
-
-  // Nodes to build an LD64B / ST64B 64-bit quantity out of i64, and vice versa
-  LS64_BUILD,
-  LS64_EXTRACT,
-
-  LD1_MERGE_ZERO,
-  LD1S_MERGE_ZERO,
-  LDNF1_MERGE_ZERO,
-  LDNF1S_MERGE_ZERO,
-  LDFF1_MERGE_ZERO,
-  LDFF1S_MERGE_ZERO,
-  LD1RQ_MERGE_ZERO,
-  LD1RO_MERGE_ZERO,
-
-  // Structured loads.
-  SVE_LD2_MERGE_ZERO,
-  SVE_LD3_MERGE_ZERO,
-  SVE_LD4_MERGE_ZERO,
-
-  // Unsigned gather loads.
-  GLD1_MERGE_ZERO,
-  GLD1_SCALED_MERGE_ZERO,
-  GLD1_UXTW_MERGE_ZERO,
-  GLD1_SXTW_MERGE_ZERO,
-  GLD1_UXTW_SCALED_MERGE_ZERO,
-  GLD1_SXTW_SCALED_MERGE_ZERO,
-  GLD1_IMM_MERGE_ZERO,
-  GLD1Q_MERGE_ZERO,
-  GLD1Q_INDEX_MERGE_ZERO,
-
-  // Signed gather loads
-  GLD1S_MERGE_ZERO,
-  GLD1S_SCALED_MERGE_ZERO,
-  GLD1S_UXTW_MERGE_ZERO,
-  GLD1S_SXTW_MERGE_ZERO,
-  GLD1S_UXTW_SCALED_MERGE_ZERO,
-  GLD1S_SXTW_SCALED_MERGE_ZERO,
-  GLD1S_IMM_MERGE_ZERO,
-
-  // Unsigned gather loads.
-  GLDFF1_MERGE_ZERO,
-  GLDFF1_SCALED_MERGE_ZERO,
-  GLDFF1_UXTW_MERGE_ZERO,
-  GLDFF1_SXTW_MERGE_ZERO,
-  GLDFF1_UXTW_SCALED_MERGE_ZERO,
-  GLDFF1_SXTW_SCALED_MERGE_ZERO,
-  GLDFF1_IMM_MERGE_ZERO,
-
-  // Signed gather loads.
-  GLDFF1S_MERGE_ZERO,
-  GLDFF1S_SCALED_MERGE_ZERO,
-  GLDFF1S_UXTW_MERGE_ZERO,
-  GLDFF1S_SXTW_MERGE_ZERO,
-  GLDFF1S_UXTW_SCALED_MERGE_ZERO,
-  GLDFF1S_SXTW_SCALED_MERGE_ZERO,
-  GLDFF1S_IMM_MERGE_ZERO,
-
-  // Non-temporal gather loads
-  GLDNT1_MERGE_ZERO,
-  GLDNT1_INDEX_MERGE_ZERO,
-  GLDNT1S_MERGE_ZERO,
-
-  // Contiguous masked store.
-  ST1_PRED,
-
-  // Scatter store
-  SST1_PRED,
-  SST1_SCALED_PRED,
-  SST1_UXTW_PRED,
-  SST1_SXTW_PRED,
-  SST1_UXTW_SCALED_PRED,
-  SST1_SXTW_SCALED_PRED,
-  SST1_IMM_PRED,
-  SST1Q_PRED,
-  SST1Q_INDEX_PRED,
-
-  // Non-temporal scatter store
-  SSTNT1_PRED,
-  SSTNT1_INDEX_PRED,
-
-  // SME
-  RDSVL,
-  REVD_MERGE_PASSTHRU,
-  ALLOCATE_ZA_BUFFER,
-  INIT_TPIDR2OBJ,
-
-  // Asserts that a function argument (i32) is zero-extended to i8 by
-  // the caller
-  ASSERT_ZEXT_BOOL,
-
-  // 128-bit system register accesses
-  // lo64, hi64, chain = MRRS(chain, sysregname)
-  MRRS,
-  // chain = MSRR(chain, sysregname, lo64, hi64)
-  MSRR,
-
-  // Strict (exception-raising) floating point comparison
-  STRICT_FCMP,
-  STRICT_FCMPE,
-
-  // SME ZA loads and stores
-  SME_ZA_LDR,
-  SME_ZA_STR,
-
-  // NEON Load/Store with post-increment base updates
-  FIRST_MEMORY_OPCODE,
-  LD2post = FIRST_MEMORY_OPCODE,
-  LD3post,
-  LD4post,
-  ST2post,
-  ST3post,
-  ST4post,
-  LD1x2post,
-  LD1x3post,
-  LD1x4post,
-  ST1x2post,
-  ST1x3post,
-  ST1x4post,
-  LD1DUPpost,
-  LD2DUPpost,
-  LD3DUPpost,
-  LD4DUPpost,
-  LD1LANEpost,
-  LD2LANEpost,
-  LD3LANEpost,
-  LD4LANEpost,
-  ST2LANEpost,
-  ST3LANEpost,
-  ST4LANEpost,
-
-  STG,
-  STZG,
-  ST2G,
-  STZ2G,
-
-  LDP,
-  LDIAPP,
-  LDNP,
-  STP,
-  STILP,
-  STNP,
-  LAST_MEMORY_OPCODE = STNP,
-};
-
-} // end namespace AArch64ISD
-
 namespace AArch64 {
 /// Possible values of current rounding mode, which is specified in bits
 /// 23:22 of FPCR.
@@ -615,8 +112,6 @@ class AArch64TargetLowering : public TargetLowering {
   /// Provide custom lowering hooks for some operations.
   SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
 
-  const char *getTargetNodeName(unsigned Opcode) const override;
-
   SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
 
   /// This method returns a target specific FastISel object, or null if the
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index d015cc15581ad0..fc79d5b3f5251c 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -778,10 +778,14 @@ def AArch64fccmp     : SDNode<"AArch64ISD::FCCMP", SDT_AArch64FCCMP>;
 def AArch64threadpointer : SDNode<"AArch64ISD::THREAD_POINTER", SDTPtrLeaf>;
 
 def AArch64fcmp         : SDNode<"AArch64ISD::FCMP", SDT_AArch64FCmp>;
-def AArch64strict_fcmp  : SDNode<"AArch64ISD::STRICT_FCMP", SDT_AArch64FCmp,
-                                 [SDNPHasChain]>;
-def AArch64strict_fcmpe : SDNode<"AArch64ISD::STRICT_FCMPE", SDT_AArch64FCmp,
-                                 [SDNPHasChain]>;
+
+let IsStrictFP = true in {
+  def AArch64strict_fcmp  : SDNode<"AArch64ISD::STRICT_FCMP", SDT_AArch64FCmp,
+                                   [SDNPHasChain]>;
+  def AArch64strict_fcmpe : SDNode<"AArch64ISD::STRICT_FCMPE", SDT_AArch64FCmp,
+                                   [SDNPHasChain]>;
+}
+
 def AArch64any_fcmp     : PatFrags<(ops node:$lhs, node:$rhs),
                                    [(AArch64strict_fcmp node:$lhs, node:$rhs),
                                     (AArch64fcmp node:$lhs, node:$rhs)]>;
diff --git a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
index f06c15ccb50755..8f138206ecd7ba 100644
--- a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
@@ -10,9 +10,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "AArch64SelectionDAGInfo.h"
 #include "AArch64TargetMachine.h"
 #include "Utils/AArch64SMEAttributes.h"
 
+#define GET_SDNODE_DESC
+#include "AArch64GenSDNodeInfo.inc"
+
 using namespace llvm;
 
 #define DEBUG_TYPE "aarch64-selectiondag-info"
@@ -23,24 +27,124 @@ static cl::opt<bool>
                                 "to lower to librt functions"),
                        cl::init(true));
 
-bool AArch64SelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
-  if (Opcode >= AArch64ISD::FIRST_MEMORY_OPCODE &&
-      Opcode <= AArch64ISD::LAST_MEMORY_OPCODE)
-    return true;
-  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+AArch64SelectionDAGInfo::AArch64SelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(AArch64GenSDNodeInfo) {}
+
+const char *AArch64SelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
+#define MAKE_CASE(V)                                                           \
+  case V:                                                                      \
+    return #V;
+
+  // These nodes don't have corresponding entries in *.td files yet.
+  switch (static_cast<AArch64ISD::NodeType>(Opcode)) {
+    MAKE_CASE(AArch64ISD::LD2post)
+    MAKE_CASE(AArch64ISD::LD3post)
+    MAKE_CASE(AArch64ISD::LD4post)
+    MAKE_CASE(AArch64ISD::ST2post)
+    MAKE_CASE(AArch64ISD::ST3post)
+    MAKE_CASE(AArch64ISD::ST4post)
+    MAKE_CASE(AArch64ISD::LD1x2post)
+    MAKE_CASE(AArch64ISD::LD1x3post)
+    MAKE_CASE(AArch64ISD::LD1x4post)
+    MAKE_CASE(AArch64ISD::ST1x2post)
+    MAKE_CASE(AArch64ISD::ST1x3post)
+    MAKE_CASE(AArch64ISD::ST1x4post)
+    MAKE_CASE(AArch64ISD::LD1DUPpost)
+    MAKE_CASE(AArch64ISD::LD2DUPpost)
+    MAKE_CASE(AArch64ISD::LD3DUPpost)
+    MAKE_CASE(AArch64ISD::LD4DUPpost)
+    MAKE_CASE(AArch64ISD::LD1LANEpost)
+    MAKE_CASE(AArch64ISD::LD2LANEpost)
+    MAKE_CASE(AArch64ISD::LD3LANEpost)
+    MAKE_CASE(AArch64ISD::LD4LANEpost)
+    MAKE_CASE(AArch64ISD::ST2LANEpost)
+    MAKE_CASE(AArch64ISD::ST3LANEpost)
+    MAKE_CASE(AArch64ISD::ST4LANEpost)
+    MAKE_CASE(AArch64ISD::SVE_LD2_MERGE_ZERO)
+    MAKE_CASE(AArch64ISD::SVE_LD3_MERGE_ZERO)
+    MAKE_CASE(AArch64ISD::SVE_LD4_MERGE_ZERO)
+    MAKE_CASE(AArch64ISD::GLD1Q_INDEX_MERGE_ZERO)
+    MAKE_CASE(AArch64ISD::GLDNT1_INDEX_MERGE_ZERO)
+    MAKE_CASE(AArch64ISD::SST1Q_INDEX_PRED)
+    MAKE_CASE(AArch64ISD::SSTNT1_INDEX_PRED)
+    MAKE_CASE(AArch64ISD::INDEX_VECTOR)
+    MAKE_CASE(AArch64ISD::MRRS)
+    MAKE_CASE(AArch64ISD::MSRR)
+  }
+#undef MAKE_CASE
+
+  return SelectionDAGGenTargetInfo::getTargetNodeName(Opcode);
 }
 
-bool AArch64SelectionDAGInfo::isTargetStrictFPOpcode(unsigned Opcode) const {
+bool AArch64SelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
+  // These nodes don't have corresponding entries in *.td files yet.
   switch (static_cast<AArch64ISD::NodeType>(Opcode)) {
   default:
     break;
-  case AArch64ISD::STRICT_FCMP:
-  case AArch64ISD::STRICT_FCMPE:
-  case AArch64ISD::SME_ZA_LDR:
-  case AArch64ISD::SME_ZA_STR:
+  case AArch64ISD::LD2post:
+  case AArch64ISD::LD3post:
+  case AArch64ISD::LD4post:
+  case AArch64ISD::ST2post:
+  case AArch64ISD::ST3post:
+  case AArch64ISD::ST4post:
+  case AArch64ISD::LD1x2post:
+  case AArch64ISD::LD1x3post:
+  case AArch64ISD::LD1x4post:
+  case AArch64ISD::ST1x2post:
+  case AArch64ISD::ST1x3post:
+  case AArch64ISD::ST1x4post:
+  case AArch64ISD::LD1DUPpost:
+  case AArch64ISD::LD2DUPpost:
+  case AArch64ISD::LD3DUPpost:
+  case AArch64ISD::LD4DUPpost:
+  case AArch64ISD::LD1LANEpost:
+  case AArch64ISD::LD2LANEpost:
+  case AArch64ISD::LD3LANEpost:
+  case AArch64ISD::LD4LANEpost:
+  case AArch64ISD::ST2LANEpost:
+  case AArch64ISD::ST3LANEpost:
+  case AArch64ISD::ST4LANEpost:
     return true;
   }
-  return SelectionDAGTargetInfo::isTargetStrictFPOpcode(Opcode);
+
+  return SelectionDAGGenTargetInfo::isTargetMemoryOpcode(Opcode);
+}
+
+void AArch64SelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
+                                               const SDNode *N) const {
+  switch (N->getOpcode()) {
+  default:
+    break;
+  case AArch64ISD::GLDFF1S_IMM_MERGE_ZERO:
+  case AArch64ISD::GLDFF1S_MERGE_ZERO:
+  case AArch64ISD::GLDFF1S_SCALED_MERGE_ZERO:
+  case AArch64ISD::GLDFF1S_SXTW_MERGE_ZERO:
+  case AArch64ISD::GLDFF1S_SXTW_SCALED_MERGE_ZERO:
+  case AArch64ISD::GLDFF1S_UXTW_MERGE_ZERO:
+  case AArch64ISD::GLDFF1S_UXTW_SCALED_MERGE_ZERO:
+  case AArch64ISD::GLDFF1_IMM_MERGE_ZERO:
+  case AArch64ISD::GLDFF1_MERGE_ZERO:
+  case AArch64ISD::GLDFF1_SCALED_MERGE_ZERO:
+  case AArch64ISD::GLDFF1_SXTW_MERGE_ZERO:
+  case AArch64ISD::GLDFF1_SXTW_SCALED_MERGE_ZERO:
+  case AArch64ISD::GLDFF1_UXTW_MERGE_ZERO:
+  case AArch64ISD::GLDFF1_UXTW_SCALED_MERGE_ZERO:
+  case AArch64ISD::LDFF1S_MERGE_ZERO:
+  case AArch64ISD::LDFF1_MERGE_ZERO:
+  case AArch64ISD::LDNF1S_MERGE_ZERO:
+  case AArch64ISD::LDNF1_MERGE_ZERO:
+    // invalid number of results; expected 3, got 2
+  case AArch64ISD::SMSTOP:
+  case AArch64ISD::COALESCER_BARRIER:
+    // invalid number of results; expected 2, got 1
+  case AArch64ISD::SMSTART:
+    // variadic operand #3 must be Register or RegisterMask
+  case AArch64ISD::REVD_MERGE_PASSTHRU:
+    // invalid number of operands; expected 3, got 4
+    return;
+  }
+
+  SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
 }
 
 SDValue AArch64SelectionDAGInfo::EmitMOPS(unsigned Opcode, SelectionDAG &DAG,
@@ -230,8 +334,7 @@ static SDValue EmitUnrolledSetTag(SelectionDAG &DAG, const SDLoc &dl,
       SDValue AddrNode = DAG.getMemBasePlusOffset(
           Ptr, TypeSize::getFixed(OffsetScaled * 16), dl);
       SDValue St = DAG.getMemIntrinsicNode(
-          OpCode2, dl, DAG.getVTList(MVT::Other),
-          {Chain, TagSrc, AddrNode},
+          OpCode2, dl, DAG.getVTList(MVT::Other), {Chain, TagSrc, AddrNode},
           MVT::v4i64,
           MF.getMachineMemOperand(BaseMemOperand, OffsetScaled * 16, 16 * 2));
       OffsetScaled += 2;
@@ -243,8 +346,7 @@ static SDValue EmitUnrolledSetTag(SelectionDAG &DAG, const SDLoc &dl,
       SDValue AddrNode = DAG.getMemBasePlusOffset(
           Ptr, TypeSize::getFixed(OffsetScaled * 16), dl);
       SDValue St = DAG.getMemIntrinsicNode(
-          OpCode1, dl, DAG.getVTList(MVT::Other),
-          {Chain, TagSrc, AddrNode},
+          OpCode1, dl, DAG.getVTList(MVT::Other), {Chain, TagSrc, AddrNode},
           MVT::v2i64,
           MF.getMachineMemOperand(BaseMemOperand, OffsetScaled * 16, 16));
       OffsetScaled += 1;
diff --git a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.h b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.h
index 7efe49c7206555..746385613ac76d 100644
--- a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.h
@@ -14,14 +14,98 @@
 #define LLVM_LIB_TARGET_AARCH64_AARCH64SELECTIONDAGINFO_H
 
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+#include "llvm/IR/RuntimeLibcalls.h"
+
+#define GET_SDNODE_ENUM
+#include "AArch64GenSDNodeInfo.inc"
 
 namespace llvm {
+namespace AArch64ISD {
+
+// For predicated nodes where the result is a vector, the operation is
+// controlled by a governing predicate and the inactive lanes are explicitly
+// defined with a value, please stick the following naming convention:
+//
+//    _MERGE_OP<n>        The result value is a vector with inactive lanes equal
+//                        to source operand OP<n>.
+//
+//    _MERGE_ZERO         The result value is a vector with inactive lanes
+//                        actively zeroed.
+//
+//    _MERGE_PASSTHRU     The result value is a vector with inactive lanes equal
+//                        to the last source operand which only purpose is being
+//                        a passthru value.
+//
+// For other cases where no explicit action is needed to set the inactive lanes,
+// or when the result is not a vector and it is needed or helpful to
+// distinguish a node from similar unpredicated nodes, use:
+//
+//    _PRED
+//
+enum NodeType : unsigned {
+  INDEX_VECTOR = GENERATED_OPCODE_END,
+
+  // Structured loads.
+  SVE_LD2_MERGE_ZERO,
+  SVE_LD3_MERGE_ZERO,
+  SVE_LD4_MERGE_ZERO,
+
+  // Unsigned gather loads.
+  GLD1Q_INDEX_MERGE_ZERO,
 
-class AArch64SelectionDAGInfo : public SelectionDAGTargetInfo {
+  // Non-temporal gather loads
+  GLDNT1_INDEX_MERGE_ZERO,
+
+  // Scatter store
+  SST1Q_INDEX_PRED,
+
+  // Non-temporal scatter store
+  SSTNT1_INDEX_PRED,
+
+  // 128-bit system register accesses
+  // lo64, hi64, chain = MRRS(chain, sysregname)
+  MRRS,
+  // chain = MSRR(chain, sysregname, lo64, hi64)
+  MSRR,
+
+  // NEON Load/Store with post-increment base updates
+  LD2post,
+  LD3post,
+  LD4post,
+  ST2post,
+  ST3post,
+  ST4post,
+  LD1x2post,
+  LD1x3post,
+  LD1x4post,
+  ST1x2post,
+  ST1x3post,
+  ST1x4post,
+  LD1DUPpost,
+  LD2DUPpost,
+  LD3DUPpost,
+  LD4DUPpost,
+  LD1LANEpost,
+  LD2LANEpost,
+  LD3LANEpost,
+  LD4LANEpost,
+  ST2LANEpost,
+  ST3LANEpost,
+  ST4LANEpost,
+};
+
+} // namespace AArch64ISD
+
+class AArch64SelectionDAGInfo : public SelectionDAGGenTargetInfo {
 public:
+  AArch64SelectionDAGInfo();
+
+  const char *getTargetNodeName(unsigned Opcode) const override;
+
   bool isTargetMemoryOpcode(unsigned Opcode) const override;
 
-  bool isTargetStrictFPOpcode(unsigned Opcode) const override;
+  void verifyTargetNode(const SelectionDAG &DAG,
+                        const SDNode *N) const override;
 
   SDValue EmitMOPS(unsigned Opcode, SelectionDAG &DAG, const SDLoc &DL,
                    SDValue Chain, SDValue Dst, SDValue SrcOrValue, SDValue Size,
diff --git a/llvm/lib/Target/AArch64/CMakeLists.txt b/llvm/lib/Target/AArch64/CMakeLists.txt
index da13db8e68b0e6..d95ff27e458ac1 100644
--- a/llvm/lib/Target/AArch64/CMakeLists.txt
+++ b/llvm/lib/Target/AArch64/CMakeLists.txt
@@ -23,6 +23,7 @@ tablegen(LLVM AArch64GenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM AArch64GenMCPseudoLowering.inc -gen-pseudo-lowering)
 tablegen(LLVM AArch64GenRegisterBank.inc -gen-register-bank)
 tablegen(LLVM AArch64GenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM AArch64GenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM AArch64GenSubtargetInfo.inc -gen-subtarget)
 tablegen(LLVM AArch64GenSystemOperands.inc -gen-searchable-tables)
 tablegen(LLVM AArch64GenExegesis.inc -gen-exegesis)
diff --git a/llvm/lib/Target/AArch64/SMEInstrFormats.td b/llvm/lib/Target/AArch64/SMEInstrFormats.td
index 9f25749c83db83..97653be20f8f0e 100644
--- a/llvm/lib/Target/AArch64/SMEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SMEInstrFormats.td
@@ -60,10 +60,13 @@ def FORM_TRANSPOSED_REG_TUPLE_X4_PSEUDO :
 }
 
 def SDTZALoadStore : SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisPtrTy<1>, SDTCisInt<2>]>;
-def AArch64SMELdr : SDNode<"AArch64ISD::SME_ZA_LDR", SDTZALoadStore,
+
+let IsStrictFP = true in {
+  def AArch64SMELdr : SDNode<"AArch64ISD::SME_ZA_LDR", SDTZALoadStore,
                              [SDNPHasChain, SDNPSideEffect, SDNPMayLoad]>;
-def AArch64SMEStr : SDNode<"AArch64ISD::SME_ZA_STR", SDTZALoadStore,
+  def AArch64SMEStr : SDNode<"AArch64ISD::SME_ZA_STR", SDTZALoadStore,
                              [SDNPHasChain, SDNPSideEffect, SDNPMayStore]>;
+}
 
 //===----------------------------------------------------------------------===//
 // SME Pseudo Classes
diff --git a/llvm/unittests/CodeGen/CMakeLists.txt b/llvm/unittests/CodeGen/CMakeLists.txt
index 963cdcc0275e16..b14a4943c486c7 100644
--- a/llvm/unittests/CodeGen/CMakeLists.txt
+++ b/llvm/unittests/CodeGen/CMakeLists.txt
@@ -20,7 +20,6 @@ set(LLVM_LINK_COMPONENTS
   )
 
 add_llvm_unittest(CodeGenTests
-  AArch64SelectionDAGTest.cpp
   AllocationOrderTest.cpp
   AMDGPUMetadataTest.cpp
   AsmPrinterDwarfTest.cpp
diff --git a/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp b/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp
similarity index 98%
rename from llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp
rename to llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp
index b00e8dc4424ab5..9b35a8fa8c1628 100644
--- a/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp
+++ b/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "../lib/Target/AArch64/AArch64ISelLowering.h"
+#include "AArch64SelectionDAGInfo.h"
 #include "llvm/Analysis/MemoryLocation.h"
 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
 #include "llvm/AsmParser/Parser.h"
@@ -27,8 +27,9 @@ namespace llvm {
 class AArch64SelectionDAGTest : public testing::Test {
 protected:
   static void SetUpTestCase() {
-    InitializeAllTargets();
-    InitializeAllTargetMCs();
+    LLVMInitializeAArch64TargetInfo();
+    LLVMInitializeAArch64Target();
+    LLVMInitializeAArch64TargetMC();
   }
 
   void SetUp() override {
@@ -37,18 +38,11 @@ class AArch64SelectionDAGTest : public testing::Test {
     Triple TargetTriple("aarch64--");
     std::string Error;
     const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
-    // FIXME: These tests do not depend on AArch64 specifically, but we have to
-    // initialize a target. A skeleton Target for unittests would allow us to
-    // always run these tests.
-    if (!T)
-      GTEST_SKIP();
 
     TargetOptions Options;
     TM = std::unique_ptr<TargetMachine>(
         T->createTargetMachine("AArch64", "", "+sve", Options, std::nullopt,
                                std::nullopt, CodeGenOptLevel::Aggressive));
-    if (!TM)
-      GTEST_SKIP();
 
     SMDiagnostic SMError;
     M = parseAssemblyString(Assembly, SMError, Context);
diff --git a/llvm/unittests/Target/AArch64/CMakeLists.txt b/llvm/unittests/Target/AArch64/CMakeLists.txt
index 449888838acdc6..67eb508e9bab8d 100644
--- a/llvm/unittests/Target/AArch64/CMakeLists.txt
+++ b/llvm/unittests/Target/AArch64/CMakeLists.txt
@@ -8,6 +8,7 @@ set(LLVM_LINK_COMPONENTS
   AArch64Desc
   AArch64Info
   AArch64Utils
+  Analysis
   AsmParser
   CodeGen
   CodeGenTypes
@@ -30,5 +31,6 @@ add_llvm_target_unittest(AArch64Tests
   SMEAttributesTest.cpp
   AArch64RegisterInfoTest.cpp
   AArch64SVESchedPseudoTest.cpp
+  AArch64SelectionDAGTest.cpp
   Immediates.cpp
   )

>From 1944bda524b6147858635657e9e29616ec9a4bdd Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 01:00:46 +0300
Subject: [PATCH 05/27] AMDGPU

---
 llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h   |   1 +
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 159 +------------
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h   | 222 ------------------
 .../Target/AMDGPU/AMDGPUSelectionDAGInfo.cpp  |  48 +++-
 .../Target/AMDGPU/AMDGPUSelectionDAGInfo.h    |  40 +++-
 llvm/lib/Target/AMDGPU/CMakeLists.txt         |   2 +
 llvm/lib/Target/AMDGPU/R600ISelLowering.cpp   |   1 +
 llvm/lib/Target/AMDGPU/SIISelLowering.cpp     |   1 +
 .../llvm.amdgcn.ds.ordered.add.gfx11.ll       |   2 +-
 ...mdgcn.ptr.buffer.atomic.fadd_rtn_errors.ll |  12 +-
 .../CodeGen/AMDGPU/sdag-print-divergence.ll   |   4 +-
 11 files changed, 95 insertions(+), 397 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h
index 7e61eb470622f1..9261814d932f02 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUISELDAGTODAG_H
 #define LLVM_LIB_TARGET_AMDGPU_AMDGPUISELDAGTODAG_H
 
+#include "AMDGPUSelectionDAGInfo.h"
 #include "GCNSubtarget.h"
 #include "SIMachineFunctionInfo.h"
 #include "SIModeRegisterDefaults.h"
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index f76acfe12e2953..0e0813ad964ff0 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -17,6 +17,7 @@
 #include "AMDGPUInstrInfo.h"
 #include "AMDGPUMachineFunction.h"
 #include "AMDGPUMemoryUtils.h"
+#include "AMDGPUSelectionDAGInfo.h"
 #include "SIMachineFunctionInfo.h"
 #include "llvm/CodeGen/Analysis.h"
 #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
@@ -5456,164 +5457,6 @@ uint32_t AMDGPUTargetLowering::getImplicitParameterOffset(
   return getImplicitParameterOffset(MFI->getExplicitKernArgSize(), Param);
 }
 
-#define NODE_NAME_CASE(node) case AMDGPUISD::node: return #node;
-
-const char* AMDGPUTargetLowering::getTargetNodeName(unsigned Opcode) const {
-  switch ((AMDGPUISD::NodeType)Opcode) {
-  case AMDGPUISD::FIRST_NUMBER: break;
-  // AMDIL DAG nodes
-  NODE_NAME_CASE(BRANCH_COND);
-
-  // AMDGPU DAG nodes
-  NODE_NAME_CASE(IF)
-  NODE_NAME_CASE(ELSE)
-  NODE_NAME_CASE(LOOP)
-  NODE_NAME_CASE(CALL)
-  NODE_NAME_CASE(TC_RETURN)
-  NODE_NAME_CASE(TC_RETURN_GFX)
-  NODE_NAME_CASE(TC_RETURN_CHAIN)
-  NODE_NAME_CASE(TRAP)
-  NODE_NAME_CASE(RET_GLUE)
-  NODE_NAME_CASE(WAVE_ADDRESS)
-  NODE_NAME_CASE(RETURN_TO_EPILOG)
-  NODE_NAME_CASE(ENDPGM)
-  NODE_NAME_CASE(ENDPGM_TRAP)
-  NODE_NAME_CASE(SIMULATED_TRAP)
-  NODE_NAME_CASE(DWORDADDR)
-  NODE_NAME_CASE(FRACT)
-  NODE_NAME_CASE(SETCC)
-  NODE_NAME_CASE(DENORM_MODE)
-  NODE_NAME_CASE(FMA_W_CHAIN)
-  NODE_NAME_CASE(FMUL_W_CHAIN)
-  NODE_NAME_CASE(CLAMP)
-  NODE_NAME_CASE(COS_HW)
-  NODE_NAME_CASE(SIN_HW)
-  NODE_NAME_CASE(FMAX_LEGACY)
-  NODE_NAME_CASE(FMIN_LEGACY)
-  NODE_NAME_CASE(FMAX3)
-  NODE_NAME_CASE(SMAX3)
-  NODE_NAME_CASE(UMAX3)
-  NODE_NAME_CASE(FMIN3)
-  NODE_NAME_CASE(SMIN3)
-  NODE_NAME_CASE(UMIN3)
-  NODE_NAME_CASE(FMED3)
-  NODE_NAME_CASE(SMED3)
-  NODE_NAME_CASE(UMED3)
-  NODE_NAME_CASE(FMAXIMUM3)
-  NODE_NAME_CASE(FMINIMUM3)
-  NODE_NAME_CASE(FDOT2)
-  NODE_NAME_CASE(URECIP)
-  NODE_NAME_CASE(DIV_SCALE)
-  NODE_NAME_CASE(DIV_FMAS)
-  NODE_NAME_CASE(DIV_FIXUP)
-  NODE_NAME_CASE(FMAD_FTZ)
-  NODE_NAME_CASE(RCP)
-  NODE_NAME_CASE(RSQ)
-  NODE_NAME_CASE(RCP_LEGACY)
-  NODE_NAME_CASE(RCP_IFLAG)
-  NODE_NAME_CASE(LOG)
-  NODE_NAME_CASE(EXP)
-  NODE_NAME_CASE(FMUL_LEGACY)
-  NODE_NAME_CASE(RSQ_CLAMP)
-  NODE_NAME_CASE(FP_CLASS)
-  NODE_NAME_CASE(DOT4)
-  NODE_NAME_CASE(CARRY)
-  NODE_NAME_CASE(BORROW)
-  NODE_NAME_CASE(BFE_U32)
-  NODE_NAME_CASE(BFE_I32)
-  NODE_NAME_CASE(BFI)
-  NODE_NAME_CASE(BFM)
-  NODE_NAME_CASE(FFBH_U32)
-  NODE_NAME_CASE(FFBH_I32)
-  NODE_NAME_CASE(FFBL_B32)
-  NODE_NAME_CASE(MUL_U24)
-  NODE_NAME_CASE(MUL_I24)
-  NODE_NAME_CASE(MULHI_U24)
-  NODE_NAME_CASE(MULHI_I24)
-  NODE_NAME_CASE(MAD_U24)
-  NODE_NAME_CASE(MAD_I24)
-  NODE_NAME_CASE(MAD_I64_I32)
-  NODE_NAME_CASE(MAD_U64_U32)
-  NODE_NAME_CASE(PERM)
-  NODE_NAME_CASE(TEXTURE_FETCH)
-  NODE_NAME_CASE(R600_EXPORT)
-  NODE_NAME_CASE(CONST_ADDRESS)
-  NODE_NAME_CASE(REGISTER_LOAD)
-  NODE_NAME_CASE(REGISTER_STORE)
-  NODE_NAME_CASE(CVT_F32_UBYTE0)
-  NODE_NAME_CASE(CVT_F32_UBYTE1)
-  NODE_NAME_CASE(CVT_F32_UBYTE2)
-  NODE_NAME_CASE(CVT_F32_UBYTE3)
-  NODE_NAME_CASE(CVT_PKRTZ_F16_F32)
-  NODE_NAME_CASE(CVT_PKNORM_I16_F32)
-  NODE_NAME_CASE(CVT_PKNORM_U16_F32)
-  NODE_NAME_CASE(CVT_PK_I16_I32)
-  NODE_NAME_CASE(CVT_PK_U16_U32)
-  NODE_NAME_CASE(FP_TO_FP16)
-  NODE_NAME_CASE(BUILD_VERTICAL_VECTOR)
-  NODE_NAME_CASE(CONST_DATA_PTR)
-  NODE_NAME_CASE(PC_ADD_REL_OFFSET)
-  NODE_NAME_CASE(LDS)
-  NODE_NAME_CASE(DUMMY_CHAIN)
-  NODE_NAME_CASE(LOAD_D16_HI)
-  NODE_NAME_CASE(LOAD_D16_LO)
-  NODE_NAME_CASE(LOAD_D16_HI_I8)
-  NODE_NAME_CASE(LOAD_D16_HI_U8)
-  NODE_NAME_CASE(LOAD_D16_LO_I8)
-  NODE_NAME_CASE(LOAD_D16_LO_U8)
-  NODE_NAME_CASE(STORE_MSKOR)
-  NODE_NAME_CASE(TBUFFER_STORE_FORMAT)
-  NODE_NAME_CASE(TBUFFER_STORE_FORMAT_D16)
-  NODE_NAME_CASE(TBUFFER_LOAD_FORMAT)
-  NODE_NAME_CASE(TBUFFER_LOAD_FORMAT_D16)
-  NODE_NAME_CASE(DS_ORDERED_COUNT)
-  NODE_NAME_CASE(ATOMIC_CMP_SWAP)
-  NODE_NAME_CASE(BUFFER_LOAD)
-  NODE_NAME_CASE(BUFFER_LOAD_UBYTE)
-  NODE_NAME_CASE(BUFFER_LOAD_USHORT)
-  NODE_NAME_CASE(BUFFER_LOAD_BYTE)
-  NODE_NAME_CASE(BUFFER_LOAD_SHORT)
-  NODE_NAME_CASE(BUFFER_LOAD_TFE)
-  NODE_NAME_CASE(BUFFER_LOAD_UBYTE_TFE)
-  NODE_NAME_CASE(BUFFER_LOAD_USHORT_TFE)
-  NODE_NAME_CASE(BUFFER_LOAD_BYTE_TFE)
-  NODE_NAME_CASE(BUFFER_LOAD_SHORT_TFE)
-  NODE_NAME_CASE(BUFFER_LOAD_FORMAT)
-  NODE_NAME_CASE(BUFFER_LOAD_FORMAT_TFE)
-  NODE_NAME_CASE(BUFFER_LOAD_FORMAT_D16)
-  NODE_NAME_CASE(SBUFFER_LOAD)
-  NODE_NAME_CASE(SBUFFER_LOAD_BYTE)
-  NODE_NAME_CASE(SBUFFER_LOAD_UBYTE)
-  NODE_NAME_CASE(SBUFFER_LOAD_SHORT)
-  NODE_NAME_CASE(SBUFFER_LOAD_USHORT)
-  NODE_NAME_CASE(SBUFFER_PREFETCH_DATA)
-  NODE_NAME_CASE(BUFFER_STORE)
-  NODE_NAME_CASE(BUFFER_STORE_BYTE)
-  NODE_NAME_CASE(BUFFER_STORE_SHORT)
-  NODE_NAME_CASE(BUFFER_STORE_FORMAT)
-  NODE_NAME_CASE(BUFFER_STORE_FORMAT_D16)
-  NODE_NAME_CASE(BUFFER_ATOMIC_SWAP)
-  NODE_NAME_CASE(BUFFER_ATOMIC_ADD)
-  NODE_NAME_CASE(BUFFER_ATOMIC_SUB)
-  NODE_NAME_CASE(BUFFER_ATOMIC_SMIN)
-  NODE_NAME_CASE(BUFFER_ATOMIC_UMIN)
-  NODE_NAME_CASE(BUFFER_ATOMIC_SMAX)
-  NODE_NAME_CASE(BUFFER_ATOMIC_UMAX)
-  NODE_NAME_CASE(BUFFER_ATOMIC_AND)
-  NODE_NAME_CASE(BUFFER_ATOMIC_OR)
-  NODE_NAME_CASE(BUFFER_ATOMIC_XOR)
-  NODE_NAME_CASE(BUFFER_ATOMIC_INC)
-  NODE_NAME_CASE(BUFFER_ATOMIC_DEC)
-  NODE_NAME_CASE(BUFFER_ATOMIC_CMPSWAP)
-  NODE_NAME_CASE(BUFFER_ATOMIC_CSUB)
-  NODE_NAME_CASE(BUFFER_ATOMIC_FADD)
-  NODE_NAME_CASE(BUFFER_ATOMIC_FMIN)
-  NODE_NAME_CASE(BUFFER_ATOMIC_FMAX)
-  NODE_NAME_CASE(BUFFER_ATOMIC_COND_SUB_U32)
-  }
-  return nullptr;
-}
-
 SDValue AMDGPUTargetLowering::getSqrtEstimate(SDValue Operand,
                                               SelectionDAG &DAG, int Enabled,
                                               int &RefinementSteps,
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h
index c74dc7942f52c0..c13fbfe51f2397 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h
@@ -278,8 +278,6 @@ class AMDGPUTargetLowering : public TargetLowering {
                                SDValue RHS, SDValue True, SDValue False,
                                SDValue CC, DAGCombinerInfo &DCI) const;
 
-  const char* getTargetNodeName(unsigned Opcode) const override;
-
   // FIXME: Turn off MergeConsecutiveStores() before Instruction Selection for
   // AMDGPU.  Commit r319036,
   // (https://github.com/llvm/llvm-project/commit/db77e57ea86d941a4262ef60261692f4cb6893e6)
@@ -389,226 +387,6 @@ class AMDGPUTargetLowering : public TargetLowering {
   }
 };
 
-namespace AMDGPUISD {
-
-enum NodeType : unsigned {
-  // AMDIL ISD Opcodes
-  FIRST_NUMBER = ISD::BUILTIN_OP_END,
-  BRANCH_COND,
-  // End AMDIL ISD Opcodes
-
-  // Function call.
-  CALL,
-  TC_RETURN,
-  TC_RETURN_GFX,
-  TC_RETURN_CHAIN,
-  TRAP,
-
-  // Masked control flow nodes.
-  IF,
-  ELSE,
-  LOOP,
-
-  // A uniform kernel return that terminates the wavefront.
-  ENDPGM,
-
-  // s_endpgm, but we may want to insert it in the middle of the block.
-  ENDPGM_TRAP,
-
-  // "s_trap 2" equivalent on hardware that does not support it.
-  SIMULATED_TRAP,
-
-  // Return to a shader part's epilog code.
-  RETURN_TO_EPILOG,
-
-  // Return with values from a non-entry function.
-  RET_GLUE,
-
-  // Convert a unswizzled wave uniform stack address to an address compatible
-  // with a vector offset for use in stack access.
-  WAVE_ADDRESS,
-
-  DWORDADDR,
-  FRACT,
-
-  /// CLAMP value between 0.0 and 1.0. NaN clamped to 0, following clamp output
-  /// modifier behavior with dx10_enable.
-  CLAMP,
-
-  // This is SETCC with the full mask result which is used for a compare with a
-  // result bit per item in the wavefront.
-  SETCC,
-
-  DENORM_MODE,
-
-  // FP ops with input and output chain.
-  FMA_W_CHAIN,
-  FMUL_W_CHAIN,
-
-  // SIN_HW, COS_HW - f32 for SI, 1 ULP max error, valid from -100 pi to 100 pi.
-  // Denormals handled on some parts.
-  COS_HW,
-  SIN_HW,
-  FMAX_LEGACY,
-  FMIN_LEGACY,
-
-  FMAX3,
-  SMAX3,
-  UMAX3,
-  FMIN3,
-  SMIN3,
-  UMIN3,
-  FMED3,
-  SMED3,
-  UMED3,
-  FMAXIMUM3,
-  FMINIMUM3,
-  FDOT2,
-  URECIP,
-  DIV_SCALE,
-  DIV_FMAS,
-  DIV_FIXUP,
-  // For emitting ISD::FMAD when f32 denormals are enabled because mac/mad is
-  // treated as an illegal operation.
-  FMAD_FTZ,
-
-  // RCP, RSQ - For f32, 1 ULP max error, no denormal handling.
-  //            For f64, max error 2^29 ULP, handles denormals.
-  RCP,
-  RSQ,
-  RCP_LEGACY,
-  RCP_IFLAG,
-
-  // log2, no denormal handling for f32.
-  LOG,
-
-  // exp2, no denormal handling for f32.
-  EXP,
-
-  FMUL_LEGACY,
-  RSQ_CLAMP,
-  FP_CLASS,
-  DOT4,
-  CARRY,
-  BORROW,
-  BFE_U32,  // Extract range of bits with zero extension to 32-bits.
-  BFE_I32,  // Extract range of bits with sign extension to 32-bits.
-  BFI,      // (src0 & src1) | (~src0 & src2)
-  BFM,      // Insert a range of bits into a 32-bit word.
-  FFBH_U32, // ctlz with -1 if input is zero.
-  FFBH_I32,
-  FFBL_B32, // cttz with -1 if input is zero.
-  MUL_U24,
-  MUL_I24,
-  MULHI_U24,
-  MULHI_I24,
-  MAD_U24,
-  MAD_I24,
-  MAD_U64_U32,
-  MAD_I64_I32,
-  PERM,
-  TEXTURE_FETCH,
-  R600_EXPORT,
-  CONST_ADDRESS,
-  REGISTER_LOAD,
-  REGISTER_STORE,
-
-  // These cvt_f32_ubyte* nodes need to remain consecutive and in order.
-  CVT_F32_UBYTE0,
-  CVT_F32_UBYTE1,
-  CVT_F32_UBYTE2,
-  CVT_F32_UBYTE3,
-
-  // Convert two float 32 numbers into a single register holding two packed f16
-  // with round to zero.
-  CVT_PKRTZ_F16_F32,
-  CVT_PKNORM_I16_F32,
-  CVT_PKNORM_U16_F32,
-  CVT_PK_I16_I32,
-  CVT_PK_U16_U32,
-
-  // Same as the standard node, except the high bits of the resulting integer
-  // are known 0.
-  FP_TO_FP16,
-
-  /// This node is for VLIW targets and it is used to represent a vector
-  /// that is stored in consecutive registers with the same channel.
-  /// For example:
-  ///   |X  |Y|Z|W|
-  /// T0|v.x| | | |
-  /// T1|v.y| | | |
-  /// T2|v.z| | | |
-  /// T3|v.w| | | |
-  BUILD_VERTICAL_VECTOR,
-  /// Pointer to the start of the shader's constant data.
-  CONST_DATA_PTR,
-  PC_ADD_REL_OFFSET,
-  LDS,
-
-  DUMMY_CHAIN,
-
-  FIRST_MEMORY_OPCODE,
-  LOAD_D16_HI = FIRST_MEMORY_OPCODE,
-  LOAD_D16_LO,
-  LOAD_D16_HI_I8,
-  LOAD_D16_HI_U8,
-  LOAD_D16_LO_I8,
-  LOAD_D16_LO_U8,
-
-  STORE_MSKOR,
-  TBUFFER_STORE_FORMAT,
-  TBUFFER_STORE_FORMAT_D16,
-  TBUFFER_LOAD_FORMAT,
-  TBUFFER_LOAD_FORMAT_D16,
-  DS_ORDERED_COUNT,
-  ATOMIC_CMP_SWAP,
-  BUFFER_LOAD,
-  BUFFER_LOAD_UBYTE,
-  BUFFER_LOAD_USHORT,
-  BUFFER_LOAD_BYTE,
-  BUFFER_LOAD_SHORT,
-  BUFFER_LOAD_TFE,
-  BUFFER_LOAD_UBYTE_TFE,
-  BUFFER_LOAD_USHORT_TFE,
-  BUFFER_LOAD_BYTE_TFE,
-  BUFFER_LOAD_SHORT_TFE,
-  BUFFER_LOAD_FORMAT,
-  BUFFER_LOAD_FORMAT_TFE,
-  BUFFER_LOAD_FORMAT_D16,
-  SBUFFER_LOAD,
-  SBUFFER_LOAD_BYTE,
-  SBUFFER_LOAD_UBYTE,
-  SBUFFER_LOAD_SHORT,
-  SBUFFER_LOAD_USHORT,
-  SBUFFER_PREFETCH_DATA,
-  BUFFER_STORE,
-  BUFFER_STORE_BYTE,
-  BUFFER_STORE_SHORT,
-  BUFFER_STORE_FORMAT,
-  BUFFER_STORE_FORMAT_D16,
-  BUFFER_ATOMIC_SWAP,
-  BUFFER_ATOMIC_ADD,
-  BUFFER_ATOMIC_SUB,
-  BUFFER_ATOMIC_SMIN,
-  BUFFER_ATOMIC_UMIN,
-  BUFFER_ATOMIC_SMAX,
-  BUFFER_ATOMIC_UMAX,
-  BUFFER_ATOMIC_AND,
-  BUFFER_ATOMIC_OR,
-  BUFFER_ATOMIC_XOR,
-  BUFFER_ATOMIC_INC,
-  BUFFER_ATOMIC_DEC,
-  BUFFER_ATOMIC_CMPSWAP,
-  BUFFER_ATOMIC_CSUB,
-  BUFFER_ATOMIC_FADD,
-  BUFFER_ATOMIC_FMIN,
-  BUFFER_ATOMIC_FMAX,
-  BUFFER_ATOMIC_COND_SUB_U32,
-  LAST_MEMORY_OPCODE = BUFFER_ATOMIC_COND_SUB_U32,
-};
-
-} // End namespace AMDGPUISD
-
 } // End namespace llvm
 
 #endif
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.cpp
index 97705ca89f3d2c..4bc2564ff8b484 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.cpp
@@ -7,15 +7,51 @@
 //===----------------------------------------------------------------------===//
 
 #include "AMDGPUSelectionDAGInfo.h"
-#include "AMDGPUISelLowering.h"
+
+#define GET_SDNODE_DESC
+#include "AMDGPUGenSDNodeInfo.inc"
 
 using namespace llvm;
 
+AMDGPUSelectionDAGInfo::AMDGPUSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(AMDGPUGenSDNodeInfo) {}
+
 AMDGPUSelectionDAGInfo::~AMDGPUSelectionDAGInfo() = default;
 
-bool AMDGPUSelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
-  if (Opcode >= AMDGPUISD::FIRST_MEMORY_OPCODE &&
-      Opcode <= AMDGPUISD::LAST_MEMORY_OPCODE)
-    return true;
-  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+const char *AMDGPUSelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
+#define NODE_NAME_CASE(node)                                                   \
+  case AMDGPUISD::node:                                                        \
+    return #node;
+
+  switch (static_cast<AMDGPUISD::NodeType>(Opcode)) {
+    // These nodes don't have corresponding entries in *.td files yet.
+    NODE_NAME_CASE(WAVE_ADDRESS)
+    NODE_NAME_CASE(MAD_I64_I32)
+    NODE_NAME_CASE(MAD_U64_U32)
+    NODE_NAME_CASE(BUILD_VERTICAL_VECTOR)
+    // These do, but only when compiling R600.td,
+    // and the enum is generated from AMDGPU.td.
+    NODE_NAME_CASE(DOT4)
+    NODE_NAME_CASE(TEXTURE_FETCH)
+    NODE_NAME_CASE(R600_EXPORT)
+    NODE_NAME_CASE(CONST_ADDRESS)
+    NODE_NAME_CASE(DUMMY_CHAIN)
+  }
+
+#undef NODE_NAME_CASE
+
+  return SelectionDAGGenTargetInfo::getTargetNodeName(Opcode);
+}
+
+void AMDGPUSelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
+                                              const SDNode *N) const {
+  switch (N->getOpcode()) {
+  case AMDGPUISD::BUFFER_LOAD:
+    // result #1 has invalid type; expected ch, got glue
+  case AMDGPUISD::DENORM_MODE:
+    // invalid number of results; expected 2, got 1
+    return;
+  }
+
+  SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
 }
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.h b/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.h
index a4f3488ab7a1fa..180ce5b60975f3 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.h
@@ -11,13 +11,49 @@
 
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 
+#define GET_SDNODE_ENUM
+#include "AMDGPUGenSDNodeInfo.inc"
+
 namespace llvm {
+namespace AMDGPUISD {
+
+enum NodeType : unsigned {
+  // Convert a unswizzled wave uniform stack address to an address compatible
+  // with a vector offset for use in stack access.
+  WAVE_ADDRESS = GENERATED_OPCODE_END,
+
+  DOT4,
+  MAD_U64_U32,
+  MAD_I64_I32,
+  TEXTURE_FETCH,
+  R600_EXPORT,
+  CONST_ADDRESS,
 
-class AMDGPUSelectionDAGInfo : public SelectionDAGTargetInfo {
+  /// This node is for VLIW targets and it is used to represent a vector
+  /// that is stored in consecutive registers with the same channel.
+  /// For example:
+  ///   |X  |Y|Z|W|
+  /// T0|v.x| | | |
+  /// T1|v.y| | | |
+  /// T2|v.z| | | |
+  /// T3|v.w| | | |
+  BUILD_VERTICAL_VECTOR,
+
+  DUMMY_CHAIN,
+};
+
+} // namespace AMDGPUISD
+
+class AMDGPUSelectionDAGInfo : public SelectionDAGGenTargetInfo {
 public:
+  AMDGPUSelectionDAGInfo();
+
   ~AMDGPUSelectionDAGInfo() override;
 
-  bool isTargetMemoryOpcode(unsigned Opcode) const override;
+  const char *getTargetNodeName(unsigned Opcode) const override;
+
+  void verifyTargetNode(const SelectionDAG &DAG,
+                        const SDNode *N) const override;
 };
 
 } // namespace llvm
diff --git a/llvm/lib/Target/AMDGPU/CMakeLists.txt b/llvm/lib/Target/AMDGPU/CMakeLists.txt
index 03038caab521df..284ee93752a30b 100644
--- a/llvm/lib/Target/AMDGPU/CMakeLists.txt
+++ b/llvm/lib/Target/AMDGPU/CMakeLists.txt
@@ -12,6 +12,7 @@ tablegen(LLVM AMDGPUGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM AMDGPUGenMCPseudoLowering.inc -gen-pseudo-lowering)
 tablegen(LLVM AMDGPUGenRegisterBank.inc -gen-register-bank)
 tablegen(LLVM AMDGPUGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM AMDGPUGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM AMDGPUGenSearchableTables.inc -gen-searchable-tables)
 tablegen(LLVM AMDGPUGenSubtargetInfo.inc -gen-subtarget)
 
@@ -32,6 +33,7 @@ tablegen(LLVM R600GenDFAPacketizer.inc -gen-dfa-packetizer)
 tablegen(LLVM R600GenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM R600GenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM R600GenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM R600GenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM R600GenSubtargetInfo.inc -gen-subtarget)
 
 add_public_tablegen_target(AMDGPUCommonTableGen)
diff --git a/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp b/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp
index c2e952418f1be2..9aa6b5b0802aa1 100644
--- a/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp
@@ -13,6 +13,7 @@
 
 #include "R600ISelLowering.h"
 #include "AMDGPU.h"
+#include "AMDGPUSelectionDAGInfo.h"
 #include "MCTargetDesc/R600MCTargetDesc.h"
 #include "R600Defines.h"
 #include "R600MachineFunctionInfo.h"
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index 8dfebd36a962e1..5ef23dcdadd354 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -14,6 +14,7 @@
 #include "SIISelLowering.h"
 #include "AMDGPU.h"
 #include "AMDGPUInstrInfo.h"
+#include "AMDGPUSelectionDAGInfo.h"
 #include "AMDGPUTargetMachine.h"
 #include "GCNSubtarget.h"
 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ds.ordered.add.gfx11.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ds.ordered.add.gfx11.ll
index 30a7235d6a702b..e79b79aeb88ad2 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ds.ordered.add.gfx11.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ds.ordered.add.gfx11.ll
@@ -2,7 +2,7 @@
 ; RUN: llc -global-isel -mtriple=amdgcn -mcpu=gfx1100 -amdgpu-enable-vopd=0 -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,FUNC %s
 ; RUN: not --crash llc -mtriple=amdgcn -mcpu=gfx1200 -amdgpu-enable-vopd=0 -verify-machineinstrs < %s 2>&1 | FileCheck -check-prefix=GFX12-ERR %s
 
-; GFX12-ERR: LLVM ERROR: Cannot select: {{.*}} = DS_ORDERED_COUNT
+; GFX12-ERR: LLVM ERROR: Cannot select: {{.*}} = AMDGPUISD::DS_ORDERED_COUNT
 
 ; FUNC-LABEL: {{^}}ds_ordered_add:
 ; GCN-DAG: v_mov_b32_e32 v[[INCR:[0-9]+]], 31
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ptr.buffer.atomic.fadd_rtn_errors.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ptr.buffer.atomic.fadd_rtn_errors.ll
index f8caf84d5c51a2..63c7fddb42ecef 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ptr.buffer.atomic.fadd_rtn_errors.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ptr.buffer.atomic.fadd_rtn_errors.ll
@@ -29,7 +29,7 @@
 ; Check bf16 buffer fadd does not select on supported subtargets.
 
 ;--- raw-ret-f32-error.ll
-; ERR-RAW-F32-SDAG: LLVM ERROR: Cannot select: {{.+}}: f32,ch = BUFFER_ATOMIC_FADD
+; ERR-RAW-F32-SDAG: LLVM ERROR: Cannot select: {{.+}}: f32,ch = AMDGPUISD::BUFFER_ATOMIC_FADD
 ; ERR-RAW-F32-GISEL: LLVM ERROR: cannot select: %{{[0-9]+}}:vgpr_32(s32) = G_AMDGPU_BUFFER_ATOMIC_FADD
 
 define float @raw_ptr_buffer_atomic_fadd_f32_rtn(float %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) {
@@ -38,7 +38,7 @@ define float @raw_ptr_buffer_atomic_fadd_f32_rtn(float %val, <4 x i32> inreg %rs
 }
 
 ;--- struct-ret-f32-error.ll
-; ERR-STRUCT-F32-SDAG: LLVM ERROR: Cannot select: {{.+}}: f32,ch = BUFFER_ATOMIC_FADD
+; ERR-STRUCT-F32-SDAG: LLVM ERROR: Cannot select: {{.+}}: f32,ch = AMDGPUISD::BUFFER_ATOMIC_FADD
 ; ERR-STRUCT-F32-GISEL: LLVM ERROR: cannot select: %{{[0-9]+}}:vgpr_32(s32) = G_AMDGPU_BUFFER_ATOMIC_FADD
 
 define float @struct_ptr_buffer_atomic_fadd_f32_rtn(float %val, ptr addrspace(8) inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) {
@@ -47,7 +47,7 @@ define float @struct_ptr_buffer_atomic_fadd_f32_rtn(float %val, ptr addrspace(8)
 }
 
 ;--- raw-ret-v2f16-error.ll
-; ERR-RAW-V2F16-SDAG: LLVM ERROR: Cannot select: {{.+}}: v2f16,ch = BUFFER_ATOMIC_FADD
+; ERR-RAW-V2F16-SDAG: LLVM ERROR: Cannot select: {{.+}}: v2f16,ch = AMDGPUISD::BUFFER_ATOMIC_FADD
 ; ERR-RAW-V2F16-GISEL: LLVM ERROR: cannot select: %{{[0-9]+}}:vgpr_32(<2 x s16>) = G_AMDGPU_BUFFER_ATOMIC_FADD
 
 define <2 x half> @raw_ptr_buffer_atomic_fadd_v2f16_rtn(<2 x half> %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) {
@@ -56,7 +56,7 @@ define <2 x half> @raw_ptr_buffer_atomic_fadd_v2f16_rtn(<2 x half> %val, <4 x i3
 }
 
 ;--- struct-ret-v2f16-error.ll
-; ERR-STRUCT-V2F16-SDAG: LLVM ERROR: Cannot select: {{.+}}: v2f16,ch = BUFFER_ATOMIC_FADD
+; ERR-STRUCT-V2F16-SDAG: LLVM ERROR: Cannot select: {{.+}}: v2f16,ch = AMDGPUISD::BUFFER_ATOMIC_FADD
 ; ERR-STRUCT-V2F16-GISEL: LLVM ERROR: cannot select: %{{[0-9]+}}:vgpr_32(<2 x s16>) = G_AMDGPU_BUFFER_ATOMIC_FADD
 
 define <2 x half> @struct_ptr_buffer_atomic_fadd_v2f16_rtn(<2 x half> %val, ptr addrspace(8) inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) {
@@ -65,7 +65,7 @@ define <2 x half> @struct_ptr_buffer_atomic_fadd_v2f16_rtn(<2 x half> %val, ptr
 }
 
 ;--- raw-ret-v2bf16-error.ll
-; ERR-RAW-V2BF16-SDAG: LLVM ERROR: Cannot select: {{.+}}: v2bf16,ch = BUFFER_ATOMIC_FADD
+; ERR-RAW-V2BF16-SDAG: LLVM ERROR: Cannot select: {{.+}}: v2bf16,ch = AMDGPUISD::BUFFER_ATOMIC_FADD
 ; ERR-RAW-V2BF16-GISEL: LLVM ERROR: cannot select: %{{[0-9]+}}:vgpr_32(<2 x s16>) = G_AMDGPU_BUFFER_ATOMIC_FADD
 
 define <2 x bfloat> @raw_ptr_buffer_atomic_fadd_v2bf16_rtn(<2 x bfloat> %val, <4 x i32> inreg %rsrc, i32 inreg %soffset) {
@@ -74,7 +74,7 @@ define <2 x bfloat> @raw_ptr_buffer_atomic_fadd_v2bf16_rtn(<2 x bfloat> %val, <4
 }
 
 ;--- struct-ret-v2bf16-error.ll
-; ERR-STRUCT-V2BF16-SDAG: LLVM ERROR: Cannot select: {{.+}}: v2bf16,ch = BUFFER_ATOMIC_FADD
+; ERR-STRUCT-V2BF16-SDAG: LLVM ERROR: Cannot select: {{.+}}: v2bf16,ch = AMDGPUISD::BUFFER_ATOMIC_FADD
 ; ERR-STRUCT-V2BF16-GISEL: LLVM ERROR: cannot select: %{{[0-9]+}}:vgpr_32(<2 x s16>) = G_AMDGPU_BUFFER_ATOMIC_FADD
 
 define <2 x bfloat> @struct_ptr_buffer_atomic_fadd_v2bf16_rtn(<2 x bfloat> %val, ptr addrspace(8) inreg %rsrc, i32 %vindex, i32 %voffset, i32 inreg %soffset) {
diff --git a/llvm/test/CodeGen/AMDGPU/sdag-print-divergence.ll b/llvm/test/CodeGen/AMDGPU/sdag-print-divergence.ll
index 695d5225421de7..f6498448dc335e 100644
--- a/llvm/test/CodeGen/AMDGPU/sdag-print-divergence.ll
+++ b/llvm/test/CodeGen/AMDGPU/sdag-print-divergence.ll
@@ -13,7 +13,7 @@
 ; GCN-DEFAULT:      t4: f32,ch = CopyFromReg # D:1 t0, Register:f32 %1
 ; GCN-DEFAULT:    t6: f32 = fadd # D:1 t5, t4
 ; GCN-DEFAULT:  t8: ch,glue = CopyToReg # D:1 t0, Register:f32 $vgpr0, t6
-; GCN-DEFAULT:  t9: ch = RETURN_TO_EPILOG t8, Register:f32 $vgpr0, t8:1
+; GCN-DEFAULT:  t9: ch = AMDGPUISD::RETURN_TO_EPILOG t8, Register:f32 $vgpr0, t8:1
 
 ; GCN-VERBOSE:  t0: ch,glue = EntryToken # D:0
 ; GCN-VERBOSE:  t2: f32,ch = CopyFromReg [ORD=1] # D:0 t0, Register:f32 %0 # D:0
@@ -21,7 +21,7 @@
 ; GCN-VERBOSE:      t4: f32,ch = CopyFromReg [ORD=1] # D:1 t0, Register:f32 %1 # D:0
 ; GCN-VERBOSE:    t6: f32 = fadd [ORD=3] # D:1 t5, t4
 ; GCN-VERBOSE:  t8: ch,glue = CopyToReg [ORD=4] # D:1 t0, Register:f32 $vgpr0 # D:0, t6
-; GCN-VERBOSE:  t9: ch = RETURN_TO_EPILOG [ORD=4] # D:0 t8, Register:f32 $vgpr0 # D:0, t8:1
+; GCN-VERBOSE:  t9: ch = AMDGPUISD::RETURN_TO_EPILOG [ORD=4] # D:0 t8, Register:f32 $vgpr0 # D:0, t8:1
 
 define amdgpu_ps float @test_sdag_dump(float inreg %scalar, float %vector)  {
 entry:

>From 7e43b9ab4cb548200fdf4360816416f642727c6f Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 03:11:01 +0300
Subject: [PATCH 06/27] ARC

---
 llvm/lib/Target/ARC/ARCISelDAGToDAG.cpp     |  1 +
 llvm/lib/Target/ARC/ARCISelLowering.cpp     | 19 +-----------
 llvm/lib/Target/ARC/ARCISelLowering.h       | 33 ---------------------
 llvm/lib/Target/ARC/ARCSelectionDAGInfo.cpp | 19 ++++++++++++
 llvm/lib/Target/ARC/ARCSelectionDAGInfo.h   | 28 +++++++++++++++++
 llvm/lib/Target/ARC/ARCSubtarget.cpp        | 11 ++++++-
 llvm/lib/Target/ARC/ARCSubtarget.h          | 10 +++----
 llvm/lib/Target/ARC/CMakeLists.txt          |  2 ++
 8 files changed, 66 insertions(+), 57 deletions(-)
 create mode 100644 llvm/lib/Target/ARC/ARCSelectionDAGInfo.cpp
 create mode 100644 llvm/lib/Target/ARC/ARCSelectionDAGInfo.h

diff --git a/llvm/lib/Target/ARC/ARCISelDAGToDAG.cpp b/llvm/lib/Target/ARC/ARCISelDAGToDAG.cpp
index 5e6cfa539b6d84..02a5721c70fcd5 100644
--- a/llvm/lib/Target/ARC/ARCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/ARC/ARCISelDAGToDAG.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "ARC.h"
+#include "ARCSelectionDAGInfo.h"
 #include "ARCTargetMachine.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
diff --git a/llvm/lib/Target/ARC/ARCISelLowering.cpp b/llvm/lib/Target/ARC/ARCISelLowering.cpp
index 5ab27681361db5..688bfcfc34d1ad 100644
--- a/llvm/lib/Target/ARC/ARCISelLowering.cpp
+++ b/llvm/lib/Target/ARC/ARCISelLowering.cpp
@@ -13,6 +13,7 @@
 #include "ARCISelLowering.h"
 #include "ARC.h"
 #include "ARCMachineFunctionInfo.h"
+#include "ARCSelectionDAGInfo.h"
 #include "ARCSubtarget.h"
 #include "ARCTargetMachine.h"
 #include "MCTargetDesc/ARCInfo.h"
@@ -178,24 +179,6 @@ ARCTargetLowering::ARCTargetLowering(const TargetMachine &TM,
   setMaxAtomicSizeInBitsSupported(0);
 }
 
-const char *ARCTargetLowering::getTargetNodeName(unsigned Opcode) const {
-  switch (Opcode) {
-  case ARCISD::BL:
-    return "ARCISD::BL";
-  case ARCISD::CMOV:
-    return "ARCISD::CMOV";
-  case ARCISD::CMP:
-    return "ARCISD::CMP";
-  case ARCISD::BRcc:
-    return "ARCISD::BRcc";
-  case ARCISD::RET:
-    return "ARCISD::RET";
-  case ARCISD::GAWRAPPER:
-    return "ARCISD::GAWRAPPER";
-  }
-  return nullptr;
-}
-
 //===----------------------------------------------------------------------===//
 //  Misc Lower Operation implementation
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/ARC/ARCISelLowering.h b/llvm/lib/Target/ARC/ARCISelLowering.h
index e070ed8752cce9..667d92ce2f61ed 100644
--- a/llvm/lib/Target/ARC/ARCISelLowering.h
+++ b/llvm/lib/Target/ARC/ARCISelLowering.h
@@ -24,36 +24,6 @@ namespace llvm {
 class ARCSubtarget;
 class ARCTargetMachine;
 
-namespace ARCISD {
-
-enum NodeType : unsigned {
-  // Start the numbering where the builtin ops and target ops leave off.
-  FIRST_NUMBER = ISD::BUILTIN_OP_END,
-
-  // Branch and link (call)
-  BL,
-
-  // Jump and link (indirect call)
-  JL,
-
-  // CMP
-  CMP,
-
-  // CMOV
-  CMOV,
-
-  // BRcc
-  BRcc,
-
-  // Global Address Wrapper
-  GAWRAPPER,
-
-  // return, (j_s [blink])
-  RET
-};
-
-} // end namespace ARCISD
-
 //===--------------------------------------------------------------------===//
 // TargetLowering Implementation
 //===--------------------------------------------------------------------===//
@@ -65,9 +35,6 @@ class ARCTargetLowering : public TargetLowering {
   /// Provide custom lowering hooks for some operations.
   SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
 
-  /// This method returns the name of a target specific DAG node.
-  const char *getTargetNodeName(unsigned Opcode) const override;
-
   /// Return true if the addressing mode represented by AM is legal for this
   /// target, for a load/store of the specified type.
   bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty,
diff --git a/llvm/lib/Target/ARC/ARCSelectionDAGInfo.cpp b/llvm/lib/Target/ARC/ARCSelectionDAGInfo.cpp
new file mode 100644
index 00000000000000..4883f894d564e0
--- /dev/null
+++ b/llvm/lib/Target/ARC/ARCSelectionDAGInfo.cpp
@@ -0,0 +1,19 @@
+//===- ARCSelectionDAGInfo.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ARCSelectionDAGInfo.h"
+
+#define GET_SDNODE_DESC
+#include "ARCGenSDNodeInfo.inc"
+
+using namespace llvm;
+
+ARCSelectionDAGInfo::ARCSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(ARCGenSDNodeInfo) {}
+
+ARCSelectionDAGInfo::~ARCSelectionDAGInfo() = default;
diff --git a/llvm/lib/Target/ARC/ARCSelectionDAGInfo.h b/llvm/lib/Target/ARC/ARCSelectionDAGInfo.h
new file mode 100644
index 00000000000000..2e8f7153d44d44
--- /dev/null
+++ b/llvm/lib/Target/ARC/ARCSelectionDAGInfo.h
@@ -0,0 +1,28 @@
+//===- ARCSelectionDAGInfo.h ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_ARC_ARCSELECTIONDAGINFO_H
+#define LLVM_LIB_TARGET_ARC_ARCSELECTIONDAGINFO_H
+
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+
+#define GET_SDNODE_ENUM
+#include "ARCGenSDNodeInfo.inc"
+
+namespace llvm {
+
+class ARCSelectionDAGInfo : public SelectionDAGGenTargetInfo {
+public:
+  ARCSelectionDAGInfo();
+
+  ~ARCSelectionDAGInfo() override;
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_ARC_ARCSELECTIONDAGINFO_H
diff --git a/llvm/lib/Target/ARC/ARCSubtarget.cpp b/llvm/lib/Target/ARC/ARCSubtarget.cpp
index 641c56b06870f8..a32ace582a9ccf 100644
--- a/llvm/lib/Target/ARC/ARCSubtarget.cpp
+++ b/llvm/lib/Target/ARC/ARCSubtarget.cpp
@@ -12,6 +12,7 @@
 
 #include "ARCSubtarget.h"
 #include "ARC.h"
+#include "ARCSelectionDAGInfo.h"
 #include "llvm/MC/TargetRegistry.h"
 
 using namespace llvm;
@@ -27,4 +28,12 @@ void ARCSubtarget::anchor() {}
 ARCSubtarget::ARCSubtarget(const Triple &TT, const std::string &CPU,
                            const std::string &FS, const TargetMachine &TM)
     : ARCGenSubtargetInfo(TT, CPU, /*TuneCPU=*/CPU, FS), InstrInfo(*this),
-      FrameLowering(*this), TLInfo(TM, *this) {}
+      FrameLowering(*this), TLInfo(TM, *this) {
+  TSInfo = std::make_unique<ARCSelectionDAGInfo>();
+}
+
+ARCSubtarget::~ARCSubtarget() = default;
+
+const SelectionDAGTargetInfo *ARCSubtarget::getSelectionDAGInfo() const {
+  return TSInfo.get();
+}
diff --git a/llvm/lib/Target/ARC/ARCSubtarget.h b/llvm/lib/Target/ARC/ARCSubtarget.h
index f3429677deeb77..5f35e3a85d9dba 100644
--- a/llvm/lib/Target/ARC/ARCSubtarget.h
+++ b/llvm/lib/Target/ARC/ARCSubtarget.h
@@ -16,7 +16,6 @@
 #include "ARCFrameLowering.h"
 #include "ARCISelLowering.h"
 #include "ARCInstrInfo.h"
-#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include <string>
 
@@ -33,7 +32,7 @@ class ARCSubtarget : public ARCGenSubtargetInfo {
   ARCInstrInfo InstrInfo;
   ARCFrameLowering FrameLowering;
   ARCTargetLowering TLInfo;
-  SelectionDAGTargetInfo TSInfo;
+  std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
 
   // ARC processor extensions
   bool Xnorm = false;
@@ -44,6 +43,8 @@ class ARCSubtarget : public ARCGenSubtargetInfo {
   ARCSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS,
                const TargetMachine &TM);
 
+  ~ARCSubtarget() override;
+
   /// Parses features string setting specified subtarget options.
   /// Definition of function is auto generated by tblgen.
   void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
@@ -58,9 +59,8 @@ class ARCSubtarget : public ARCGenSubtargetInfo {
   const ARCRegisterInfo *getRegisterInfo() const override {
     return &InstrInfo.getRegisterInfo();
   }
-  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
-    return &TSInfo;
-  }
+
+  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
 
   bool hasNorm() const { return Xnorm; }
 };
diff --git a/llvm/lib/Target/ARC/CMakeLists.txt b/llvm/lib/Target/ARC/CMakeLists.txt
index 9f3c1787c5635e..196cc31cc50802 100644
--- a/llvm/lib/Target/ARC/CMakeLists.txt
+++ b/llvm/lib/Target/ARC/CMakeLists.txt
@@ -8,6 +8,7 @@ tablegen(LLVM ARCGenDAGISel.inc -gen-dag-isel)
 tablegen(LLVM ARCGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM ARCGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM ARCGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM ARCGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM ARCGenSubtargetInfo.inc -gen-subtarget)
 
 add_public_tablegen_target(ARCCommonTableGen)
@@ -24,6 +25,7 @@ add_llvm_target(ARCCodeGen
   ARCMCInstLower.cpp
   ARCOptAddrMode.cpp
   ARCRegisterInfo.cpp
+  ARCSelectionDAGInfo.cpp
   ARCSubtarget.cpp
   ARCTargetMachine.cpp
 

>From 4e364f2d9934ed99c020e42963c5c88970b6813d Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 01:00:59 +0300
Subject: [PATCH 07/27] ARM

---
 llvm/lib/Target/ARM/ARMISelLowering.cpp     | 220 +-------------
 llvm/lib/Target/ARM/ARMISelLowering.h       | 315 --------------------
 llvm/lib/Target/ARM/ARMInstrInfo.td         |   2 +-
 llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp | 114 ++++++-
 llvm/lib/Target/ARM/ARMSelectionDAGInfo.h   |  71 ++++-
 llvm/lib/Target/ARM/CMakeLists.txt          |   1 +
 6 files changed, 186 insertions(+), 537 deletions(-)

diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 595bb6e73f453c..c6e5cddf71f84e 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -1695,220 +1695,6 @@ ARMTargetLowering::findRepresentativeClass(const TargetRegisterInfo *TRI,
   return std::make_pair(RRC, Cost);
 }
 
-const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
-#define MAKE_CASE(V)                                                           \
-  case V:                                                                      \
-    return #V;
-  switch ((ARMISD::NodeType)Opcode) {
-  case ARMISD::FIRST_NUMBER:
-    break;
-    MAKE_CASE(ARMISD::Wrapper)
-    MAKE_CASE(ARMISD::WrapperPIC)
-    MAKE_CASE(ARMISD::WrapperJT)
-    MAKE_CASE(ARMISD::COPY_STRUCT_BYVAL)
-    MAKE_CASE(ARMISD::CALL)
-    MAKE_CASE(ARMISD::CALL_PRED)
-    MAKE_CASE(ARMISD::CALL_NOLINK)
-    MAKE_CASE(ARMISD::tSECALL)
-    MAKE_CASE(ARMISD::t2CALL_BTI)
-    MAKE_CASE(ARMISD::BRCOND)
-    MAKE_CASE(ARMISD::BR_JT)
-    MAKE_CASE(ARMISD::BR2_JT)
-    MAKE_CASE(ARMISD::RET_GLUE)
-    MAKE_CASE(ARMISD::SERET_GLUE)
-    MAKE_CASE(ARMISD::INTRET_GLUE)
-    MAKE_CASE(ARMISD::PIC_ADD)
-    MAKE_CASE(ARMISD::CMP)
-    MAKE_CASE(ARMISD::CMN)
-    MAKE_CASE(ARMISD::CMPZ)
-    MAKE_CASE(ARMISD::CMPFP)
-    MAKE_CASE(ARMISD::CMPFPE)
-    MAKE_CASE(ARMISD::CMPFPw0)
-    MAKE_CASE(ARMISD::CMPFPEw0)
-    MAKE_CASE(ARMISD::BCC_i64)
-    MAKE_CASE(ARMISD::FMSTAT)
-    MAKE_CASE(ARMISD::CMOV)
-    MAKE_CASE(ARMISD::SSAT)
-    MAKE_CASE(ARMISD::USAT)
-    MAKE_CASE(ARMISD::ASRL)
-    MAKE_CASE(ARMISD::LSRL)
-    MAKE_CASE(ARMISD::LSLL)
-    MAKE_CASE(ARMISD::LSLS)
-    MAKE_CASE(ARMISD::LSRS1)
-    MAKE_CASE(ARMISD::ASRS1)
-    MAKE_CASE(ARMISD::RRX)
-    MAKE_CASE(ARMISD::ADDC)
-    MAKE_CASE(ARMISD::ADDE)
-    MAKE_CASE(ARMISD::SUBC)
-    MAKE_CASE(ARMISD::SUBE)
-    MAKE_CASE(ARMISD::VMOVRRD)
-    MAKE_CASE(ARMISD::VMOVDRR)
-    MAKE_CASE(ARMISD::VMOVhr)
-    MAKE_CASE(ARMISD::VMOVrh)
-    MAKE_CASE(ARMISD::VMOVSR)
-    MAKE_CASE(ARMISD::EH_SJLJ_SETJMP)
-    MAKE_CASE(ARMISD::EH_SJLJ_LONGJMP)
-    MAKE_CASE(ARMISD::EH_SJLJ_SETUP_DISPATCH)
-    MAKE_CASE(ARMISD::TC_RETURN)
-    MAKE_CASE(ARMISD::THREAD_POINTER)
-    MAKE_CASE(ARMISD::DYN_ALLOC)
-    MAKE_CASE(ARMISD::MEMBARRIER_MCR)
-    MAKE_CASE(ARMISD::PRELOAD)
-    MAKE_CASE(ARMISD::LDRD)
-    MAKE_CASE(ARMISD::STRD)
-    MAKE_CASE(ARMISD::WIN__CHKSTK)
-    MAKE_CASE(ARMISD::WIN__DBZCHK)
-    MAKE_CASE(ARMISD::PREDICATE_CAST)
-    MAKE_CASE(ARMISD::VECTOR_REG_CAST)
-    MAKE_CASE(ARMISD::MVESEXT)
-    MAKE_CASE(ARMISD::MVEZEXT)
-    MAKE_CASE(ARMISD::MVETRUNC)
-    MAKE_CASE(ARMISD::VCMP)
-    MAKE_CASE(ARMISD::VCMPZ)
-    MAKE_CASE(ARMISD::VTST)
-    MAKE_CASE(ARMISD::VSHLs)
-    MAKE_CASE(ARMISD::VSHLu)
-    MAKE_CASE(ARMISD::VSHLIMM)
-    MAKE_CASE(ARMISD::VSHRsIMM)
-    MAKE_CASE(ARMISD::VSHRuIMM)
-    MAKE_CASE(ARMISD::VRSHRsIMM)
-    MAKE_CASE(ARMISD::VRSHRuIMM)
-    MAKE_CASE(ARMISD::VRSHRNIMM)
-    MAKE_CASE(ARMISD::VQSHLsIMM)
-    MAKE_CASE(ARMISD::VQSHLuIMM)
-    MAKE_CASE(ARMISD::VQSHLsuIMM)
-    MAKE_CASE(ARMISD::VQSHRNsIMM)
-    MAKE_CASE(ARMISD::VQSHRNuIMM)
-    MAKE_CASE(ARMISD::VQSHRNsuIMM)
-    MAKE_CASE(ARMISD::VQRSHRNsIMM)
-    MAKE_CASE(ARMISD::VQRSHRNuIMM)
-    MAKE_CASE(ARMISD::VQRSHRNsuIMM)
-    MAKE_CASE(ARMISD::VSLIIMM)
-    MAKE_CASE(ARMISD::VSRIIMM)
-    MAKE_CASE(ARMISD::VGETLANEu)
-    MAKE_CASE(ARMISD::VGETLANEs)
-    MAKE_CASE(ARMISD::VMOVIMM)
-    MAKE_CASE(ARMISD::VMVNIMM)
-    MAKE_CASE(ARMISD::VMOVFPIMM)
-    MAKE_CASE(ARMISD::VDUP)
-    MAKE_CASE(ARMISD::VDUPLANE)
-    MAKE_CASE(ARMISD::VEXT)
-    MAKE_CASE(ARMISD::VREV64)
-    MAKE_CASE(ARMISD::VREV32)
-    MAKE_CASE(ARMISD::VREV16)
-    MAKE_CASE(ARMISD::VZIP)
-    MAKE_CASE(ARMISD::VUZP)
-    MAKE_CASE(ARMISD::VTRN)
-    MAKE_CASE(ARMISD::VTBL1)
-    MAKE_CASE(ARMISD::VTBL2)
-    MAKE_CASE(ARMISD::VMOVN)
-    MAKE_CASE(ARMISD::VQMOVNs)
-    MAKE_CASE(ARMISD::VQMOVNu)
-    MAKE_CASE(ARMISD::VCVTN)
-    MAKE_CASE(ARMISD::VCVTL)
-    MAKE_CASE(ARMISD::VIDUP)
-    MAKE_CASE(ARMISD::VMULLs)
-    MAKE_CASE(ARMISD::VMULLu)
-    MAKE_CASE(ARMISD::VQDMULH)
-    MAKE_CASE(ARMISD::VADDVs)
-    MAKE_CASE(ARMISD::VADDVu)
-    MAKE_CASE(ARMISD::VADDVps)
-    MAKE_CASE(ARMISD::VADDVpu)
-    MAKE_CASE(ARMISD::VADDLVs)
-    MAKE_CASE(ARMISD::VADDLVu)
-    MAKE_CASE(ARMISD::VADDLVAs)
-    MAKE_CASE(ARMISD::VADDLVAu)
-    MAKE_CASE(ARMISD::VADDLVps)
-    MAKE_CASE(ARMISD::VADDLVpu)
-    MAKE_CASE(ARMISD::VADDLVAps)
-    MAKE_CASE(ARMISD::VADDLVApu)
-    MAKE_CASE(ARMISD::VMLAVs)
-    MAKE_CASE(ARMISD::VMLAVu)
-    MAKE_CASE(ARMISD::VMLAVps)
-    MAKE_CASE(ARMISD::VMLAVpu)
-    MAKE_CASE(ARMISD::VMLALVs)
-    MAKE_CASE(ARMISD::VMLALVu)
-    MAKE_CASE(ARMISD::VMLALVps)
-    MAKE_CASE(ARMISD::VMLALVpu)
-    MAKE_CASE(ARMISD::VMLALVAs)
-    MAKE_CASE(ARMISD::VMLALVAu)
-    MAKE_CASE(ARMISD::VMLALVAps)
-    MAKE_CASE(ARMISD::VMLALVApu)
-    MAKE_CASE(ARMISD::VMINVu)
-    MAKE_CASE(ARMISD::VMINVs)
-    MAKE_CASE(ARMISD::VMAXVu)
-    MAKE_CASE(ARMISD::VMAXVs)
-    MAKE_CASE(ARMISD::UMAAL)
-    MAKE_CASE(ARMISD::UMLAL)
-    MAKE_CASE(ARMISD::SMLAL)
-    MAKE_CASE(ARMISD::SMLALBB)
-    MAKE_CASE(ARMISD::SMLALBT)
-    MAKE_CASE(ARMISD::SMLALTB)
-    MAKE_CASE(ARMISD::SMLALTT)
-    MAKE_CASE(ARMISD::SMULWB)
-    MAKE_CASE(ARMISD::SMULWT)
-    MAKE_CASE(ARMISD::SMLALD)
-    MAKE_CASE(ARMISD::SMLALDX)
-    MAKE_CASE(ARMISD::SMLSLD)
-    MAKE_CASE(ARMISD::SMLSLDX)
-    MAKE_CASE(ARMISD::SMMLAR)
-    MAKE_CASE(ARMISD::SMMLSR)
-    MAKE_CASE(ARMISD::QADD16b)
-    MAKE_CASE(ARMISD::QSUB16b)
-    MAKE_CASE(ARMISD::QADD8b)
-    MAKE_CASE(ARMISD::QSUB8b)
-    MAKE_CASE(ARMISD::UQADD16b)
-    MAKE_CASE(ARMISD::UQSUB16b)
-    MAKE_CASE(ARMISD::UQADD8b)
-    MAKE_CASE(ARMISD::UQSUB8b)
-    MAKE_CASE(ARMISD::BUILD_VECTOR)
-    MAKE_CASE(ARMISD::BFI)
-    MAKE_CASE(ARMISD::VORRIMM)
-    MAKE_CASE(ARMISD::VBICIMM)
-    MAKE_CASE(ARMISD::VBSP)
-    MAKE_CASE(ARMISD::MEMCPY)
-    MAKE_CASE(ARMISD::VLD1DUP)
-    MAKE_CASE(ARMISD::VLD2DUP)
-    MAKE_CASE(ARMISD::VLD3DUP)
-    MAKE_CASE(ARMISD::VLD4DUP)
-    MAKE_CASE(ARMISD::VLD1_UPD)
-    MAKE_CASE(ARMISD::VLD2_UPD)
-    MAKE_CASE(ARMISD::VLD3_UPD)
-    MAKE_CASE(ARMISD::VLD4_UPD)
-    MAKE_CASE(ARMISD::VLD1x2_UPD)
-    MAKE_CASE(ARMISD::VLD1x3_UPD)
-    MAKE_CASE(ARMISD::VLD1x4_UPD)
-    MAKE_CASE(ARMISD::VLD2LN_UPD)
-    MAKE_CASE(ARMISD::VLD3LN_UPD)
-    MAKE_CASE(ARMISD::VLD4LN_UPD)
-    MAKE_CASE(ARMISD::VLD1DUP_UPD)
-    MAKE_CASE(ARMISD::VLD2DUP_UPD)
-    MAKE_CASE(ARMISD::VLD3DUP_UPD)
-    MAKE_CASE(ARMISD::VLD4DUP_UPD)
-    MAKE_CASE(ARMISD::VST1_UPD)
-    MAKE_CASE(ARMISD::VST2_UPD)
-    MAKE_CASE(ARMISD::VST3_UPD)
-    MAKE_CASE(ARMISD::VST4_UPD)
-    MAKE_CASE(ARMISD::VST1x2_UPD)
-    MAKE_CASE(ARMISD::VST1x3_UPD)
-    MAKE_CASE(ARMISD::VST1x4_UPD)
-    MAKE_CASE(ARMISD::VST2LN_UPD)
-    MAKE_CASE(ARMISD::VST3LN_UPD)
-    MAKE_CASE(ARMISD::VST4LN_UPD)
-    MAKE_CASE(ARMISD::WLS)
-    MAKE_CASE(ARMISD::WLSSETUP)
-    MAKE_CASE(ARMISD::LE)
-    MAKE_CASE(ARMISD::LOOP_DEC)
-    MAKE_CASE(ARMISD::CSINV)
-    MAKE_CASE(ARMISD::CSNEG)
-    MAKE_CASE(ARMISD::CSINC)
-    MAKE_CASE(ARMISD::MEMCPYLOOP)
-    MAKE_CASE(ARMISD::MEMSETLOOP)
-#undef MAKE_CASE
-  }
-  return nullptr;
-}
-
 EVT ARMTargetLowering::getSetCCResultType(const DataLayout &DL, LLVMContext &,
                                           EVT VT) const {
   if (!VT.isVector())
@@ -3444,8 +3230,8 @@ ARMTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
     return LowerInterruptReturn(RetOps, dl, DAG);
   }
 
-  ARMISD::NodeType RetNode = AFI->isCmseNSEntryFunction() ? ARMISD::SERET_GLUE :
-                                                            ARMISD::RET_GLUE;
+  unsigned RetNode =
+      AFI->isCmseNSEntryFunction() ? ARMISD::SERET_GLUE : ARMISD::RET_GLUE;
   return DAG.getNode(RetNode, dl, MVT::Other, RetOps);
 }
 
@@ -4948,7 +4734,7 @@ SDValue ARMTargetLowering::getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
     }
   }
 
-  ARMISD::NodeType CompareType;
+  unsigned CompareType;
   switch (CondCode) {
   default:
     CompareType = ARMISD::CMP;
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h
index cd663cebeab01f..e7c45b437bd6d9 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.h
+++ b/llvm/lib/Target/ARM/ARMISelLowering.h
@@ -50,319 +50,6 @@ class TargetMachine;
 class TargetRegisterInfo;
 class VectorType;
 
-  namespace ARMISD {
-
-  // ARM Specific DAG Nodes
-  enum NodeType : unsigned {
-    // Start the numbering where the builtin ops and target ops leave off.
-    FIRST_NUMBER = ISD::BUILTIN_OP_END,
-
-    Wrapper,    // Wrapper - A wrapper node for TargetConstantPool,
-                // TargetExternalSymbol, and TargetGlobalAddress.
-    WrapperPIC, // WrapperPIC - A wrapper node for TargetGlobalAddress in
-                // PIC mode.
-    WrapperJT,  // WrapperJT - A wrapper node for TargetJumpTable
-
-    // Add pseudo op to model memcpy for struct byval.
-    COPY_STRUCT_BYVAL,
-
-    CALL,        // Function call.
-    CALL_PRED,   // Function call that's predicable.
-    CALL_NOLINK, // Function call with branch not branch-and-link.
-    tSECALL,     // CMSE non-secure function call.
-    t2CALL_BTI,  // Thumb function call followed by BTI instruction.
-    BRCOND,      // Conditional branch.
-    BR_JT,       // Jumptable branch.
-    BR2_JT,      // Jumptable branch (2 level - jumptable entry is a jump).
-    RET_GLUE,    // Return with a flag operand.
-    SERET_GLUE,  // CMSE Entry function return with a flag operand.
-    INTRET_GLUE, // Interrupt return with an LR-offset and a flag operand.
-
-    PIC_ADD, // Add with a PC operand and a PIC label.
-
-    ASRL, // MVE long arithmetic shift right.
-    LSRL, // MVE long shift right.
-    LSLL, // MVE long shift left.
-
-    CMP,      // ARM compare instructions.
-    CMN,      // ARM CMN instructions.
-    CMPZ,     // ARM compare that sets only Z flag.
-    CMPFP,    // ARM VFP compare instruction, sets FPSCR.
-    CMPFPE,   // ARM VFP signalling compare instruction, sets FPSCR.
-    CMPFPw0,  // ARM VFP compare against zero instruction, sets FPSCR.
-    CMPFPEw0, // ARM VFP signalling compare against zero instruction, sets
-              // FPSCR.
-    FMSTAT,   // ARM fmstat instruction.
-
-    CMOV, // ARM conditional move instructions.
-
-    SSAT, // Signed saturation
-    USAT, // Unsigned saturation
-
-    BCC_i64,
-
-    LSLS,  // Flag-setting shift left.
-    LSRS1, // Flag-setting logical shift right by one bit.
-    ASRS1, // Flag-setting arithmetic shift right by one bit.
-    RRX,   // Shift right one bit with carry in.
-
-    ADDC, // Add with carry
-    ADDE, // Add using carry
-    SUBC, // Sub with carry
-    SUBE, // Sub using carry
-
-    VMOVRRD, // double to two gprs.
-    VMOVDRR, // Two gprs to double.
-    VMOVSR,  // move gpr to single, used for f32 literal constructed in a gpr
-
-    EH_SJLJ_SETJMP,         // SjLj exception handling setjmp.
-    EH_SJLJ_LONGJMP,        // SjLj exception handling longjmp.
-    EH_SJLJ_SETUP_DISPATCH, // SjLj exception handling setup_dispatch.
-
-    TC_RETURN, // Tail call return pseudo.
-
-    THREAD_POINTER,
-
-    DYN_ALLOC, // Dynamic allocation on the stack.
-
-    MEMBARRIER_MCR, // Memory barrier (MCR)
-
-    PRELOAD, // Preload
-
-    WIN__CHKSTK, // Windows' __chkstk call to do stack probing.
-    WIN__DBZCHK, // Windows' divide by zero check
-
-    WLS, // Low-overhead loops, While Loop Start branch. See t2WhileLoopStart
-    WLSSETUP, // Setup for the iteration count of a WLS. See t2WhileLoopSetup.
-    LOOP_DEC, // Really a part of LE, performs the sub
-    LE,       // Low-overhead loops, Loop End
-
-    PREDICATE_CAST,  // Predicate cast for MVE i1 types
-    VECTOR_REG_CAST, // Reinterpret the current contents of a vector register
-
-    MVESEXT,  // Legalization aids for extending a vector into two/four vectors.
-    MVEZEXT,  //  or truncating two/four vectors into one. Eventually becomes
-    MVETRUNC, //  stack store/load sequence, if not optimized to anything else.
-
-    VCMP,  // Vector compare.
-    VCMPZ, // Vector compare to zero.
-    VTST,  // Vector test bits.
-
-    // Vector shift by vector
-    VSHLs, // ...left/right by signed
-    VSHLu, // ...left/right by unsigned
-
-    // Vector shift by immediate:
-    VSHLIMM,  // ...left
-    VSHRsIMM, // ...right (signed)
-    VSHRuIMM, // ...right (unsigned)
-
-    // Vector rounding shift by immediate:
-    VRSHRsIMM, // ...right (signed)
-    VRSHRuIMM, // ...right (unsigned)
-    VRSHRNIMM, // ...right narrow
-
-    // Vector saturating shift by immediate:
-    VQSHLsIMM,   // ...left (signed)
-    VQSHLuIMM,   // ...left (unsigned)
-    VQSHLsuIMM,  // ...left (signed to unsigned)
-    VQSHRNsIMM,  // ...right narrow (signed)
-    VQSHRNuIMM,  // ...right narrow (unsigned)
-    VQSHRNsuIMM, // ...right narrow (signed to unsigned)
-
-    // Vector saturating rounding shift by immediate:
-    VQRSHRNsIMM,  // ...right narrow (signed)
-    VQRSHRNuIMM,  // ...right narrow (unsigned)
-    VQRSHRNsuIMM, // ...right narrow (signed to unsigned)
-
-    // Vector shift and insert:
-    VSLIIMM, // ...left
-    VSRIIMM, // ...right
-
-    // Vector get lane (VMOV scalar to ARM core register)
-    // (These are used for 8- and 16-bit element types only.)
-    VGETLANEu, // zero-extend vector extract element
-    VGETLANEs, // sign-extend vector extract element
-
-    // Vector move immediate and move negated immediate:
-    VMOVIMM,
-    VMVNIMM,
-
-    // Vector move f32 immediate:
-    VMOVFPIMM,
-
-    // Move H <-> R, clearing top 16 bits
-    VMOVrh,
-    VMOVhr,
-
-    // Vector duplicate:
-    VDUP,
-    VDUPLANE,
-
-    // Vector shuffles:
-    VEXT,   // extract
-    VREV64, // reverse elements within 64-bit doublewords
-    VREV32, // reverse elements within 32-bit words
-    VREV16, // reverse elements within 16-bit halfwords
-    VZIP,   // zip (interleave)
-    VUZP,   // unzip (deinterleave)
-    VTRN,   // transpose
-    VTBL1,  // 1-register shuffle with mask
-    VTBL2,  // 2-register shuffle with mask
-    VMOVN,  // MVE vmovn
-
-    // MVE Saturating truncates
-    VQMOVNs, // Vector (V) Saturating (Q) Move and Narrow (N), signed (s)
-    VQMOVNu, // Vector (V) Saturating (Q) Move and Narrow (N), unsigned (u)
-
-    // MVE float <> half converts
-    VCVTN, // MVE vcvt f32 -> f16, truncating into either the bottom or top
-           // lanes
-    VCVTL, // MVE vcvt f16 -> f32, extending from either the bottom or top lanes
-
-    // MVE VIDUP instruction, taking a start value and increment.
-    VIDUP,
-
-    // Vector multiply long:
-    VMULLs, // ...signed
-    VMULLu, // ...unsigned
-
-    VQDMULH, // MVE vqdmulh instruction
-
-    // MVE reductions
-    VADDVs,  // sign- or zero-extend the elements of a vector to i32,
-    VADDVu,  //   add them all together, and return an i32 of their sum
-    VADDVps, // Same as VADDV[su] but with a v4i1 predicate mask
-    VADDVpu,
-    VADDLVs,  // sign- or zero-extend elements to i64 and sum, returning
-    VADDLVu,  //   the low and high 32-bit halves of the sum
-    VADDLVAs, // Same as VADDLV[su] but also add an input accumulator
-    VADDLVAu, //   provided as low and high halves
-    VADDLVps, // Same as VADDLV[su] but with a v4i1 predicate mask
-    VADDLVpu,
-    VADDLVAps, // Same as VADDLVp[su] but with a v4i1 predicate mask
-    VADDLVApu,
-    VMLAVs, // sign- or zero-extend the elements of two vectors to i32, multiply
-    VMLAVu, //   them and add the results together, returning an i32 of the sum
-    VMLAVps, // Same as VMLAV[su] with a v4i1 predicate mask
-    VMLAVpu,
-    VMLALVs,  // Same as VMLAV but with i64, returning the low and
-    VMLALVu,  //   high 32-bit halves of the sum
-    VMLALVps, // Same as VMLALV[su] with a v4i1 predicate mask
-    VMLALVpu,
-    VMLALVAs,  // Same as VMLALV but also add an input accumulator
-    VMLALVAu,  //   provided as low and high halves
-    VMLALVAps, // Same as VMLALVA[su] with a v4i1 predicate mask
-    VMLALVApu,
-    VMINVu, // Find minimum unsigned value of a vector and register
-    VMINVs, // Find minimum signed value of a vector and register
-    VMAXVu, // Find maximum unsigned value of a vector and register
-    VMAXVs, // Find maximum signed value of a vector and register
-
-    SMULWB,  // Signed multiply word by half word, bottom
-    SMULWT,  // Signed multiply word by half word, top
-    UMLAL,   // 64bit Unsigned Accumulate Multiply
-    SMLAL,   // 64bit Signed Accumulate Multiply
-    UMAAL,   // 64-bit Unsigned Accumulate Accumulate Multiply
-    SMLALBB, // 64-bit signed accumulate multiply bottom, bottom 16
-    SMLALBT, // 64-bit signed accumulate multiply bottom, top 16
-    SMLALTB, // 64-bit signed accumulate multiply top, bottom 16
-    SMLALTT, // 64-bit signed accumulate multiply top, top 16
-    SMLALD,  // Signed multiply accumulate long dual
-    SMLALDX, // Signed multiply accumulate long dual exchange
-    SMLSLD,  // Signed multiply subtract long dual
-    SMLSLDX, // Signed multiply subtract long dual exchange
-    SMMLAR,  // Signed multiply long, round and add
-    SMMLSR,  // Signed multiply long, subtract and round
-
-    // Single Lane QADD8 and QADD16. Only the bottom lane. That's what the b
-    // stands for.
-    QADD8b,
-    QSUB8b,
-    QADD16b,
-    QSUB16b,
-    UQADD8b,
-    UQSUB8b,
-    UQADD16b,
-    UQSUB16b,
-
-    // Operands of the standard BUILD_VECTOR node are not legalized, which
-    // is fine if BUILD_VECTORs are always lowered to shuffles or other
-    // operations, but for ARM some BUILD_VECTORs are legal as-is and their
-    // operands need to be legalized.  Define an ARM-specific version of
-    // BUILD_VECTOR for this purpose.
-    BUILD_VECTOR,
-
-    // Bit-field insert
-    BFI,
-
-    // Vector OR with immediate
-    VORRIMM,
-    // Vector AND with NOT of immediate
-    VBICIMM,
-
-    // Pseudo vector bitwise select
-    VBSP,
-
-    // Pseudo-instruction representing a memory copy using ldm/stm
-    // instructions.
-    MEMCPY,
-
-    // Pseudo-instruction representing a memory copy using a tail predicated
-    // loop
-    MEMCPYLOOP,
-    // Pseudo-instruction representing a memset using a tail predicated
-    // loop
-    MEMSETLOOP,
-
-    // V8.1MMainline condition select
-    CSINV, // Conditional select invert.
-    CSNEG, // Conditional select negate.
-    CSINC, // Conditional select increment.
-
-    // Vector load N-element structure to all lanes:
-    FIRST_MEMORY_OPCODE,
-    VLD1DUP = FIRST_MEMORY_OPCODE,
-    VLD2DUP,
-    VLD3DUP,
-    VLD4DUP,
-
-    // NEON loads with post-increment base updates:
-    VLD1_UPD,
-    VLD2_UPD,
-    VLD3_UPD,
-    VLD4_UPD,
-    VLD2LN_UPD,
-    VLD3LN_UPD,
-    VLD4LN_UPD,
-    VLD1DUP_UPD,
-    VLD2DUP_UPD,
-    VLD3DUP_UPD,
-    VLD4DUP_UPD,
-    VLD1x2_UPD,
-    VLD1x3_UPD,
-    VLD1x4_UPD,
-
-    // NEON stores with post-increment base updates:
-    VST1_UPD,
-    VST2_UPD,
-    VST3_UPD,
-    VST4_UPD,
-    VST2LN_UPD,
-    VST3LN_UPD,
-    VST4LN_UPD,
-    VST1x2_UPD,
-    VST1x3_UPD,
-    VST1x4_UPD,
-
-    // Load/Store of dual registers
-    LDRD,
-    STRD,
-    LAST_MEMORY_OPCODE = STRD,
-  };
-
-  } // end namespace ARMISD
-
   namespace ARM {
   /// Possible values of current rounding mode, which is specified in bits
   /// 23:22 of FPSCR.
@@ -424,8 +111,6 @@ class VectorType;
     void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,
                             SelectionDAG &DAG) const override;
 
-    const char *getTargetNodeName(unsigned Opcode) const override;
-
     bool isSelectSupported(SelectSupportKind Kind) const override {
       // ARM does not support scalar condition selects on vectors.
       return (Kind != ScalarCondVectorVal);
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index 1cb6589184b603..b8ccd12b7c72b5 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -40,7 +40,7 @@ def SDT_ARMCMov : SDTypeProfile<1, 4, [
   SDTCisVT<4, FlagsVT>,    // in flags
 ]>;
 
-def SDT_ARMBrcond : SDTypeProfile<0, 2, [
+def SDT_ARMBrcond : SDTypeProfile<0, 3, [
   SDTCisVT<0, OtherVT>,    // target basic block
   SDTCisVT<1, CondCodeVT>, // condition code
   SDTCisVT<2, FlagsVT>,    // in flags
diff --git a/llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp b/llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp
index 24972636adb960..082308623674b9 100644
--- a/llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp
@@ -10,9 +10,14 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "ARMSelectionDAGInfo.h"
 #include "ARMTargetTransformInfo.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/Support/CommandLine.h"
+
+#define GET_SDNODE_DESC
+#include "ARMGenSDNodeInfo.inc"
+
 using namespace llvm;
 
 #define DEBUG_TYPE "arm-selectiondag-info"
@@ -30,11 +35,114 @@ cl::opt<TPLoop::MemTransfer> EnableMemtransferTPLoop(
                           "Allow (may be subject to certain conditions) "
                           "conversion of memcpy to TP loop.")));
 
+ARMSelectionDAGInfo::ARMSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(ARMGenSDNodeInfo) {}
+
+const char *ARMSelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
+#define MAKE_CASE(V)                                                           \
+  case V:                                                                      \
+    return #V;
+
+  // These nodes don't have corresponding entries in *.td files yet.
+  switch (static_cast<ARMISD::NodeType>(Opcode)) {
+    MAKE_CASE(ARMISD::DYN_ALLOC)
+    MAKE_CASE(ARMISD::MVESEXT)
+    MAKE_CASE(ARMISD::MVEZEXT)
+    MAKE_CASE(ARMISD::MVETRUNC)
+    MAKE_CASE(ARMISD::UMAAL)
+    MAKE_CASE(ARMISD::UMLAL)
+    MAKE_CASE(ARMISD::SMLAL)
+    MAKE_CASE(ARMISD::BUILD_VECTOR)
+    MAKE_CASE(ARMISD::VLD1DUP)
+    MAKE_CASE(ARMISD::VLD2DUP)
+    MAKE_CASE(ARMISD::VLD3DUP)
+    MAKE_CASE(ARMISD::VLD4DUP)
+    MAKE_CASE(ARMISD::VLD1_UPD)
+    MAKE_CASE(ARMISD::VLD2_UPD)
+    MAKE_CASE(ARMISD::VLD3_UPD)
+    MAKE_CASE(ARMISD::VLD4_UPD)
+    MAKE_CASE(ARMISD::VLD1x2_UPD)
+    MAKE_CASE(ARMISD::VLD1x3_UPD)
+    MAKE_CASE(ARMISD::VLD1x4_UPD)
+    MAKE_CASE(ARMISD::VLD2LN_UPD)
+    MAKE_CASE(ARMISD::VLD3LN_UPD)
+    MAKE_CASE(ARMISD::VLD4LN_UPD)
+    MAKE_CASE(ARMISD::VLD1DUP_UPD)
+    MAKE_CASE(ARMISD::VLD2DUP_UPD)
+    MAKE_CASE(ARMISD::VLD3DUP_UPD)
+    MAKE_CASE(ARMISD::VLD4DUP_UPD)
+    MAKE_CASE(ARMISD::VST1_UPD)
+    MAKE_CASE(ARMISD::VST3_UPD)
+    MAKE_CASE(ARMISD::VST1x2_UPD)
+    MAKE_CASE(ARMISD::VST1x3_UPD)
+    MAKE_CASE(ARMISD::VST1x4_UPD)
+    MAKE_CASE(ARMISD::VST2LN_UPD)
+    MAKE_CASE(ARMISD::VST3LN_UPD)
+    MAKE_CASE(ARMISD::VST4LN_UPD)
+    MAKE_CASE(ARMISD::WLS)
+    MAKE_CASE(ARMISD::WLSSETUP)
+    MAKE_CASE(ARMISD::LE)
+    MAKE_CASE(ARMISD::LOOP_DEC)
+  }
+#undef MAKE_CASE
+
+  return SelectionDAGGenTargetInfo::getTargetNodeName(Opcode);
+}
+
 bool ARMSelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
-  if (Opcode >= ARMISD::FIRST_MEMORY_OPCODE &&
-      Opcode <= ARMISD::LAST_MEMORY_OPCODE)
+  // These nodes don't have corresponding entries in *.td files yet.
+  switch (static_cast<ARMISD::NodeType>(Opcode)) {
+  default:
+    break;
+  case ARMISD::VLD1DUP:
+  case ARMISD::VLD2DUP:
+  case ARMISD::VLD3DUP:
+  case ARMISD::VLD4DUP:
+  case ARMISD::VLD1_UPD:
+  case ARMISD::VLD2_UPD:
+  case ARMISD::VLD3_UPD:
+  case ARMISD::VLD4_UPD:
+  case ARMISD::VLD2LN_UPD:
+  case ARMISD::VLD3LN_UPD:
+  case ARMISD::VLD4LN_UPD:
+  case ARMISD::VLD1DUP_UPD:
+  case ARMISD::VLD2DUP_UPD:
+  case ARMISD::VLD3DUP_UPD:
+  case ARMISD::VLD4DUP_UPD:
+  case ARMISD::VLD1x2_UPD:
+  case ARMISD::VLD1x3_UPD:
+  case ARMISD::VLD1x4_UPD:
+  case ARMISD::VST1_UPD:
+  case ARMISD::VST3_UPD:
+  case ARMISD::VST2LN_UPD:
+  case ARMISD::VST3LN_UPD:
+  case ARMISD::VST4LN_UPD:
+  case ARMISD::VST1x2_UPD:
+  case ARMISD::VST1x3_UPD:
+  case ARMISD::VST1x4_UPD:
     return true;
-  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+  }
+
+  return SelectionDAGGenTargetInfo::isTargetMemoryOpcode(Opcode);
+}
+
+void ARMSelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
+                                           const SDNode *N) const {
+  switch (N->getOpcode()) {
+  default:
+    break;
+  case ARMISD::WIN__DBZCHK:
+    // invalid number of results; expected 2, got 1
+  case ARMISD::WIN__CHKSTK:
+    // invalid number of results; expected 1, got 2
+  case ARMISD::COPY_STRUCT_BYVAL:
+    // invalid number of operands; expected 6, got 5
+  case ARMISD::MEMCPY:
+    // invalid number of operands; expected 5, got 4
+    return;
+  }
+
+  SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
 }
 
 // Emit, if possible, a specialized version of the given Libcall. Typically this
diff --git a/llvm/lib/Target/ARM/ARMSelectionDAGInfo.h b/llvm/lib/Target/ARM/ARMSelectionDAGInfo.h
index d68150e66567ce..3bc3ea999e7a37 100644
--- a/llvm/lib/Target/ARM/ARMSelectionDAGInfo.h
+++ b/llvm/lib/Target/ARM/ARMSelectionDAGInfo.h
@@ -17,7 +17,69 @@
 #include "llvm/CodeGen/RuntimeLibcallUtil.h"
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 
+#define GET_SDNODE_ENUM
+#include "ARMGenSDNodeInfo.inc"
+
 namespace llvm {
+namespace ARMISD {
+
+enum NodeType : unsigned {
+  DYN_ALLOC = GENERATED_OPCODE_END, // Dynamic allocation on the stack.
+
+  WLS,      // Low-overhead loops, While Loop Start branch. See t2WhileLoopStart
+  WLSSETUP, // Setup for the iteration count of a WLS. See t2WhileLoopSetup.
+  LOOP_DEC, // Really a part of LE, performs the sub
+  LE,       // Low-overhead loops, Loop End
+
+  MVESEXT,  // Legalization aids for extending a vector into two/four vectors.
+  MVEZEXT,  //  or truncating two/four vectors into one. Eventually becomes
+  MVETRUNC, //  stack store/load sequence, if not optimized to anything else.
+
+  UMLAL, // 64bit Unsigned Accumulate Multiply
+  SMLAL, // 64bit Signed Accumulate Multiply
+  UMAAL, // 64-bit Unsigned Accumulate Accumulate Multiply
+
+  // Operands of the standard BUILD_VECTOR node are not legalized, which
+  // is fine if BUILD_VECTORs are always lowered to shuffles or other
+  // operations, but for ARM some BUILD_VECTORs are legal as-is and their
+  // operands need to be legalized.  Define an ARM-specific version of
+  // BUILD_VECTOR for this purpose.
+  BUILD_VECTOR,
+
+  // Vector load N-element structure to all lanes:
+  VLD1DUP,
+  VLD2DUP,
+  VLD3DUP,
+  VLD4DUP,
+
+  // NEON loads with post-increment base updates:
+  VLD1_UPD,
+  VLD2_UPD,
+  VLD3_UPD,
+  VLD4_UPD,
+  VLD2LN_UPD,
+  VLD3LN_UPD,
+  VLD4LN_UPD,
+  VLD1DUP_UPD,
+  VLD2DUP_UPD,
+  VLD3DUP_UPD,
+  VLD4DUP_UPD,
+  VLD1x2_UPD,
+  VLD1x3_UPD,
+  VLD1x4_UPD,
+
+  // NEON stores with post-increment base updates:
+  VST1_UPD,
+  VST3_UPD,
+  VST2LN_UPD,
+  VST3LN_UPD,
+  VST4LN_UPD,
+  VST1x2_UPD,
+  VST1x3_UPD,
+  VST1x4_UPD,
+};
+
+} // namespace ARMISD
 
 namespace ARM_AM {
   static inline ShiftOpc getShiftOpcForNode(unsigned Opcode) {
@@ -35,10 +97,17 @@ namespace ARM_AM {
   }
 }  // end namespace ARM_AM
 
-class ARMSelectionDAGInfo : public SelectionDAGTargetInfo {
+class ARMSelectionDAGInfo : public SelectionDAGGenTargetInfo {
 public:
+  ARMSelectionDAGInfo();
+
+  const char *getTargetNodeName(unsigned Opcode) const override;
+
   bool isTargetMemoryOpcode(unsigned Opcode) const override;
 
+  void verifyTargetNode(const SelectionDAG &DAG,
+                        const SDNode *N) const override;
+
   SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &dl,
                                   SDValue Chain, SDValue Dst, SDValue Src,
                                   SDValue Size, Align Alignment,
diff --git a/llvm/lib/Target/ARM/CMakeLists.txt b/llvm/lib/Target/ARM/CMakeLists.txt
index a39629bd8aeb02..d99368e1d3b2b1 100644
--- a/llvm/lib/Target/ARM/CMakeLists.txt
+++ b/llvm/lib/Target/ARM/CMakeLists.txt
@@ -14,6 +14,7 @@ tablegen(LLVM ARMGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM ARMGenMCPseudoLowering.inc -gen-pseudo-lowering)
 tablegen(LLVM ARMGenRegisterBank.inc -gen-register-bank)
 tablegen(LLVM ARMGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM ARMGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM ARMGenSubtargetInfo.inc -gen-subtarget)
 tablegen(LLVM ARMGenSystemRegister.inc -gen-searchable-tables)
 

>From de0c0c8663e979895103cbdefe31dd123382cb5f Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 03:11:05 +0300
Subject: [PATCH 08/27] AVR

---
 llvm/lib/Target/AVR/AVRISelLowering.cpp     | 34 ------------
 llvm/lib/Target/AVR/AVRISelLowering.h       | 60 ---------------------
 llvm/lib/Target/AVR/AVRSelectionDAGInfo.cpp | 19 +++++++
 llvm/lib/Target/AVR/AVRSelectionDAGInfo.h   |  8 ++-
 llvm/lib/Target/AVR/CMakeLists.txt          |  2 +
 5 files changed, 28 insertions(+), 95 deletions(-)
 create mode 100644 llvm/lib/Target/AVR/AVRSelectionDAGInfo.cpp

diff --git a/llvm/lib/Target/AVR/AVRISelLowering.cpp b/llvm/lib/Target/AVR/AVRISelLowering.cpp
index 07c79f6f227b02..ad883355ee4163 100644
--- a/llvm/lib/Target/AVR/AVRISelLowering.cpp
+++ b/llvm/lib/Target/AVR/AVRISelLowering.cpp
@@ -220,40 +220,6 @@ AVRTargetLowering::AVRTargetLowering(const AVRTargetMachine &TM,
   setMinimumJumpTableEntries(UINT_MAX);
 }
 
-const char *AVRTargetLowering::getTargetNodeName(unsigned Opcode) const {
-#define NODE(name)                                                             \
-  case AVRISD::name:                                                           \
-    return #name
-
-  switch (Opcode) {
-  default:
-    return nullptr;
-    NODE(RET_GLUE);
-    NODE(RETI_GLUE);
-    NODE(CALL);
-    NODE(WRAPPER);
-    NODE(LSL);
-    NODE(LSLW);
-    NODE(LSR);
-    NODE(LSRW);
-    NODE(ROL);
-    NODE(ROR);
-    NODE(ASR);
-    NODE(ASRW);
-    NODE(LSLLOOP);
-    NODE(LSRLOOP);
-    NODE(ROLLOOP);
-    NODE(RORLOOP);
-    NODE(ASRLOOP);
-    NODE(BRCOND);
-    NODE(CMP);
-    NODE(CMPC);
-    NODE(TST);
-    NODE(SELECT_CC);
-#undef NODE
-  }
-}
-
 EVT AVRTargetLowering::getSetCCResultType(const DataLayout &DL, LLVMContext &,
                                           EVT VT) const {
   assert(!VT.isVector() && "No AVR SetCC type for vectors!");
diff --git a/llvm/lib/Target/AVR/AVRISelLowering.h b/llvm/lib/Target/AVR/AVRISelLowering.h
index f6057959345325..cd86e21e32a7da 100644
--- a/llvm/lib/Target/AVR/AVRISelLowering.h
+++ b/llvm/lib/Target/AVR/AVRISelLowering.h
@@ -19,64 +19,6 @@
 
 namespace llvm {
 
-namespace AVRISD {
-
-/// AVR Specific DAG Nodes
-enum NodeType {
-  /// Start the numbering where the builtin ops leave off.
-  FIRST_NUMBER = ISD::BUILTIN_OP_END,
-  /// Return from subroutine.
-  RET_GLUE,
-  /// Return from ISR.
-  RETI_GLUE,
-  /// Represents an abstract call instruction,
-  /// which includes a bunch of information.
-  CALL,
-  /// A wrapper node for TargetConstantPool,
-  /// TargetExternalSymbol, and TargetGlobalAddress.
-  WRAPPER,
-  LSL,     ///< Logical shift left.
-  LSLBN,   ///< Byte logical shift left N bits.
-  LSLWN,   ///< Word logical shift left N bits.
-  LSLHI,   ///< Higher 8-bit of word logical shift left.
-  LSLW,    ///< Wide logical shift left.
-  LSR,     ///< Logical shift right.
-  LSRBN,   ///< Byte logical shift right N bits.
-  LSRWN,   ///< Word logical shift right N bits.
-  LSRLO,   ///< Lower 8-bit of word logical shift right.
-  LSRW,    ///< Wide logical shift right.
-  ASR,     ///< Arithmetic shift right.
-  ASRBN,   ///< Byte arithmetic shift right N bits.
-  ASRWN,   ///< Word arithmetic shift right N bits.
-  ASRLO,   ///< Lower 8-bit of word arithmetic shift right.
-  ASRW,    ///< Wide arithmetic shift right.
-  ROR,     ///< Bit rotate right.
-  ROL,     ///< Bit rotate left.
-  LSLLOOP, ///< A loop of single logical shift left instructions.
-  LSRLOOP, ///< A loop of single logical shift right instructions.
-  ROLLOOP, ///< A loop of single left bit rotate instructions.
-  RORLOOP, ///< A loop of single right bit rotate instructions.
-  ASRLOOP, ///< A loop of single arithmetic shift right instructions.
-  /// AVR conditional branches. Operand 0 is the chain operand, operand 1
-  /// is the block to branch if condition is true, operand 2 is the
-  /// condition code, and operand 3 is the flag operand produced by a CMP
-  /// or TEST instruction.
-  BRCOND,
-  /// Compare instruction.
-  CMP,
-  /// Compare with carry instruction.
-  CMPC,
-  /// Test for zero or minus instruction.
-  TST,
-  /// Swap Rd[7:4] <-> Rd[3:0].
-  SWAP,
-  /// Operand 0 and operand 1 are selection variable, operand 2
-  /// is condition code and operand 3 is flag operand.
-  SELECT_CC
-};
-
-} // end of namespace AVRISD
-
 class AVRSubtarget;
 class AVRTargetMachine;
 
@@ -95,8 +37,6 @@ class AVRTargetLowering : public TargetLowering {
     return MVT::i8;
   }
 
-  const char *getTargetNodeName(unsigned Opcode) const override;
-
   SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
 
   void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
diff --git a/llvm/lib/Target/AVR/AVRSelectionDAGInfo.cpp b/llvm/lib/Target/AVR/AVRSelectionDAGInfo.cpp
new file mode 100644
index 00000000000000..833e5b3b966ece
--- /dev/null
+++ b/llvm/lib/Target/AVR/AVRSelectionDAGInfo.cpp
@@ -0,0 +1,19 @@
+//===- AVRSelectionDAGInfo.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "AVRSelectionDAGInfo.h"
+
+#define GET_SDNODE_DESC
+#include "AVRGenSDNodeInfo.inc"
+
+using namespace llvm;
+
+AVRSelectionDAGInfo::AVRSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(AVRGenSDNodeInfo) {}
+
+AVRSelectionDAGInfo::~AVRSelectionDAGInfo() = default;
diff --git a/llvm/lib/Target/AVR/AVRSelectionDAGInfo.h b/llvm/lib/Target/AVR/AVRSelectionDAGInfo.h
index 3e7bd57f10cf07..0edac1ef45f2f4 100644
--- a/llvm/lib/Target/AVR/AVRSelectionDAGInfo.h
+++ b/llvm/lib/Target/AVR/AVRSelectionDAGInfo.h
@@ -15,11 +15,17 @@
 
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 
+#define GET_SDNODE_ENUM
+#include "AVRGenSDNodeInfo.inc"
+
 namespace llvm {
 
 /// Holds information about the AVR instruction selection DAG.
-class AVRSelectionDAGInfo : public SelectionDAGTargetInfo {
+class AVRSelectionDAGInfo : public SelectionDAGGenTargetInfo {
 public:
+  AVRSelectionDAGInfo();
+
+  ~AVRSelectionDAGInfo() override;
 };
 
 } // end namespace llvm
diff --git a/llvm/lib/Target/AVR/CMakeLists.txt b/llvm/lib/Target/AVR/CMakeLists.txt
index 817ba739d8418a..781dac02c70834 100644
--- a/llvm/lib/Target/AVR/CMakeLists.txt
+++ b/llvm/lib/Target/AVR/CMakeLists.txt
@@ -10,6 +10,7 @@ tablegen(LLVM AVRGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM AVRGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM AVRGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM AVRGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM AVRGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM AVRGenSubtargetInfo.inc -gen-subtarget)
 
 add_public_tablegen_target(AVRCommonTableGen)
@@ -23,6 +24,7 @@ add_llvm_target(AVRCodeGen
   AVRISelLowering.cpp
   AVRMCInstLower.cpp
   AVRRegisterInfo.cpp
+  AVRSelectionDAGInfo.cpp
   AVRShiftExpand.cpp
   AVRSubtarget.cpp
   AVRTargetMachine.cpp

>From 6bb4c96aee094e2168833fcd3935fdf49ddc4ca2 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 01:01:09 +0300
Subject: [PATCH 09/27] BPF

---
 llvm/lib/Target/BPF/BPFISelLowering.cpp     | 20 --------------------
 llvm/lib/Target/BPF/BPFISelLowering.h       | 14 --------------
 llvm/lib/Target/BPF/BPFSelectionDAGInfo.cpp | 21 +++++++++++++++++++++
 llvm/lib/Target/BPF/BPFSelectionDAGInfo.h   | 10 +++++++++-
 llvm/lib/Target/BPF/CMakeLists.txt          |  1 +
 5 files changed, 31 insertions(+), 35 deletions(-)

diff --git a/llvm/lib/Target/BPF/BPFISelLowering.cpp b/llvm/lib/Target/BPF/BPFISelLowering.cpp
index 1f5cadf37ab581..eab35123b916a1 100644
--- a/llvm/lib/Target/BPF/BPFISelLowering.cpp
+++ b/llvm/lib/Target/BPF/BPFISelLowering.cpp
@@ -701,26 +701,6 @@ SDValue BPFTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
   return DAG.getNode(BPFISD::SELECT_CC, DL, Op.getValueType(), Ops);
 }
 
-const char *BPFTargetLowering::getTargetNodeName(unsigned Opcode) const {
-  switch ((BPFISD::NodeType)Opcode) {
-  case BPFISD::FIRST_NUMBER:
-    break;
-  case BPFISD::RET_GLUE:
-    return "BPFISD::RET_GLUE";
-  case BPFISD::CALL:
-    return "BPFISD::CALL";
-  case BPFISD::SELECT_CC:
-    return "BPFISD::SELECT_CC";
-  case BPFISD::BR_CC:
-    return "BPFISD::BR_CC";
-  case BPFISD::Wrapper:
-    return "BPFISD::Wrapper";
-  case BPFISD::MEMCPY:
-    return "BPFISD::MEMCPY";
-  }
-  return nullptr;
-}
-
 static SDValue getTargetNode(GlobalAddressSDNode *N, const SDLoc &DL, EVT Ty,
                              SelectionDAG &DAG, unsigned Flags) {
   return DAG.getTargetGlobalAddress(N->getGlobal(), DL, Ty, 0, Flags);
diff --git a/llvm/lib/Target/BPF/BPFISelLowering.h b/llvm/lib/Target/BPF/BPFISelLowering.h
index d59098f9f569ba..a18c560494828b 100644
--- a/llvm/lib/Target/BPF/BPFISelLowering.h
+++ b/llvm/lib/Target/BPF/BPFISelLowering.h
@@ -20,17 +20,6 @@
 
 namespace llvm {
 class BPFSubtarget;
-namespace BPFISD {
-enum NodeType : unsigned {
-  FIRST_NUMBER = ISD::BUILTIN_OP_END,
-  RET_GLUE,
-  CALL,
-  SELECT_CC,
-  BR_CC,
-  Wrapper,
-  MEMCPY
-};
-}
 
 class BPFTargetLowering : public TargetLowering {
 public:
@@ -39,9 +28,6 @@ class BPFTargetLowering : public TargetLowering {
   // Provide custom lowering hooks for some operations.
   SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
 
-  // This method returns the name of a target specific DAG node.
-  const char *getTargetNodeName(unsigned Opcode) const override;
-
   // This method decides whether folding a constant offset
   // with the given GlobalAddress is legal.
   bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
diff --git a/llvm/lib/Target/BPF/BPFSelectionDAGInfo.cpp b/llvm/lib/Target/BPF/BPFSelectionDAGInfo.cpp
index 3e29e6c7ed3865..567bf81552f752 100644
--- a/llvm/lib/Target/BPF/BPFSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/BPF/BPFSelectionDAGInfo.cpp
@@ -10,12 +10,33 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "BPFSelectionDAGInfo.h"
 #include "BPFTargetMachine.h"
 #include "llvm/CodeGen/SelectionDAG.h"
+
+#define GET_SDNODE_DESC
+#include "BPFGenSDNodeInfo.inc"
+
 using namespace llvm;
 
 #define DEBUG_TYPE "bpf-selectiondag-info"
 
+BPFSelectionDAGInfo::BPFSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(BPFGenSDNodeInfo) {}
+
+void BPFSelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
+                                           const SDNode *N) const {
+  switch (N->getOpcode()) {
+  default:
+    break;
+  case BPFISD::MEMCPY:
+    // invalid number of operands; expected 6, got 5
+    return;
+  }
+
+  SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
+}
+
 SDValue BPFSelectionDAGInfo::EmitTargetCodeForMemcpy(
     SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
     SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline,
diff --git a/llvm/lib/Target/BPF/BPFSelectionDAGInfo.h b/llvm/lib/Target/BPF/BPFSelectionDAGInfo.h
index 79f05e57bb5cd8..ab36f60005f3f5 100644
--- a/llvm/lib/Target/BPF/BPFSelectionDAGInfo.h
+++ b/llvm/lib/Target/BPF/BPFSelectionDAGInfo.h
@@ -15,10 +15,18 @@
 
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 
+#define GET_SDNODE_ENUM
+#include "BPFGenSDNodeInfo.inc"
+
 namespace llvm {
 
-class BPFSelectionDAGInfo : public SelectionDAGTargetInfo {
+class BPFSelectionDAGInfo : public SelectionDAGGenTargetInfo {
 public:
+  BPFSelectionDAGInfo();
+
+  void verifyTargetNode(const SelectionDAG &DAG,
+                        const SDNode *N) const override;
+
   SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &dl,
                                   SDValue Chain, SDValue Dst, SDValue Src,
                                   SDValue Size, Align Alignment,
diff --git a/llvm/lib/Target/BPF/CMakeLists.txt b/llvm/lib/Target/BPF/CMakeLists.txt
index eade4cacb7100e..105b67db108f81 100644
--- a/llvm/lib/Target/BPF/CMakeLists.txt
+++ b/llvm/lib/Target/BPF/CMakeLists.txt
@@ -10,6 +10,7 @@ tablegen(LLVM BPFGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM BPFGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM BPFGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM BPFGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM BPFGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM BPFGenSubtargetInfo.inc -gen-subtarget)
 tablegen(LLVM BPFGenGlobalISel.inc -gen-global-isel)
 tablegen(LLVM BPFGenRegisterBank.inc -gen-register-bank)

>From 9ebcb16f2f2bc96aa4b3785fd261df1401f98a74 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 03:11:11 +0300
Subject: [PATCH 10/27] CSKY

---
 llvm/lib/Target/CSKY/CMakeLists.txt           |  2 ++
 llvm/lib/Target/CSKY/CSKYISelLowering.cpp     | 27 ------------------
 llvm/lib/Target/CSKY/CSKYISelLowering.h       | 21 +-------------
 llvm/lib/Target/CSKY/CSKYSelectionDAGInfo.cpp | 19 +++++++++++++
 llvm/lib/Target/CSKY/CSKYSelectionDAGInfo.h   | 28 +++++++++++++++++++
 llvm/lib/Target/CSKY/CSKYSubtarget.cpp        | 11 +++++++-
 llvm/lib/Target/CSKY/CSKYSubtarget.h          | 10 +++----
 7 files changed, 65 insertions(+), 53 deletions(-)
 create mode 100644 llvm/lib/Target/CSKY/CSKYSelectionDAGInfo.cpp
 create mode 100644 llvm/lib/Target/CSKY/CSKYSelectionDAGInfo.h

diff --git a/llvm/lib/Target/CSKY/CMakeLists.txt b/llvm/lib/Target/CSKY/CMakeLists.txt
index cdce80591a2fd2..4b900bc99c271d 100644
--- a/llvm/lib/Target/CSKY/CMakeLists.txt
+++ b/llvm/lib/Target/CSKY/CMakeLists.txt
@@ -12,6 +12,7 @@ tablegen(LLVM CSKYGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM CSKYGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM CSKYGenMCPseudoLowering.inc -gen-pseudo-lowering)
 tablegen(LLVM CSKYGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM CSKYGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM CSKYGenSubtargetInfo.inc -gen-subtarget)
 
 add_public_tablegen_target(CSKYCommonTableGen)
@@ -26,6 +27,7 @@ add_llvm_target(CSKYCodeGen
   CSKYISelLowering.cpp
   CSKYMCInstLower.cpp
   CSKYRegisterInfo.cpp
+  CSKYSelectionDAGInfo.cpp
   CSKYSubtarget.cpp
   CSKYTargetMachine.cpp
   CSKYTargetObjectFile.cpp
diff --git a/llvm/lib/Target/CSKY/CSKYISelLowering.cpp b/llvm/lib/Target/CSKY/CSKYISelLowering.cpp
index c3fc9f9ead5eb3..5150755caf0661 100644
--- a/llvm/lib/Target/CSKY/CSKYISelLowering.cpp
+++ b/llvm/lib/Target/CSKY/CSKYISelLowering.cpp
@@ -1116,33 +1116,6 @@ SDValue CSKYTargetLowering::getTargetNode(ConstantPoolSDNode *N, SDLoc DL,
                                    N->getOffset(), Flags);
 }
 
-const char *CSKYTargetLowering::getTargetNodeName(unsigned Opcode) const {
-  switch (Opcode) {
-  default:
-    llvm_unreachable("unknown CSKYISD node");
-  case CSKYISD::NIE:
-    return "CSKYISD::NIE";
-  case CSKYISD::NIR:
-    return "CSKYISD::NIR";
-  case CSKYISD::RET:
-    return "CSKYISD::RET";
-  case CSKYISD::CALL:
-    return "CSKYISD::CALL";
-  case CSKYISD::CALLReg:
-    return "CSKYISD::CALLReg";
-  case CSKYISD::TAIL:
-    return "CSKYISD::TAIL";
-  case CSKYISD::TAILReg:
-    return "CSKYISD::TAILReg";
-  case CSKYISD::LOAD_ADDR:
-    return "CSKYISD::LOAD_ADDR";
-  case CSKYISD::BITCAST_TO_LOHI:
-    return "CSKYISD::BITCAST_TO_LOHI";
-  case CSKYISD::BITCAST_FROM_LOHI:
-    return "CSKYISD::BITCAST_FROM_LOHI";
-  }
-}
-
 SDValue CSKYTargetLowering::LowerGlobalAddress(SDValue Op,
                                                SelectionDAG &DAG) const {
   SDLoc DL(Op);
diff --git a/llvm/lib/Target/CSKY/CSKYISelLowering.h b/llvm/lib/Target/CSKY/CSKYISelLowering.h
index d59481af3c5ba9..3ea7c1a9176335 100644
--- a/llvm/lib/Target/CSKY/CSKYISelLowering.h
+++ b/llvm/lib/Target/CSKY/CSKYISelLowering.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_LIB_TARGET_CSKY_CSKYISELLOWERING_H
 #define LLVM_LIB_TARGET_CSKY_CSKYISELLOWERING_H
 
+#include "CSKYSelectionDAGInfo.h"
 #include "MCTargetDesc/CSKYBaseInfo.h"
 #include "llvm/CodeGen/CallingConvLower.h"
 #include "llvm/CodeGen/TargetLowering.h"
@@ -21,24 +22,6 @@
 namespace llvm {
 class CSKYSubtarget;
 
-namespace CSKYISD {
-enum NodeType : unsigned {
-  FIRST_NUMBER = ISD::BUILTIN_OP_END,
-  NIE,
-  NIR,
-  RET,
-  CALL,
-  CALLReg,
-  TAIL,
-  TAILReg,
-  LOAD_ADDR,
-  // i32, i32 <-- f64
-  BITCAST_TO_LOHI,
-  // f64 < -- i32, i32
-  BITCAST_FROM_LOHI,
-};
-}
-
 class CSKYTargetLowering : public TargetLowering {
   const CSKYSubtarget &Subtarget;
 
@@ -71,8 +54,6 @@ class CSKYTargetLowering : public TargetLowering {
   SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
                     SmallVectorImpl<SDValue> &InVals) const override;
 
-  const char *getTargetNodeName(unsigned Opcode) const override;
-
   /// If a physical register, this returns the register that receives the
   /// exception address on entry to an EH pad.
   Register
diff --git a/llvm/lib/Target/CSKY/CSKYSelectionDAGInfo.cpp b/llvm/lib/Target/CSKY/CSKYSelectionDAGInfo.cpp
new file mode 100644
index 00000000000000..496d21d3964d12
--- /dev/null
+++ b/llvm/lib/Target/CSKY/CSKYSelectionDAGInfo.cpp
@@ -0,0 +1,19 @@
+//===- CSKYSelectionDAGInfo.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CSKYSelectionDAGInfo.h"
+
+#define GET_SDNODE_DESC
+#include "CSKYGenSDNodeInfo.inc"
+
+using namespace llvm;
+
+CSKYSelectionDAGInfo::CSKYSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(CSKYGenSDNodeInfo) {}
+
+CSKYSelectionDAGInfo::~CSKYSelectionDAGInfo() = default;
diff --git a/llvm/lib/Target/CSKY/CSKYSelectionDAGInfo.h b/llvm/lib/Target/CSKY/CSKYSelectionDAGInfo.h
new file mode 100644
index 00000000000000..61546c6079475d
--- /dev/null
+++ b/llvm/lib/Target/CSKY/CSKYSelectionDAGInfo.h
@@ -0,0 +1,28 @@
+//===- CSKYSelectionDAGInfo.h -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_CSKY_CSKYSELECTIONDAGINFO_H
+#define LLVM_LIB_TARGET_CSKY_CSKYSELECTIONDAGINFO_H
+
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+
+#define GET_SDNODE_ENUM
+#include "CSKYGenSDNodeInfo.inc"
+
+namespace llvm {
+
+class CSKYSelectionDAGInfo : public SelectionDAGGenTargetInfo {
+public:
+  CSKYSelectionDAGInfo();
+
+  ~CSKYSelectionDAGInfo() override;
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_CSKY_CSKYSELECTIONDAGINFO_H
diff --git a/llvm/lib/Target/CSKY/CSKYSubtarget.cpp b/llvm/lib/Target/CSKY/CSKYSubtarget.cpp
index 251dbed8270850..a554d1c0e739b0 100644
--- a/llvm/lib/Target/CSKY/CSKYSubtarget.cpp
+++ b/llvm/lib/Target/CSKY/CSKYSubtarget.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "CSKYSubtarget.h"
+#include "CSKYSelectionDAGInfo.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 
 using namespace llvm;
@@ -91,7 +92,15 @@ CSKYSubtarget::CSKYSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
                              StringRef FS, const TargetMachine &TM)
     : CSKYGenSubtargetInfo(TT, CPU, TuneCPU, FS),
       FrameLowering(initializeSubtargetDependencies(TT, CPU, TuneCPU, FS)),
-      InstrInfo(*this), RegInfo(), TLInfo(TM, *this) {}
+      InstrInfo(*this), RegInfo(), TLInfo(TM, *this) {
+  TSInfo = std::make_unique<CSKYSelectionDAGInfo>();
+}
+
+CSKYSubtarget::~CSKYSubtarget() = default;
+
+const SelectionDAGTargetInfo *CSKYSubtarget::getSelectionDAGInfo() const {
+  return TSInfo.get();
+}
 
 bool CSKYSubtarget::useHardFloatABI() const {
   auto FloatABI = getTargetLowering()->getTargetMachine().Options.FloatABIType;
diff --git a/llvm/lib/Target/CSKY/CSKYSubtarget.h b/llvm/lib/Target/CSKY/CSKYSubtarget.h
index b8be347935ac73..a3f2ddcb7165b5 100644
--- a/llvm/lib/Target/CSKY/CSKYSubtarget.h
+++ b/llvm/lib/Target/CSKY/CSKYSubtarget.h
@@ -17,7 +17,6 @@
 #include "CSKYISelLowering.h"
 #include "CSKYInstrInfo.h"
 #include "CSKYRegisterInfo.h"
-#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/Target/TargetMachine.h"
 
@@ -34,7 +33,7 @@ class CSKYSubtarget : public CSKYGenSubtargetInfo {
   CSKYInstrInfo InstrInfo;
   CSKYRegisterInfo RegInfo;
   CSKYTargetLowering TLInfo;
-  SelectionDAGTargetInfo TSInfo;
+  std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
 
   enum CSKYProcFamilyEnum {
     Others,
@@ -112,6 +111,8 @@ class CSKYSubtarget : public CSKYGenSubtargetInfo {
   CSKYSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
                 StringRef FS, const TargetMachine &TM);
 
+  ~CSKYSubtarget() override;
+
   const CSKYFrameLowering *getFrameLowering() const override {
     return &FrameLowering;
   }
@@ -120,9 +121,8 @@ class CSKYSubtarget : public CSKYGenSubtargetInfo {
   const CSKYTargetLowering *getTargetLowering() const override {
     return &TLInfo;
   }
-  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
-    return &TSInfo;
-  }
+
+  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
 
   /// Initializes using the passed in CPU and feature strings so that we can
   /// use initializer lists for subtarget initialization.

>From 1b8d8000bf5c28c7d9727e9eef2a768e614cced8 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 01:01:21 +0300
Subject: [PATCH 11/27] Hexagon

---
 llvm/lib/Target/Hexagon/CMakeLists.txt        |  1 +
 .../Target/Hexagon/HexagonISelLowering.cpp    | 60 ------------
 llvm/lib/Target/Hexagon/HexagonISelLowering.h | 95 -------------------
 .../Hexagon/HexagonSelectionDAGInfo.cpp       | 59 ++++++++++++
 .../Target/Hexagon/HexagonSelectionDAGInfo.h  | 61 +++++++++++-
 5 files changed, 119 insertions(+), 157 deletions(-)

diff --git a/llvm/lib/Target/Hexagon/CMakeLists.txt b/llvm/lib/Target/Hexagon/CMakeLists.txt
index d758260a8ab5db..998d2f84334dfd 100644
--- a/llvm/lib/Target/Hexagon/CMakeLists.txt
+++ b/llvm/lib/Target/Hexagon/CMakeLists.txt
@@ -11,6 +11,7 @@ tablegen(LLVM HexagonGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM HexagonGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM HexagonGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM HexagonGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM HexagonGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM HexagonGenSubtargetInfo.inc -gen-subtarget)
 
 add_public_tablegen_target(HexagonCommonTableGen)
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
index 9fbf4cb684a526..baec08827608f4 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -1900,64 +1900,6 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
   setLibcallName(RTLIB::FPEXT_F16_F32, "__extendhfsf2");
 }
 
-const char* HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const {
-  switch ((HexagonISD::NodeType)Opcode) {
-  case HexagonISD::ADDC:          return "HexagonISD::ADDC";
-  case HexagonISD::SUBC:          return "HexagonISD::SUBC";
-  case HexagonISD::ALLOCA:        return "HexagonISD::ALLOCA";
-  case HexagonISD::AT_GOT:        return "HexagonISD::AT_GOT";
-  case HexagonISD::AT_PCREL:      return "HexagonISD::AT_PCREL";
-  case HexagonISD::BARRIER:       return "HexagonISD::BARRIER";
-  case HexagonISD::CALL:          return "HexagonISD::CALL";
-  case HexagonISD::CALLnr:        return "HexagonISD::CALLnr";
-  case HexagonISD::CALLR:         return "HexagonISD::CALLR";
-  case HexagonISD::COMBINE:       return "HexagonISD::COMBINE";
-  case HexagonISD::CONST32_GP:    return "HexagonISD::CONST32_GP";
-  case HexagonISD::CONST32:       return "HexagonISD::CONST32";
-  case HexagonISD::CP:            return "HexagonISD::CP";
-  case HexagonISD::DCFETCH:       return "HexagonISD::DCFETCH";
-  case HexagonISD::EH_RETURN:     return "HexagonISD::EH_RETURN";
-  case HexagonISD::TSTBIT:        return "HexagonISD::TSTBIT";
-  case HexagonISD::EXTRACTU:      return "HexagonISD::EXTRACTU";
-  case HexagonISD::INSERT:        return "HexagonISD::INSERT";
-  case HexagonISD::JT:            return "HexagonISD::JT";
-  case HexagonISD::RET_GLUE:      return "HexagonISD::RET_GLUE";
-  case HexagonISD::TC_RETURN:     return "HexagonISD::TC_RETURN";
-  case HexagonISD::VASL:          return "HexagonISD::VASL";
-  case HexagonISD::VASR:          return "HexagonISD::VASR";
-  case HexagonISD::VLSR:          return "HexagonISD::VLSR";
-  case HexagonISD::MFSHL:         return "HexagonISD::MFSHL";
-  case HexagonISD::MFSHR:         return "HexagonISD::MFSHR";
-  case HexagonISD::SSAT:          return "HexagonISD::SSAT";
-  case HexagonISD::USAT:          return "HexagonISD::USAT";
-  case HexagonISD::SMUL_LOHI:     return "HexagonISD::SMUL_LOHI";
-  case HexagonISD::UMUL_LOHI:     return "HexagonISD::UMUL_LOHI";
-  case HexagonISD::USMUL_LOHI:    return "HexagonISD::USMUL_LOHI";
-  case HexagonISD::VEXTRACTW:     return "HexagonISD::VEXTRACTW";
-  case HexagonISD::VINSERTW0:     return "HexagonISD::VINSERTW0";
-  case HexagonISD::VROR:          return "HexagonISD::VROR";
-  case HexagonISD::READCYCLE:     return "HexagonISD::READCYCLE";
-  case HexagonISD::READTIMER:     return "HexagonISD::READTIMER";
-  case HexagonISD::PTRUE:         return "HexagonISD::PTRUE";
-  case HexagonISD::PFALSE:        return "HexagonISD::PFALSE";
-  case HexagonISD::D2P:           return "HexagonISD::D2P";
-  case HexagonISD::P2D:           return "HexagonISD::P2D";
-  case HexagonISD::V2Q:           return "HexagonISD::V2Q";
-  case HexagonISD::Q2V:           return "HexagonISD::Q2V";
-  case HexagonISD::QCAT:          return "HexagonISD::QCAT";
-  case HexagonISD::QTRUE:         return "HexagonISD::QTRUE";
-  case HexagonISD::QFALSE:        return "HexagonISD::QFALSE";
-  case HexagonISD::TL_EXTEND:     return "HexagonISD::TL_EXTEND";
-  case HexagonISD::TL_TRUNCATE:   return "HexagonISD::TL_TRUNCATE";
-  case HexagonISD::TYPECAST:      return "HexagonISD::TYPECAST";
-  case HexagonISD::VALIGN:        return "HexagonISD::VALIGN";
-  case HexagonISD::VALIGNADDR:    return "HexagonISD::VALIGNADDR";
-  case HexagonISD::ISEL:          return "HexagonISD::ISEL";
-  case HexagonISD::OP_END:        break;
-  }
-  return nullptr;
-}
-
 bool
 HexagonTargetLowering::validateConstPtrAlignment(SDValue Ptr, Align NeedAlign,
       const SDLoc &dl, SelectionDAG &DAG) const {
@@ -3351,8 +3293,6 @@ HexagonTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
     default:
 #ifndef NDEBUG
       Op.getNode()->dumpr(&DAG);
-      if (Opc > HexagonISD::OP_BEGIN && Opc < HexagonISD::OP_END)
-        errs() << "Error: check for a non-legal type in this operation\n";
 #endif
       llvm_unreachable("Should not custom lower this!");
 
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
index 3fd961f5a74623..af20e5a06c6378 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
@@ -29,99 +29,6 @@
 
 namespace llvm {
 
-namespace HexagonISD {
-
-enum NodeType : unsigned {
-  OP_BEGIN = ISD::BUILTIN_OP_END,
-
-  CONST32 = OP_BEGIN,
-  CONST32_GP,  // For marking data present in GP.
-  ADDC,        // Add with carry: (X, Y, Cin) -> (X+Y, Cout).
-  SUBC,        // Sub with carry: (X, Y, Cin) -> (X+~Y+Cin, Cout).
-  ALLOCA,
-
-  AT_GOT,      // Index in GOT.
-  AT_PCREL,    // Offset relative to PC.
-
-  CALL,        // Function call.
-  CALLnr,      // Function call that does not return.
-  CALLR,
-
-  RET_GLUE,    // Return with a glue operand.
-  BARRIER,     // Memory barrier.
-  JT,          // Jump table.
-  CP,          // Constant pool.
-
-  COMBINE,
-  VASL,        // Vector shifts by a scalar value
-  VASR,
-  VLSR,
-  MFSHL,       // Funnel shifts with the shift amount guaranteed to be
-  MFSHR,       // within the range of the bit width of the element.
-
-  SSAT,        // Signed saturate.
-  USAT,        // Unsigned saturate.
-  SMUL_LOHI,   // Same as ISD::SMUL_LOHI, but opaque to the combiner.
-  UMUL_LOHI,   // Same as ISD::UMUL_LOHI, but opaque to the combiner.
-               // We want to legalize MULH[SU] to [SU]MUL_LOHI, but the
-               // combiner will keep rewriting it back to MULH[SU].
-  USMUL_LOHI,  // Like SMUL_LOHI, but unsigned*signed.
-
-  TSTBIT,
-  INSERT,
-  EXTRACTU,
-  VEXTRACTW,
-  VINSERTW0,
-  VROR,
-  TC_RETURN,
-  EH_RETURN,
-  DCFETCH,
-  READCYCLE,
-  READTIMER,
-  PTRUE,
-  PFALSE,
-  D2P,         // Convert 8-byte value to 8-bit predicate register. [*]
-  P2D,         // Convert 8-bit predicate register to 8-byte value. [*]
-  V2Q,         // Convert HVX vector to a vector predicate reg. [*]
-  Q2V,         // Convert vector predicate to an HVX vector. [*]
-               // [*] The equivalence is defined as "Q <=> (V != 0)",
-               //     where the != operation compares bytes.
-               // Note: V != 0 is implemented as V >u 0.
-  QCAT,
-  QTRUE,
-  QFALSE,
-
-  TL_EXTEND,   // Wrappers for ISD::*_EXTEND and ISD::TRUNCATE to prevent DAG
-  TL_TRUNCATE, // from auto-folding operations, e.g.
-               // (i32 ext (i16 ext i8)) would be folded to (i32 ext i8).
-               // To simplify the type legalization, we want to keep these
-               // single steps separate during type legalization.
-               // TL_[EXTEND|TRUNCATE] Inp, i128 _, i32 Opc
-               // * Inp is the original input to extend/truncate,
-               // * _ is a dummy operand with an illegal type (can be undef),
-               // * Opc is the original opcode.
-               // The legalization process (in Hexagon lowering code) will
-               // first deal with the "real" types (i.e. Inp and the result),
-               // and once all of them are processed, the wrapper node will
-               // be replaced with the original ISD node. The dummy illegal
-               // operand is there to make sure that the legalization hooks
-               // are called again after everything else is legal, giving
-               // us the opportunity to undo the wrapping.
-
-  TYPECAST,    // No-op that's used to convert between different legal
-               // types in a register.
-  VALIGN,      // Align two vectors (in Op0, Op1) to one that would have
-               // been loaded from address in Op2.
-  VALIGNADDR,  // Align vector address: Op0 & -Op1, except when it is
-               // an address in a vector load, then it's a no-op.
-  ISEL,        // Marker for nodes that were created during ISel, and
-               // which need explicit selection (would have been left
-               // unselected otherwise).
-  OP_END
-};
-
-} // end namespace HexagonISD
-
 class HexagonSubtarget;
 
 class HexagonTargetLowering : public TargetLowering {
@@ -182,8 +89,6 @@ class HexagonTargetLowering : public TargetLowering {
   void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
                           SelectionDAG &DAG) const override;
 
-  const char *getTargetNodeName(unsigned Opcode) const override;
-
   SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
diff --git a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
index 1b724e8fcae91c..70aaa9ed9f96b8 100644
--- a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
@@ -10,12 +10,71 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "HexagonSelectionDAGInfo.h"
 #include "HexagonTargetMachine.h"
 #include "llvm/CodeGen/SelectionDAG.h"
+
+#define GET_SDNODE_DESC
+#include "HexagonGenSDNodeInfo.inc"
+
 using namespace llvm;
 
 #define DEBUG_TYPE "hexagon-selectiondag-info"
 
+HexagonSelectionDAGInfo::HexagonSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(HexagonGenSDNodeInfo) {}
+
+const char *HexagonSelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
+  // These nodes don't have corresponding entries in *.td files yet.
+  switch (static_cast<HexagonISD::NodeType>(Opcode)) {
+  case HexagonISD::ADDC:
+    return "HexagonISD::ADDC";
+  case HexagonISD::SUBC:
+    return "HexagonISD::SUBC";
+  case HexagonISD::CALLR:
+    return "HexagonISD::CALLR";
+  case HexagonISD::SMUL_LOHI:
+    return "HexagonISD::SMUL_LOHI";
+  case HexagonISD::UMUL_LOHI:
+    return "HexagonISD::UMUL_LOHI";
+  case HexagonISD::USMUL_LOHI:
+    return "HexagonISD::USMUL_LOHI";
+  case HexagonISD::VROR:
+    return "HexagonISD::VROR";
+  case HexagonISD::D2P:
+    return "HexagonISD::D2P";
+  case HexagonISD::P2D:
+    return "HexagonISD::P2D";
+  case HexagonISD::V2Q:
+    return "HexagonISD::V2Q";
+  case HexagonISD::Q2V:
+    return "HexagonISD::Q2V";
+  case HexagonISD::TL_EXTEND:
+    return "HexagonISD::TL_EXTEND";
+  case HexagonISD::TL_TRUNCATE:
+    return "HexagonISD::TL_TRUNCATE";
+  case HexagonISD::TYPECAST:
+    return "HexagonISD::TYPECAST";
+  case HexagonISD::ISEL:
+    return "HexagonISD::ISEL";
+  }
+
+  return SelectionDAGGenTargetInfo::getTargetNodeName(Opcode);
+}
+
+void HexagonSelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
+                                               const SDNode *N) const {
+  switch (N->getOpcode()) {
+  default:
+    break;
+  case HexagonISD::VALIGNADDR:
+    // invalid number of operands; expected 1, got 2
+    return;
+  }
+
+  SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
+}
+
 SDValue HexagonSelectionDAGInfo::EmitTargetCodeForMemcpy(
     SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
     SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline,
diff --git a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h
index 0d3b1725d1bc4c..c62be58901034f 100644
--- a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h
+++ b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h
@@ -15,11 +15,68 @@
 
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 
+#define GET_SDNODE_ENUM
+#include "HexagonGenSDNodeInfo.inc"
+
 namespace llvm {
+namespace HexagonISD {
+
+enum NodeType : unsigned {
+  ADDC = GENERATED_OPCODE_END, // Add with carry: (X, Y, Cin) -> (X+Y, Cout).
+  SUBC, // Sub with carry: (X, Y, Cin) -> (X+~Y+Cin, Cout).
+
+  CALLR,
+
+  SMUL_LOHI,  // Same as ISD::SMUL_LOHI, but opaque to the combiner.
+  UMUL_LOHI,  // Same as ISD::UMUL_LOHI, but opaque to the combiner.
+              // We want to legalize MULH[SU] to [SU]MUL_LOHI, but the
+              // combiner will keep rewriting it back to MULH[SU].
+  USMUL_LOHI, // Like SMUL_LOHI, but unsigned*signed.
+
+  VROR,
+  D2P, // Convert 8-byte value to 8-bit predicate register. [*]
+  P2D, // Convert 8-bit predicate register to 8-byte value. [*]
+  V2Q, // Convert HVX vector to a vector predicate reg. [*]
+  Q2V, // Convert vector predicate to an HVX vector. [*]
+       // [*] The equivalence is defined as "Q <=> (V != 0)",
+       //     where the != operation compares bytes.
+       // Note: V != 0 is implemented as V >u 0.
+
+  TL_EXTEND,   // Wrappers for ISD::*_EXTEND and ISD::TRUNCATE to prevent DAG
+  TL_TRUNCATE, // from auto-folding operations, e.g.
+               // (i32 ext (i16 ext i8)) would be folded to (i32 ext i8).
+               // To simplify the type legalization, we want to keep these
+               // single steps separate during type legalization.
+               // TL_[EXTEND|TRUNCATE] Inp, i128 _, i32 Opc
+               // * Inp is the original input to extend/truncate,
+               // * _ is a dummy operand with an illegal type (can be undef),
+               // * Opc is the original opcode.
+               // The legalization process (in Hexagon lowering code) will
+               // first deal with the "real" types (i.e. Inp and the result),
+               // and once all of them are processed, the wrapper node will
+               // be replaced with the original ISD node. The dummy illegal
+               // operand is there to make sure that the legalization hooks
+               // are called again after everything else is legal, giving
+               // us the opportunity to undo the wrapping.
 
-class HexagonSelectionDAGInfo : public SelectionDAGTargetInfo {
+  TYPECAST, // No-op that's used to convert between different legal
+            // types in a register.
+  ISEL,     // Marker for nodes that were created during ISel, and
+            // which need explicit selection (would have been left
+            // unselected otherwise).
+  // clang-format on
+};
+
+} // namespace HexagonISD
+
+class HexagonSelectionDAGInfo : public SelectionDAGGenTargetInfo {
 public:
-  explicit HexagonSelectionDAGInfo() = default;
+  HexagonSelectionDAGInfo();
+
+  const char *getTargetNodeName(unsigned Opcode) const override;
+
+  void verifyTargetNode(const SelectionDAG &DAG,
+                        const SDNode *N) const override;
 
   SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &dl,
                                   SDValue Chain, SDValue Dst, SDValue Src,

>From a6c5cf5bcd570f57e4d5bc9d5fcafd0de100b831 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 01:01:32 +0300
Subject: [PATCH 12/27] Lanai (Wrapper removed)

---
 llvm/lib/Target/Lanai/CMakeLists.txt          |  1 +
 llvm/lib/Target/Lanai/LanaiISelLowering.cpp   | 31 -------------
 llvm/lib/Target/Lanai/LanaiISelLowering.h     | 45 -------------------
 .../Target/Lanai/LanaiSelectionDAGInfo.cpp    | 10 +++--
 llvm/lib/Target/Lanai/LanaiSelectionDAGInfo.h |  7 ++-
 5 files changed, 13 insertions(+), 81 deletions(-)

diff --git a/llvm/lib/Target/Lanai/CMakeLists.txt b/llvm/lib/Target/Lanai/CMakeLists.txt
index 16d5f727043fe9..4a628e13fc1773 100644
--- a/llvm/lib/Target/Lanai/CMakeLists.txt
+++ b/llvm/lib/Target/Lanai/CMakeLists.txt
@@ -10,6 +10,7 @@ tablegen(LLVM LanaiGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM LanaiGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM LanaiGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM LanaiGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM LanaiGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM LanaiGenSubtargetInfo.inc -gen-subtarget)
 
 add_public_tablegen_target(LanaiCommonTableGen)
diff --git a/llvm/lib/Target/Lanai/LanaiISelLowering.cpp b/llvm/lib/Target/Lanai/LanaiISelLowering.cpp
index da55b7b8c6d68c..b55a41b7786ce0 100644
--- a/llvm/lib/Target/Lanai/LanaiISelLowering.cpp
+++ b/llvm/lib/Target/Lanai/LanaiISelLowering.cpp
@@ -1086,37 +1086,6 @@ SDValue LanaiTargetLowering::LowerFRAMEADDR(SDValue Op,
   return FrameAddr;
 }
 
-const char *LanaiTargetLowering::getTargetNodeName(unsigned Opcode) const {
-  switch (Opcode) {
-  case LanaiISD::ADJDYNALLOC:
-    return "LanaiISD::ADJDYNALLOC";
-  case LanaiISD::RET_GLUE:
-    return "LanaiISD::RET_GLUE";
-  case LanaiISD::CALL:
-    return "LanaiISD::CALL";
-  case LanaiISD::SELECT_CC:
-    return "LanaiISD::SELECT_CC";
-  case LanaiISD::SETCC:
-    return "LanaiISD::SETCC";
-  case LanaiISD::SUBBF:
-    return "LanaiISD::SUBBF";
-  case LanaiISD::SET_FLAG:
-    return "LanaiISD::SET_FLAG";
-  case LanaiISD::BR_CC:
-    return "LanaiISD::BR_CC";
-  case LanaiISD::Wrapper:
-    return "LanaiISD::Wrapper";
-  case LanaiISD::HI:
-    return "LanaiISD::HI";
-  case LanaiISD::LO:
-    return "LanaiISD::LO";
-  case LanaiISD::SMALL:
-    return "LanaiISD::SMALL";
-  default:
-    return nullptr;
-  }
-}
-
 SDValue LanaiTargetLowering::LowerConstantPool(SDValue Op,
                                                SelectionDAG &DAG) const {
   SDLoc DL(Op);
diff --git a/llvm/lib/Target/Lanai/LanaiISelLowering.h b/llvm/lib/Target/Lanai/LanaiISelLowering.h
index 5fa5444b51618c..7d67ff278dd743 100644
--- a/llvm/lib/Target/Lanai/LanaiISelLowering.h
+++ b/llvm/lib/Target/Lanai/LanaiISelLowering.h
@@ -20,47 +20,6 @@
 #include "llvm/CodeGen/TargetLowering.h"
 
 namespace llvm {
-namespace LanaiISD {
-enum {
-  FIRST_NUMBER = ISD::BUILTIN_OP_END,
-
-  ADJDYNALLOC,
-
-  // Return with a glue operand. Operand 0 is the chain operand.
-  RET_GLUE,
-
-  // CALL - These operations represent an abstract call instruction, which
-  // includes a bunch of information.
-  CALL,
-
-  // SELECT_CC - Operand 0 and operand 1 are selection variable, operand 3
-  // is condition code and operand 4 is flag operand.
-  SELECT_CC,
-
-  // SETCC - Store the conditional code to a register.
-  SETCC,
-
-  // SET_FLAG - Set flag compare.
-  SET_FLAG,
-
-  // SUBBF - Subtract with borrow that sets flags.
-  SUBBF,
-
-  // BR_CC - Used to glue together a conditional branch and comparison
-  BR_CC,
-
-  // Wrapper - A wrapper node for TargetConstantPool, TargetExternalSymbol,
-  // and TargetGlobalAddress.
-  Wrapper,
-
-  // Get the Higher/Lower 16 bits from a 32-bit immediate.
-  HI,
-  LO,
-
-  // Small 21-bit immediate in global memory.
-  SMALL
-};
-} // namespace LanaiISD
 
 class LanaiSubtarget;
 
@@ -71,10 +30,6 @@ class LanaiTargetLowering : public TargetLowering {
   // LowerOperation - Provide custom lowering hooks for some operations.
   SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
 
-  // getTargetNodeName - This method returns the name of a target specific
-  // DAG node.
-  const char *getTargetNodeName(unsigned Opcode) const override;
-
   SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
diff --git a/llvm/lib/Target/Lanai/LanaiSelectionDAGInfo.cpp b/llvm/lib/Target/Lanai/LanaiSelectionDAGInfo.cpp
index 091e29a90d7e7e..77e01c6dfe6e81 100644
--- a/llvm/lib/Target/Lanai/LanaiSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/Lanai/LanaiSelectionDAGInfo.cpp
@@ -12,9 +12,15 @@
 
 #include "LanaiSelectionDAGInfo.h"
 
+#define GET_SDNODE_DESC
+#include "LanaiGenSDNodeInfo.inc"
+
 #define DEBUG_TYPE "lanai-selectiondag-info"
 
-namespace llvm {
+using namespace llvm;
+
+LanaiSelectionDAGInfo::LanaiSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(LanaiGenSDNodeInfo) {}
 
 SDValue LanaiSelectionDAGInfo::EmitTargetCodeForMemcpy(
     SelectionDAG & /*DAG*/, const SDLoc & /*dl*/, SDValue /*Chain*/,
@@ -28,5 +34,3 @@ SDValue LanaiSelectionDAGInfo::EmitTargetCodeForMemcpy(
 
   return SDValue();
 }
-
-} // namespace llvm
diff --git a/llvm/lib/Target/Lanai/LanaiSelectionDAGInfo.h b/llvm/lib/Target/Lanai/LanaiSelectionDAGInfo.h
index 8355168a7396f5..41549082d6fcc4 100644
--- a/llvm/lib/Target/Lanai/LanaiSelectionDAGInfo.h
+++ b/llvm/lib/Target/Lanai/LanaiSelectionDAGInfo.h
@@ -16,11 +16,14 @@
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/Target/TargetMachine.h"
 
+#define GET_SDNODE_ENUM
+#include "LanaiGenSDNodeInfo.inc"
+
 namespace llvm {
 
-class LanaiSelectionDAGInfo : public SelectionDAGTargetInfo {
+class LanaiSelectionDAGInfo : public SelectionDAGGenTargetInfo {
 public:
-  LanaiSelectionDAGInfo() = default;
+  LanaiSelectionDAGInfo();
 
   SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &dl,
                                   SDValue Chain, SDValue Dst, SDValue Src,

>From 4ee99352ca71a25ed925a6a791f456c2039ca287 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 03:11:17 +0300
Subject: [PATCH 13/27] LoongArch (ROTL_W, CACOP_D, CACOP_W removed)

---
 llvm/lib/Target/LoongArch/CMakeLists.txt      |   2 +
 .../Target/LoongArch/LoongArchISelDAGToDAG.h  |   1 +
 .../LoongArch/LoongArchISelLowering.cpp       |  96 +------------
 .../Target/LoongArch/LoongArchISelLowering.h  | 134 ------------------
 .../LoongArch/LoongArchSelectionDAGInfo.cpp   |  19 +++
 .../LoongArch/LoongArchSelectionDAGInfo.h     |  28 ++++
 .../Target/LoongArch/LoongArchSubtarget.cpp   |  11 +-
 .../lib/Target/LoongArch/LoongArchSubtarget.h |  10 +-
 8 files changed, 68 insertions(+), 233 deletions(-)
 create mode 100644 llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.cpp
 create mode 100644 llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.h

diff --git a/llvm/lib/Target/LoongArch/CMakeLists.txt b/llvm/lib/Target/LoongArch/CMakeLists.txt
index 0f674b1b0fa9e2..8689d09140a1e0 100644
--- a/llvm/lib/Target/LoongArch/CMakeLists.txt
+++ b/llvm/lib/Target/LoongArch/CMakeLists.txt
@@ -10,6 +10,7 @@ tablegen(LLVM LoongArchGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM LoongArchGenMCPseudoLowering.inc -gen-pseudo-lowering)
 tablegen(LLVM LoongArchGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM LoongArchGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM LoongArchGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM LoongArchGenSubtargetInfo.inc -gen-subtarget)
 
 add_public_tablegen_target(LoongArchCommonTableGen)
@@ -27,6 +28,7 @@ add_llvm_target(LoongArchCodeGen
   LoongArchMergeBaseOffset.cpp
   LoongArchOptWInstrs.cpp
   LoongArchRegisterInfo.cpp
+  LoongArchSelectionDAGInfo.cpp
   LoongArchSubtarget.cpp
   LoongArchTargetMachine.cpp
   LoongArchTargetTransformInfo.cpp
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h
index 363b4f0ca7cf06..1224a236072b23 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h
+++ b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h
@@ -14,6 +14,7 @@
 #define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELDAGTODAG_H
 
 #include "LoongArch.h"
+#include "LoongArchSelectionDAGInfo.h"
 #include "LoongArchTargetMachine.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
 
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 104e601de044b4..3d6ba8125c0915 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -15,6 +15,7 @@
 #include "LoongArch.h"
 #include "LoongArchMachineFunctionInfo.h"
 #include "LoongArchRegisterInfo.h"
+#include "LoongArchSelectionDAGInfo.h"
 #include "LoongArchSubtarget.h"
 #include "MCTargetDesc/LoongArchBaseInfo.h"
 #include "MCTargetDesc/LoongArchMCTargetDesc.h"
@@ -2685,7 +2686,7 @@ SDValue LoongArchTargetLowering::lowerShiftRightParts(SDValue Op,
 
 // Returns the opcode of the target-specific SDNode that implements the 32-bit
 // form of the given Opcode.
-static LoongArchISD::NodeType getLoongArchWOpcode(unsigned Opcode) {
+static unsigned getLoongArchWOpcode(unsigned Opcode) {
   switch (Opcode) {
   default:
     llvm_unreachable("Unexpected opcode");
@@ -2721,7 +2722,7 @@ static LoongArchISD::NodeType getLoongArchWOpcode(unsigned Opcode) {
 static SDValue customLegalizeToWOp(SDNode *N, SelectionDAG &DAG, int NumOp,
                                    unsigned ExtOpc = ISD::ANY_EXTEND) {
   SDLoc DL(N);
-  LoongArchISD::NodeType WOpcode = getLoongArchWOpcode(N->getOpcode());
+  unsigned WOpcode = getLoongArchWOpcode(N->getOpcode());
   SDValue NewOp0, NewRes;
 
   switch (NumOp) {
@@ -4707,97 +4708,6 @@ bool LoongArchTargetLowering::allowsMisalignedMemoryAccesses(
   return true;
 }
 
-const char *LoongArchTargetLowering::getTargetNodeName(unsigned Opcode) const {
-  switch ((LoongArchISD::NodeType)Opcode) {
-  case LoongArchISD::FIRST_NUMBER:
-    break;
-
-#define NODE_NAME_CASE(node)                                                   \
-  case LoongArchISD::node:                                                     \
-    return "LoongArchISD::" #node;
-
-    // TODO: Add more target-dependent nodes later.
-    NODE_NAME_CASE(CALL)
-    NODE_NAME_CASE(CALL_MEDIUM)
-    NODE_NAME_CASE(CALL_LARGE)
-    NODE_NAME_CASE(RET)
-    NODE_NAME_CASE(TAIL)
-    NODE_NAME_CASE(TAIL_MEDIUM)
-    NODE_NAME_CASE(TAIL_LARGE)
-    NODE_NAME_CASE(SLL_W)
-    NODE_NAME_CASE(SRA_W)
-    NODE_NAME_CASE(SRL_W)
-    NODE_NAME_CASE(BSTRINS)
-    NODE_NAME_CASE(BSTRPICK)
-    NODE_NAME_CASE(MOVGR2FR_W_LA64)
-    NODE_NAME_CASE(MOVFR2GR_S_LA64)
-    NODE_NAME_CASE(FTINT)
-    NODE_NAME_CASE(REVB_2H)
-    NODE_NAME_CASE(REVB_2W)
-    NODE_NAME_CASE(BITREV_4B)
-    NODE_NAME_CASE(BITREV_8B)
-    NODE_NAME_CASE(BITREV_W)
-    NODE_NAME_CASE(ROTR_W)
-    NODE_NAME_CASE(ROTL_W)
-    NODE_NAME_CASE(DIV_W)
-    NODE_NAME_CASE(DIV_WU)
-    NODE_NAME_CASE(MOD_W)
-    NODE_NAME_CASE(MOD_WU)
-    NODE_NAME_CASE(CLZ_W)
-    NODE_NAME_CASE(CTZ_W)
-    NODE_NAME_CASE(DBAR)
-    NODE_NAME_CASE(IBAR)
-    NODE_NAME_CASE(BREAK)
-    NODE_NAME_CASE(SYSCALL)
-    NODE_NAME_CASE(CRC_W_B_W)
-    NODE_NAME_CASE(CRC_W_H_W)
-    NODE_NAME_CASE(CRC_W_W_W)
-    NODE_NAME_CASE(CRC_W_D_W)
-    NODE_NAME_CASE(CRCC_W_B_W)
-    NODE_NAME_CASE(CRCC_W_H_W)
-    NODE_NAME_CASE(CRCC_W_W_W)
-    NODE_NAME_CASE(CRCC_W_D_W)
-    NODE_NAME_CASE(CSRRD)
-    NODE_NAME_CASE(CSRWR)
-    NODE_NAME_CASE(CSRXCHG)
-    NODE_NAME_CASE(IOCSRRD_B)
-    NODE_NAME_CASE(IOCSRRD_H)
-    NODE_NAME_CASE(IOCSRRD_W)
-    NODE_NAME_CASE(IOCSRRD_D)
-    NODE_NAME_CASE(IOCSRWR_B)
-    NODE_NAME_CASE(IOCSRWR_H)
-    NODE_NAME_CASE(IOCSRWR_W)
-    NODE_NAME_CASE(IOCSRWR_D)
-    NODE_NAME_CASE(CPUCFG)
-    NODE_NAME_CASE(MOVGR2FCSR)
-    NODE_NAME_CASE(MOVFCSR2GR)
-    NODE_NAME_CASE(CACOP_D)
-    NODE_NAME_CASE(CACOP_W)
-    NODE_NAME_CASE(VSHUF)
-    NODE_NAME_CASE(VPICKEV)
-    NODE_NAME_CASE(VPICKOD)
-    NODE_NAME_CASE(VPACKEV)
-    NODE_NAME_CASE(VPACKOD)
-    NODE_NAME_CASE(VILVL)
-    NODE_NAME_CASE(VILVH)
-    NODE_NAME_CASE(VSHUF4I)
-    NODE_NAME_CASE(VREPLVEI)
-    NODE_NAME_CASE(VREPLGR2VR)
-    NODE_NAME_CASE(XVPERMI)
-    NODE_NAME_CASE(VPICK_SEXT_ELT)
-    NODE_NAME_CASE(VPICK_ZEXT_ELT)
-    NODE_NAME_CASE(VREPLVE)
-    NODE_NAME_CASE(VALL_ZERO)
-    NODE_NAME_CASE(VANY_ZERO)
-    NODE_NAME_CASE(VALL_NONZERO)
-    NODE_NAME_CASE(VANY_NONZERO)
-    NODE_NAME_CASE(FRECIPE)
-    NODE_NAME_CASE(FRSQRTE)
-  }
-#undef NODE_NAME_CASE
-  return nullptr;
-}
-
 //===----------------------------------------------------------------------===//
 //                     Calling Convention Implementation
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
index e619cb69f33325..0e676f79fb106f 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
@@ -21,137 +21,6 @@
 
 namespace llvm {
 class LoongArchSubtarget;
-namespace LoongArchISD {
-enum NodeType : unsigned {
-  FIRST_NUMBER = ISD::BUILTIN_OP_END,
-
-  // TODO: add more LoongArchISDs
-  CALL,
-  CALL_MEDIUM,
-  CALL_LARGE,
-  RET,
-  TAIL,
-  TAIL_MEDIUM,
-  TAIL_LARGE,
-
-  // 32-bit shifts, directly matching the semantics of the named LoongArch
-  // instructions.
-  SLL_W,
-  SRA_W,
-  SRL_W,
-
-  ROTL_W,
-  ROTR_W,
-
-  // unsigned 32-bit integer division
-  DIV_W,
-  MOD_W,
-  DIV_WU,
-  MOD_WU,
-
-  // FPR<->GPR transfer operations
-  MOVGR2FR_W_LA64,
-  MOVFR2GR_S_LA64,
-  MOVFCSR2GR,
-  MOVGR2FCSR,
-
-  FTINT,
-
-  // Bit counting operations
-  CLZ_W,
-  CTZ_W,
-
-  BSTRINS,
-  BSTRPICK,
-
-  // Byte-swapping and bit-reversal
-  REVB_2H,
-  REVB_2W,
-  BITREV_4B,
-  BITREV_8B,
-  BITREV_W,
-
-  // Intrinsic operations start ============================================
-  BREAK,
-  CACOP_D,
-  CACOP_W,
-  DBAR,
-  IBAR,
-  SYSCALL,
-
-  // CRC check operations
-  CRC_W_B_W,
-  CRC_W_H_W,
-  CRC_W_W_W,
-  CRC_W_D_W,
-  CRCC_W_B_W,
-  CRCC_W_H_W,
-  CRCC_W_W_W,
-  CRCC_W_D_W,
-
-  CSRRD,
-
-  // Write new value to CSR and return old value.
-  // Operand 0: A chain pointer.
-  // Operand 1: The new value to write.
-  // Operand 2: The address of the required CSR.
-  // Result 0: The old value of the CSR.
-  // Result 1: The new chain pointer.
-  CSRWR,
-
-  // Similar to CSRWR but with a write mask.
-  // Operand 0: A chain pointer.
-  // Operand 1: The new value to write.
-  // Operand 2: The write mask.
-  // Operand 3: The address of the required CSR.
-  // Result 0: The old value of the CSR.
-  // Result 1: The new chain pointer.
-  CSRXCHG,
-
-  // IOCSR access operations
-  IOCSRRD_B,
-  IOCSRRD_W,
-  IOCSRRD_H,
-  IOCSRRD_D,
-  IOCSRWR_B,
-  IOCSRWR_H,
-  IOCSRWR_W,
-  IOCSRWR_D,
-
-  // Read CPU configuration information operation
-  CPUCFG,
-
-  // Vector Shuffle
-  VREPLVE,
-  VSHUF,
-  VPICKEV,
-  VPICKOD,
-  VPACKEV,
-  VPACKOD,
-  VILVL,
-  VILVH,
-  VSHUF4I,
-  VREPLVEI,
-  VREPLGR2VR,
-  XVPERMI,
-
-  // Extended vector element extraction
-  VPICK_SEXT_ELT,
-  VPICK_ZEXT_ELT,
-
-  // Vector comparisons
-  VALL_ZERO,
-  VANY_ZERO,
-  VALL_NONZERO,
-  VANY_NONZERO,
-
-  // Floating point approximate reciprocal operation
-  FRECIPE,
-  FRSQRTE
-
-  // Intrinsic operations end =============================================
-};
-} // end namespace LoongArchISD
 
 class LoongArchTargetLowering : public TargetLowering {
   const LoongArchSubtarget &Subtarget;
@@ -171,9 +40,6 @@ class LoongArchTargetLowering : public TargetLowering {
 
   SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
 
-  // This method returns the name of a target specific DAG node.
-  const char *getTargetNodeName(unsigned Opcode) const override;
-
   // Lower incoming arguments, copy physregs into vregs.
   SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
                                bool IsVarArg,
diff --git a/llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.cpp b/llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.cpp
new file mode 100644
index 00000000000000..33a87afdb2b496
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.cpp
@@ -0,0 +1,19 @@
+//===- LoongArchSelectionDAGInfo.cpp --------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "LoongArchSelectionDAGInfo.h"
+
+#define GET_SDNODE_DESC
+#include "LoongArchGenSDNodeInfo.inc"
+
+using namespace llvm;
+
+LoongArchSelectionDAGInfo::LoongArchSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(LoongArchGenSDNodeInfo) {}
+
+LoongArchSelectionDAGInfo::~LoongArchSelectionDAGInfo() = default;
diff --git a/llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.h b/llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.h
new file mode 100644
index 00000000000000..ae6d82889d2ab6
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.h
@@ -0,0 +1,28 @@
+//===- LoongArchSelectionDAGInfo.h ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHSELECTIONDAGINFO_H
+#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHSELECTIONDAGINFO_H
+
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+
+#define GET_SDNODE_ENUM
+#include "LoongArchGenSDNodeInfo.inc"
+
+namespace llvm {
+
+class LoongArchSelectionDAGInfo : public SelectionDAGGenTargetInfo {
+public:
+  LoongArchSelectionDAGInfo();
+
+  ~LoongArchSelectionDAGInfo() override;
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHSELECTIONDAGINFO_H
diff --git a/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp b/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp
index 3acbe4992273a3..3ac3f558c3ce67 100644
--- a/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp
@@ -12,6 +12,7 @@
 
 #include "LoongArchSubtarget.h"
 #include "LoongArchFrameLowering.h"
+#include "LoongArchSelectionDAGInfo.h"
 #include "MCTargetDesc/LoongArchBaseInfo.h"
 
 using namespace llvm;
@@ -95,4 +96,12 @@ LoongArchSubtarget::LoongArchSubtarget(const Triple &TT, StringRef CPU,
     : LoongArchGenSubtargetInfo(TT, CPU, TuneCPU, FS),
       FrameLowering(
           initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
-      InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {}
+      InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {
+  TSInfo = std::make_unique<LoongArchSelectionDAGInfo>();
+}
+
+LoongArchSubtarget::~LoongArchSubtarget() = default;
+
+const SelectionDAGTargetInfo *LoongArchSubtarget::getSelectionDAGInfo() const {
+  return TSInfo.get();
+}
diff --git a/llvm/lib/Target/LoongArch/LoongArchSubtarget.h b/llvm/lib/Target/LoongArch/LoongArchSubtarget.h
index 5e12bafebb0d52..16d06dc06766f2 100644
--- a/llvm/lib/Target/LoongArch/LoongArchSubtarget.h
+++ b/llvm/lib/Target/LoongArch/LoongArchSubtarget.h
@@ -18,7 +18,6 @@
 #include "LoongArchInstrInfo.h"
 #include "LoongArchRegisterInfo.h"
 #include "MCTargetDesc/LoongArchBaseInfo.h"
-#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/Target/TargetMachine.h"
@@ -47,7 +46,7 @@ class LoongArchSubtarget : public LoongArchGenSubtargetInfo {
   LoongArchInstrInfo InstrInfo;
   LoongArchRegisterInfo RegInfo;
   LoongArchTargetLowering TLInfo;
-  SelectionDAGTargetInfo TSInfo;
+  std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
 
   Align PrefFunctionAlignment;
   Align PrefLoopAlignment;
@@ -69,6 +68,8 @@ class LoongArchSubtarget : public LoongArchGenSubtargetInfo {
   LoongArchSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
                      StringRef FS, StringRef ABIName, const TargetMachine &TM);
 
+  ~LoongArchSubtarget() override;
+
   // Parses features string setting specified subtarget options. The
   // definition of this function is auto-generated by tblgen.
   void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
@@ -83,9 +84,8 @@ class LoongArchSubtarget : public LoongArchGenSubtargetInfo {
   const LoongArchTargetLowering *getTargetLowering() const override {
     return &TLInfo;
   }
-  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
-    return &TSInfo;
-  }
+
+  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
 
 #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER)                    \
   bool GETTER() const { return ATTRIBUTE; }

>From 837abbd693d4e9b8b8d914b3b5688722e7f395b6 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 03:11:23 +0300
Subject: [PATCH 14/27] M68k

---
 llvm/lib/Target/M68k/CMakeLists.txt           |  2 +
 llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp     |  2 +-
 llvm/lib/Target/M68k/M68kISelLowering.cpp     | 60 +--------------
 llvm/lib/Target/M68k/M68kISelLowering.h       | 73 -------------------
 llvm/lib/Target/M68k/M68kSelectionDAGInfo.cpp | 32 ++++++++
 llvm/lib/Target/M68k/M68kSelectionDAGInfo.h   | 39 ++++++++++
 llvm/lib/Target/M68k/M68kSubtarget.cpp        | 13 +++-
 llvm/lib/Target/M68k/M68kSubtarget.h          | 12 +--
 8 files changed, 91 insertions(+), 142 deletions(-)
 create mode 100644 llvm/lib/Target/M68k/M68kSelectionDAGInfo.cpp
 create mode 100644 llvm/lib/Target/M68k/M68kSelectionDAGInfo.h

diff --git a/llvm/lib/Target/M68k/CMakeLists.txt b/llvm/lib/Target/M68k/CMakeLists.txt
index 1661dccece3dd8..7005df4fb8a823 100644
--- a/llvm/lib/Target/M68k/CMakeLists.txt
+++ b/llvm/lib/Target/M68k/CMakeLists.txt
@@ -6,6 +6,7 @@ tablegen(LLVM M68kGenGlobalISel.inc       -gen-global-isel)
 tablegen(LLVM M68kGenRegisterInfo.inc     -gen-register-info)
 tablegen(LLVM M68kGenRegisterBank.inc     -gen-register-bank)
 tablegen(LLVM M68kGenInstrInfo.inc        -gen-instr-info)
+tablegen(LLVM M68kGenSDNodeInfo.inc       -gen-sd-node-info)
 tablegen(LLVM M68kGenSubtargetInfo.inc    -gen-subtarget)
 tablegen(LLVM M68kGenMCCodeEmitter.inc    -gen-emitter)
 tablegen(LLVM M68kGenMCPseudoLowering.inc -gen-pseudo-lowering)
@@ -32,6 +33,7 @@ add_llvm_target(M68kCodeGen
   M68kMachineFunction.cpp
   M68kMCInstLower.cpp
   M68kRegisterInfo.cpp
+  M68kSelectionDAGInfo.cpp
   M68kSubtarget.cpp
   M68kTargetMachine.cpp
   M68kTargetObjectFile.cpp
diff --git a/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp b/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp
index 53c144c8fa79a1..9c3d61ec60e008 100644
--- a/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp
+++ b/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp
@@ -15,8 +15,8 @@
 
 #include "M68kMachineFunction.h"
 #include "M68kRegisterInfo.h"
+#include "M68kSelectionDAGInfo.h"
 #include "M68kTargetMachine.h"
-
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
diff --git a/llvm/lib/Target/M68k/M68kISelLowering.cpp b/llvm/lib/Target/M68k/M68kISelLowering.cpp
index ff966baecf27d3..048e381d710472 100644
--- a/llvm/lib/Target/M68k/M68kISelLowering.cpp
+++ b/llvm/lib/Target/M68k/M68kISelLowering.cpp
@@ -15,10 +15,10 @@
 #include "M68kISelLowering.h"
 #include "M68kCallingConv.h"
 #include "M68kMachineFunction.h"
+#include "M68kSelectionDAGInfo.h"
 #include "M68kSubtarget.h"
 #include "M68kTargetMachine.h"
 #include "M68kTargetObjectFile.h"
-
 #include "llvm/ADT/Statistic.h"
 #include "llvm/CodeGen/CallingConvLower.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
@@ -3640,64 +3640,6 @@ SDValue M68kTargetLowering::PerformDAGCombine(SDNode *N,
   return SDValue();
 }
 
-//===----------------------------------------------------------------------===//
-// M68kISD Node Names
-//===----------------------------------------------------------------------===//
-const char *M68kTargetLowering::getTargetNodeName(unsigned Opcode) const {
-  switch (Opcode) {
-  case M68kISD::CALL:
-    return "M68kISD::CALL";
-  case M68kISD::TAIL_CALL:
-    return "M68kISD::TAIL_CALL";
-  case M68kISD::RET:
-    return "M68kISD::RET";
-  case M68kISD::TC_RETURN:
-    return "M68kISD::TC_RETURN";
-  case M68kISD::ADD:
-    return "M68kISD::ADD";
-  case M68kISD::SUB:
-    return "M68kISD::SUB";
-  case M68kISD::ADDX:
-    return "M68kISD::ADDX";
-  case M68kISD::SUBX:
-    return "M68kISD::SUBX";
-  case M68kISD::SMUL:
-    return "M68kISD::SMUL";
-  case M68kISD::UMUL:
-    return "M68kISD::UMUL";
-  case M68kISD::OR:
-    return "M68kISD::OR";
-  case M68kISD::XOR:
-    return "M68kISD::XOR";
-  case M68kISD::AND:
-    return "M68kISD::AND";
-  case M68kISD::CMP:
-    return "M68kISD::CMP";
-  case M68kISD::BTST:
-    return "M68kISD::BTST";
-  case M68kISD::SELECT:
-    return "M68kISD::SELECT";
-  case M68kISD::CMOV:
-    return "M68kISD::CMOV";
-  case M68kISD::BRCOND:
-    return "M68kISD::BRCOND";
-  case M68kISD::SETCC:
-    return "M68kISD::SETCC";
-  case M68kISD::SETCC_CARRY:
-    return "M68kISD::SETCC_CARRY";
-  case M68kISD::GLOBAL_BASE_REG:
-    return "M68kISD::GLOBAL_BASE_REG";
-  case M68kISD::Wrapper:
-    return "M68kISD::Wrapper";
-  case M68kISD::WrapperPC:
-    return "M68kISD::WrapperPC";
-  case M68kISD::SEG_ALLOCA:
-    return "M68kISD::SEG_ALLOCA";
-  default:
-    return NULL;
-  }
-}
-
 CCAssignFn *M68kTargetLowering::getCCAssignFn(CallingConv::ID CC, bool Return,
                                               bool IsVarArg) const {
   if (Return)
diff --git a/llvm/lib/Target/M68k/M68kISelLowering.h b/llvm/lib/Target/M68k/M68kISelLowering.h
index d00907775f9280..2a2da580fe6e7b 100644
--- a/llvm/lib/Target/M68k/M68kISelLowering.h
+++ b/llvm/lib/Target/M68k/M68kISelLowering.h
@@ -25,77 +25,6 @@
 #include <deque>
 
 namespace llvm {
-namespace M68kISD {
-
-/// M68k Specific DAG nodes
-enum NodeType {
-  /// Start the numbering from where ISD NodeType finishes.
-  FIRST_NUMBER = ISD::BUILTIN_OP_END,
-
-  CALL,
-  RET,
-  TAIL_CALL,
-  TC_RETURN,
-
-  /// M68k compare and logical compare instructions. Subtracts the source
-  /// operand from the destination data register and sets the condition
-  /// codes according to the result. Immediate always goes first.
-  CMP,
-
-  /// M68k bit-test instructions.
-  BTST,
-
-  /// M68k Select
-  SELECT,
-
-  /// M68k SetCC. Operand 0 is condition code, and operand 1 is the CCR
-  /// operand, usually produced by a CMP instruction.
-  SETCC,
-
-  // Same as SETCC except it's materialized with a subx and the value is all
-  // one's or all zero's.
-  SETCC_CARRY, // R = carry_bit ? ~0 : 0
-
-  /// M68k conditional moves. Operand 0 and operand 1 are the two values
-  /// to select from. Operand 2 is the condition code, and operand 3 is the
-  /// flag operand produced by a CMP or TEST instruction. It also writes a
-  /// flag result.
-  CMOV,
-
-  /// M68k conditional branches. Operand 0 is the chain operand, operand 1
-  /// is the block to branch if condition is true, operand 2 is the
-  /// condition code, and operand 3 is the flag operand produced by a CMP
-  /// or TEST instruction.
-  BRCOND,
-
-  // Arithmetic operations with CCR results.
-  ADD,
-  SUB,
-  ADDX,
-  SUBX,
-  SMUL,
-  UMUL,
-  OR,
-  XOR,
-  AND,
-
-  // GlobalBaseReg,
-  GLOBAL_BASE_REG,
-
-  /// A wrapper node for TargetConstantPool,
-  /// TargetExternalSymbol, and TargetGlobalAddress.
-  Wrapper,
-
-  /// Special wrapper used under M68k PIC mode for PC
-  /// relative displacements.
-  WrapperPC,
-
-  // For allocating variable amounts of stack space when using
-  // segmented stacks. Check if the current stacklet has enough space, and
-  // falls back to heap allocation if not.
-  SEG_ALLOCA,
-};
-} // namespace M68kISD
 
 /// Define some predicates that are used for node matching.
 namespace M68k {
@@ -124,8 +53,6 @@ class M68kTargetLowering : public TargetLowering {
   static const M68kTargetLowering *create(const M68kTargetMachine &TM,
                                           const M68kSubtarget &STI);
 
-  const char *getTargetNodeName(unsigned Opcode) const override;
-
   /// Return the value type to use for ISD::SETCC.
   EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
                          EVT VT) const override;
diff --git a/llvm/lib/Target/M68k/M68kSelectionDAGInfo.cpp b/llvm/lib/Target/M68k/M68kSelectionDAGInfo.cpp
new file mode 100644
index 00000000000000..d455561dbaf210
--- /dev/null
+++ b/llvm/lib/Target/M68k/M68kSelectionDAGInfo.cpp
@@ -0,0 +1,32 @@
+//===- M68kSelectionDAGInfo.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "M68kSelectionDAGInfo.h"
+
+#define GET_SDNODE_DESC
+#include "M68kGenSDNodeInfo.inc"
+
+using namespace llvm;
+
+M68kSelectionDAGInfo::M68kSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(M68kGenSDNodeInfo) {}
+
+M68kSelectionDAGInfo::~M68kSelectionDAGInfo() = default;
+
+const char *M68kSelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
+  switch (static_cast<M68kISD::NodeType>(Opcode)) {
+  case M68kISD::TAIL_CALL:
+    return "M68kISD::TAIL_CALL";
+  case M68kISD::SELECT:
+    return "M68kISD::SELECT";
+  case M68kISD::GLOBAL_BASE_REG:
+    return "M68kISD::GLOBAL_BASE_REG";
+  }
+
+  return SelectionDAGGenTargetInfo::getTargetNodeName(Opcode);
+}
diff --git a/llvm/lib/Target/M68k/M68kSelectionDAGInfo.h b/llvm/lib/Target/M68k/M68kSelectionDAGInfo.h
new file mode 100644
index 00000000000000..aed1844a929ae6
--- /dev/null
+++ b/llvm/lib/Target/M68k/M68kSelectionDAGInfo.h
@@ -0,0 +1,39 @@
+//===- M68kSelectionDAGInfo.h -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_M68K_M68KSELECTIONDAGINFO_H
+#define LLVM_LIB_TARGET_M68K_M68KSELECTIONDAGINFO_H
+
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+
+#define GET_SDNODE_ENUM
+#include "M68kGenSDNodeInfo.inc"
+
+namespace llvm {
+namespace M68kISD {
+
+enum NodeType : unsigned {
+  TAIL_CALL = GENERATED_OPCODE_END,
+  SELECT,
+  GLOBAL_BASE_REG,
+};
+
+} // namespace M68kISD
+
+class M68kSelectionDAGInfo : public SelectionDAGGenTargetInfo {
+public:
+  M68kSelectionDAGInfo();
+
+  ~M68kSelectionDAGInfo() override;
+
+  const char *getTargetNodeName(unsigned Opcode) const override;
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_M68K_M68KSELECTIONDAGINFO_H
diff --git a/llvm/lib/Target/M68k/M68kSubtarget.cpp b/llvm/lib/Target/M68k/M68kSubtarget.cpp
index 53ec574ae5596c..59d865ff1f4a96 100644
--- a/llvm/lib/Target/M68k/M68kSubtarget.cpp
+++ b/llvm/lib/Target/M68k/M68kSubtarget.cpp
@@ -15,12 +15,11 @@
 #include "GISel/M68kCallLowering.h"
 #include "GISel/M68kLegalizerInfo.h"
 #include "GISel/M68kRegisterBankInfo.h"
-
 #include "M68k.h"
 #include "M68kMachineFunction.h"
 #include "M68kRegisterInfo.h"
+#include "M68kSelectionDAGInfo.h"
 #include "M68kTargetMachine.h"
-
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/Function.h"
@@ -50,10 +49,12 @@ void M68kSubtarget::anchor() {}
 
 M68kSubtarget::M68kSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
                              const M68kTargetMachine &TM)
-    : M68kGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), TM(TM), TSInfo(),
+    : M68kGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), TM(TM),
       InstrInfo(initializeSubtargetDependencies(CPU, TT, FS, TM)),
       FrameLowering(*this, this->getStackAlignment()), TLInfo(TM, *this),
       TargetTriple(TT) {
+  TSInfo = std::make_unique<M68kSelectionDAGInfo>();
+
   CallLoweringInfo.reset(new M68kCallLowering(*getTargetLowering()));
   Legalizer.reset(new M68kLegalizerInfo(*this));
 
@@ -62,6 +63,12 @@ M68kSubtarget::M68kSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
   InstSelector.reset(createM68kInstructionSelector(TM, *this, *RBI));
 }
 
+M68kSubtarget::~M68kSubtarget() = default;
+
+const SelectionDAGTargetInfo *M68kSubtarget::getSelectionDAGInfo() const {
+  return TSInfo.get();
+}
+
 const CallLowering *M68kSubtarget::getCallLowering() const {
   return CallLoweringInfo.get();
 }
diff --git a/llvm/lib/Target/M68k/M68kSubtarget.h b/llvm/lib/Target/M68k/M68kSubtarget.h
index c08a9786fb27ba..16ca7d2e6d0fda 100644
--- a/llvm/lib/Target/M68k/M68kSubtarget.h
+++ b/llvm/lib/Target/M68k/M68kSubtarget.h
@@ -22,7 +22,6 @@
 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
 #include "llvm/CodeGen/RegisterBankInfo.h"
-#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/MC/MCInstrItineraries.h"
@@ -63,7 +62,6 @@ class M68kSubtarget : public M68kGenSubtargetInfo {
 
   const M68kTargetMachine &TM;
 
-  SelectionDAGTargetInfo TSInfo;
   M68kInstrInfo InstrInfo;
   M68kFrameLowering FrameLowering;
   M68kTargetLowering TLInfo;
@@ -80,6 +78,8 @@ class M68kSubtarget : public M68kGenSubtargetInfo {
   M68kSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
                 const M68kTargetMachine &_TM);
 
+  ~M68kSubtarget() override;
+
   /// Parses features string setting specified subtarget options.  Definition
   /// of function is auto generated by tblgen.
   void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
@@ -148,10 +148,6 @@ class M68kSubtarget : public M68kGenSubtargetInfo {
                                                  StringRef FS,
                                                  const M68kTargetMachine &TM);
 
-  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
-    return &TSInfo;
-  }
-
   const M68kInstrInfo *getInstrInfo() const override { return &InstrInfo; }
 
   const M68kFrameLowering *getFrameLowering() const override {
@@ -171,6 +167,9 @@ class M68kSubtarget : public M68kGenSubtargetInfo {
   }
 
 protected:
+  // SelectionDAGISel related APIs.
+  std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
+
   // GlobalISel related APIs.
   std::unique_ptr<CallLowering> CallLoweringInfo;
   std::unique_ptr<InstructionSelector> InstSelector;
@@ -178,6 +177,7 @@ class M68kSubtarget : public M68kGenSubtargetInfo {
   std::unique_ptr<RegisterBankInfo> RegBankInfo;
 
 public:
+  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
   const CallLowering *getCallLowering() const override;
   InstructionSelector *getInstructionSelector() const override;
   const LegalizerInfo *getLegalizerInfo() const override;

>From fd62222399f991322183860e0ffcfe9ad9660a88 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 01:02:01 +0300
Subject: [PATCH 15/27] Mips

---
 llvm/lib/Target/Mips/CMakeLists.txt           |   1 +
 llvm/lib/Target/Mips/MipsISelLowering.cpp     | 122 ----------
 llvm/lib/Target/Mips/MipsISelLowering.h       | 214 +-----------------
 llvm/lib/Target/Mips/MipsSelectionDAGInfo.cpp |  44 +++-
 llvm/lib/Target/Mips/MipsSelectionDAGInfo.h   |  33 ++-
 5 files changed, 65 insertions(+), 349 deletions(-)

diff --git a/llvm/lib/Target/Mips/CMakeLists.txt b/llvm/lib/Target/Mips/CMakeLists.txt
index 21d1765107ae6f..6d59a21ad137f4 100644
--- a/llvm/lib/Target/Mips/CMakeLists.txt
+++ b/llvm/lib/Target/Mips/CMakeLists.txt
@@ -16,6 +16,7 @@ tablegen(LLVM MipsGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM MipsGenMCPseudoLowering.inc -gen-pseudo-lowering)
 tablegen(LLVM MipsGenRegisterBank.inc -gen-register-bank)
 tablegen(LLVM MipsGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM MipsGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM MipsGenSubtargetInfo.inc -gen-subtarget)
 tablegen(LLVM MipsGenExegesis.inc -gen-exegesis)
 
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index d5f38c414e703d..2d783b75af0ab1 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -171,128 +171,6 @@ SDValue MipsTargetLowering::getTargetNode(ConstantPoolSDNode *N, EVT Ty,
                                    N->getOffset(), Flag);
 }
 
-const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {
-  switch ((MipsISD::NodeType)Opcode) {
-  case MipsISD::FIRST_NUMBER:      break;
-  case MipsISD::JmpLink:           return "MipsISD::JmpLink";
-  case MipsISD::TailCall:          return "MipsISD::TailCall";
-  case MipsISD::Highest:           return "MipsISD::Highest";
-  case MipsISD::Higher:            return "MipsISD::Higher";
-  case MipsISD::Hi:                return "MipsISD::Hi";
-  case MipsISD::Lo:                return "MipsISD::Lo";
-  case MipsISD::GotHi:             return "MipsISD::GotHi";
-  case MipsISD::TlsHi:             return "MipsISD::TlsHi";
-  case MipsISD::GPRel:             return "MipsISD::GPRel";
-  case MipsISD::ThreadPointer:     return "MipsISD::ThreadPointer";
-  case MipsISD::Ret:               return "MipsISD::Ret";
-  case MipsISD::ERet:              return "MipsISD::ERet";
-  case MipsISD::EH_RETURN:         return "MipsISD::EH_RETURN";
-  case MipsISD::FAbs:              return "MipsISD::FAbs";
-  case MipsISD::FMS:               return "MipsISD::FMS";
-  case MipsISD::FPBrcond:          return "MipsISD::FPBrcond";
-  case MipsISD::FPCmp:             return "MipsISD::FPCmp";
-  case MipsISD::FSELECT:           return "MipsISD::FSELECT";
-  case MipsISD::MTC1_D64:          return "MipsISD::MTC1_D64";
-  case MipsISD::CMovFP_T:          return "MipsISD::CMovFP_T";
-  case MipsISD::CMovFP_F:          return "MipsISD::CMovFP_F";
-  case MipsISD::TruncIntFP:        return "MipsISD::TruncIntFP";
-  case MipsISD::MFHI:              return "MipsISD::MFHI";
-  case MipsISD::MFLO:              return "MipsISD::MFLO";
-  case MipsISD::MTLOHI:            return "MipsISD::MTLOHI";
-  case MipsISD::Mult:              return "MipsISD::Mult";
-  case MipsISD::Multu:             return "MipsISD::Multu";
-  case MipsISD::MAdd:              return "MipsISD::MAdd";
-  case MipsISD::MAddu:             return "MipsISD::MAddu";
-  case MipsISD::MSub:              return "MipsISD::MSub";
-  case MipsISD::MSubu:             return "MipsISD::MSubu";
-  case MipsISD::DivRem:            return "MipsISD::DivRem";
-  case MipsISD::DivRemU:           return "MipsISD::DivRemU";
-  case MipsISD::DivRem16:          return "MipsISD::DivRem16";
-  case MipsISD::DivRemU16:         return "MipsISD::DivRemU16";
-  case MipsISD::BuildPairF64:      return "MipsISD::BuildPairF64";
-  case MipsISD::ExtractElementF64: return "MipsISD::ExtractElementF64";
-  case MipsISD::Wrapper:           return "MipsISD::Wrapper";
-  case MipsISD::DynAlloc:          return "MipsISD::DynAlloc";
-  case MipsISD::Sync:              return "MipsISD::Sync";
-  case MipsISD::Ext:               return "MipsISD::Ext";
-  case MipsISD::Ins:               return "MipsISD::Ins";
-  case MipsISD::CIns:              return "MipsISD::CIns";
-  case MipsISD::LWL:               return "MipsISD::LWL";
-  case MipsISD::LWR:               return "MipsISD::LWR";
-  case MipsISD::SWL:               return "MipsISD::SWL";
-  case MipsISD::SWR:               return "MipsISD::SWR";
-  case MipsISD::LDL:               return "MipsISD::LDL";
-  case MipsISD::LDR:               return "MipsISD::LDR";
-  case MipsISD::SDL:               return "MipsISD::SDL";
-  case MipsISD::SDR:               return "MipsISD::SDR";
-  case MipsISD::EXTP:              return "MipsISD::EXTP";
-  case MipsISD::EXTPDP:            return "MipsISD::EXTPDP";
-  case MipsISD::EXTR_S_H:          return "MipsISD::EXTR_S_H";
-  case MipsISD::EXTR_W:            return "MipsISD::EXTR_W";
-  case MipsISD::EXTR_R_W:          return "MipsISD::EXTR_R_W";
-  case MipsISD::EXTR_RS_W:         return "MipsISD::EXTR_RS_W";
-  case MipsISD::SHILO:             return "MipsISD::SHILO";
-  case MipsISD::MTHLIP:            return "MipsISD::MTHLIP";
-  case MipsISD::MULSAQ_S_W_PH:     return "MipsISD::MULSAQ_S_W_PH";
-  case MipsISD::MAQ_S_W_PHL:       return "MipsISD::MAQ_S_W_PHL";
-  case MipsISD::MAQ_S_W_PHR:       return "MipsISD::MAQ_S_W_PHR";
-  case MipsISD::MAQ_SA_W_PHL:      return "MipsISD::MAQ_SA_W_PHL";
-  case MipsISD::MAQ_SA_W_PHR:      return "MipsISD::MAQ_SA_W_PHR";
-  case MipsISD::DOUBLE_SELECT_I:   return "MipsISD::DOUBLE_SELECT_I";
-  case MipsISD::DOUBLE_SELECT_I64: return "MipsISD::DOUBLE_SELECT_I64";
-  case MipsISD::DPAU_H_QBL:        return "MipsISD::DPAU_H_QBL";
-  case MipsISD::DPAU_H_QBR:        return "MipsISD::DPAU_H_QBR";
-  case MipsISD::DPSU_H_QBL:        return "MipsISD::DPSU_H_QBL";
-  case MipsISD::DPSU_H_QBR:        return "MipsISD::DPSU_H_QBR";
-  case MipsISD::DPAQ_S_W_PH:       return "MipsISD::DPAQ_S_W_PH";
-  case MipsISD::DPSQ_S_W_PH:       return "MipsISD::DPSQ_S_W_PH";
-  case MipsISD::DPAQ_SA_L_W:       return "MipsISD::DPAQ_SA_L_W";
-  case MipsISD::DPSQ_SA_L_W:       return "MipsISD::DPSQ_SA_L_W";
-  case MipsISD::DPA_W_PH:          return "MipsISD::DPA_W_PH";
-  case MipsISD::DPS_W_PH:          return "MipsISD::DPS_W_PH";
-  case MipsISD::DPAQX_S_W_PH:      return "MipsISD::DPAQX_S_W_PH";
-  case MipsISD::DPAQX_SA_W_PH:     return "MipsISD::DPAQX_SA_W_PH";
-  case MipsISD::DPAX_W_PH:         return "MipsISD::DPAX_W_PH";
-  case MipsISD::DPSX_W_PH:         return "MipsISD::DPSX_W_PH";
-  case MipsISD::DPSQX_S_W_PH:      return "MipsISD::DPSQX_S_W_PH";
-  case MipsISD::DPSQX_SA_W_PH:     return "MipsISD::DPSQX_SA_W_PH";
-  case MipsISD::MULSA_W_PH:        return "MipsISD::MULSA_W_PH";
-  case MipsISD::MULT:              return "MipsISD::MULT";
-  case MipsISD::MULTU:             return "MipsISD::MULTU";
-  case MipsISD::MADD_DSP:          return "MipsISD::MADD_DSP";
-  case MipsISD::MADDU_DSP:         return "MipsISD::MADDU_DSP";
-  case MipsISD::MSUB_DSP:          return "MipsISD::MSUB_DSP";
-  case MipsISD::MSUBU_DSP:         return "MipsISD::MSUBU_DSP";
-  case MipsISD::SHLL_DSP:          return "MipsISD::SHLL_DSP";
-  case MipsISD::SHRA_DSP:          return "MipsISD::SHRA_DSP";
-  case MipsISD::SHRL_DSP:          return "MipsISD::SHRL_DSP";
-  case MipsISD::SETCC_DSP:         return "MipsISD::SETCC_DSP";
-  case MipsISD::SELECT_CC_DSP:     return "MipsISD::SELECT_CC_DSP";
-  case MipsISD::VALL_ZERO:         return "MipsISD::VALL_ZERO";
-  case MipsISD::VANY_ZERO:         return "MipsISD::VANY_ZERO";
-  case MipsISD::VALL_NONZERO:      return "MipsISD::VALL_NONZERO";
-  case MipsISD::VANY_NONZERO:      return "MipsISD::VANY_NONZERO";
-  case MipsISD::VCEQ:              return "MipsISD::VCEQ";
-  case MipsISD::VCLE_S:            return "MipsISD::VCLE_S";
-  case MipsISD::VCLE_U:            return "MipsISD::VCLE_U";
-  case MipsISD::VCLT_S:            return "MipsISD::VCLT_S";
-  case MipsISD::VCLT_U:            return "MipsISD::VCLT_U";
-  case MipsISD::VEXTRACT_SEXT_ELT: return "MipsISD::VEXTRACT_SEXT_ELT";
-  case MipsISD::VEXTRACT_ZEXT_ELT: return "MipsISD::VEXTRACT_ZEXT_ELT";
-  case MipsISD::VNOR:              return "MipsISD::VNOR";
-  case MipsISD::VSHF:              return "MipsISD::VSHF";
-  case MipsISD::SHF:               return "MipsISD::SHF";
-  case MipsISD::ILVEV:             return "MipsISD::ILVEV";
-  case MipsISD::ILVOD:             return "MipsISD::ILVOD";
-  case MipsISD::ILVL:              return "MipsISD::ILVL";
-  case MipsISD::ILVR:              return "MipsISD::ILVR";
-  case MipsISD::PCKEV:             return "MipsISD::PCKEV";
-  case MipsISD::PCKOD:             return "MipsISD::PCKOD";
-  case MipsISD::INSVE:             return "MipsISD::INSVE";
-  }
-  return nullptr;
-}
-
 MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
                                        const MipsSubtarget &STI)
     : TargetLowering(TM), Subtarget(STI), ABI(TM.getABI()) {
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h
index ae56bf7c8a2e72..788adb11e50cbd 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -18,6 +18,7 @@
 #include "MCTargetDesc/MipsBaseInfo.h"
 #include "MCTargetDesc/MipsMCTargetDesc.h"
 #include "Mips.h"
+#include "MipsSelectionDAGInfo.h"
 #include "llvm/CodeGen/CallingConvLower.h"
 #include "llvm/CodeGen/ISDOpcodes.h"
 #include "llvm/CodeGen/MachineMemOperand.h"
@@ -50,215 +51,6 @@ class MipsTargetMachine;
 class TargetLibraryInfo;
 class TargetRegisterClass;
 
-  namespace MipsISD {
-
-    enum NodeType : unsigned {
-      // Start the numbering from where ISD NodeType finishes.
-      FIRST_NUMBER = ISD::BUILTIN_OP_END,
-
-      // Jump and link (call)
-      JmpLink,
-
-      // Tail call
-      TailCall,
-
-      // Get the Highest (63-48) 16 bits from a 64-bit immediate
-      Highest,
-
-      // Get the Higher (47-32) 16 bits from a 64-bit immediate
-      Higher,
-
-      // Get the High 16 bits from a 32/64-bit immediate
-      // No relation with Mips Hi register
-      Hi,
-
-      // Get the Lower 16 bits from a 32/64-bit immediate
-      // No relation with Mips Lo register
-      Lo,
-
-      // Get the High 16 bits from a 32 bit immediate for accessing the GOT.
-      GotHi,
-
-      // Get the High 16 bits from a 32-bit immediate for accessing TLS.
-      TlsHi,
-
-      // Handle gp_rel (small data/bss sections) relocation.
-      GPRel,
-
-      // Thread Pointer
-      ThreadPointer,
-
-      // Vector Floating Point Multiply and Subtract
-      FMS,
-
-      // Floating Point Branch Conditional
-      FPBrcond,
-
-      // Floating Point Compare
-      FPCmp,
-
-      // Floating point Abs
-      FAbs,
-
-      // Floating point select
-      FSELECT,
-
-      // Node used to generate an MTC1 i32 to f64 instruction
-      MTC1_D64,
-
-      // Floating Point Conditional Moves
-      CMovFP_T,
-      CMovFP_F,
-
-      // FP-to-int truncation node.
-      TruncIntFP,
-
-      // Return
-      Ret,
-
-      // Interrupt, exception, error trap Return
-      ERet,
-
-      // Software Exception Return.
-      EH_RETURN,
-
-      // Node used to extract integer from accumulator.
-      MFHI,
-      MFLO,
-
-      // Node used to insert integers to accumulator.
-      MTLOHI,
-
-      // Mult nodes.
-      Mult,
-      Multu,
-
-      // MAdd/Sub nodes
-      MAdd,
-      MAddu,
-      MSub,
-      MSubu,
-
-      // DivRem(u)
-      DivRem,
-      DivRemU,
-      DivRem16,
-      DivRemU16,
-
-      BuildPairF64,
-      ExtractElementF64,
-
-      Wrapper,
-
-      DynAlloc,
-
-      Sync,
-
-      Ext,
-      Ins,
-      CIns,
-
-      // EXTR.W intrinsic nodes.
-      EXTP,
-      EXTPDP,
-      EXTR_S_H,
-      EXTR_W,
-      EXTR_R_W,
-      EXTR_RS_W,
-      SHILO,
-      MTHLIP,
-
-      // DPA.W intrinsic nodes.
-      MULSAQ_S_W_PH,
-      MAQ_S_W_PHL,
-      MAQ_S_W_PHR,
-      MAQ_SA_W_PHL,
-      MAQ_SA_W_PHR,
-      DPAU_H_QBL,
-      DPAU_H_QBR,
-      DPSU_H_QBL,
-      DPSU_H_QBR,
-      DPAQ_S_W_PH,
-      DPSQ_S_W_PH,
-      DPAQ_SA_L_W,
-      DPSQ_SA_L_W,
-      DPA_W_PH,
-      DPS_W_PH,
-      DPAQX_S_W_PH,
-      DPAQX_SA_W_PH,
-      DPAX_W_PH,
-      DPSX_W_PH,
-      DPSQX_S_W_PH,
-      DPSQX_SA_W_PH,
-      MULSA_W_PH,
-
-      MULT,
-      MULTU,
-      MADD_DSP,
-      MADDU_DSP,
-      MSUB_DSP,
-      MSUBU_DSP,
-
-      // DSP shift nodes.
-      SHLL_DSP,
-      SHRA_DSP,
-      SHRL_DSP,
-
-      // DSP setcc and select_cc nodes.
-      SETCC_DSP,
-      SELECT_CC_DSP,
-
-      // Vector comparisons.
-      // These take a vector and return a boolean.
-      VALL_ZERO,
-      VANY_ZERO,
-      VALL_NONZERO,
-      VANY_NONZERO,
-
-      // These take a vector and return a vector bitmask.
-      VCEQ,
-      VCLE_S,
-      VCLE_U,
-      VCLT_S,
-      VCLT_U,
-
-      // Vector Shuffle with mask as an operand
-      VSHF,  // Generic shuffle
-      SHF,   // 4-element set shuffle.
-      ILVEV, // Interleave even elements
-      ILVOD, // Interleave odd elements
-      ILVL,  // Interleave left elements
-      ILVR,  // Interleave right elements
-      PCKEV, // Pack even elements
-      PCKOD, // Pack odd elements
-
-      // Vector Lane Copy
-      INSVE, // Copy element from one vector to another
-
-      // Combined (XOR (OR $a, $b), -1)
-      VNOR,
-
-      // Extended vector element extraction
-      VEXTRACT_SEXT_ELT,
-      VEXTRACT_ZEXT_ELT,
-
-      // Double select nodes for machines without conditional-move.
-      DOUBLE_SELECT_I,
-      DOUBLE_SELECT_I64,
-
-      // Load/Store Left/Right nodes.
-      LWL,
-      LWR,
-      SWL,
-      SWR,
-      LDL,
-      LDR,
-      SDL,
-      SDR
-    };
-
-  } // ene namespace MipsISD
-
   //===--------------------------------------------------------------------===//
   // TargetLowering Implementation
   //===--------------------------------------------------------------------===//
@@ -329,10 +121,6 @@ class TargetRegisterClass;
     void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,
                             SelectionDAG &DAG) const override;
 
-    /// getTargetNodeName - This method returns the name of a target specific
-    //  DAG node.
-    const char *getTargetNodeName(unsigned Opcode) const override;
-
     /// getSetCCResultType - get the ISD::SETCC result ValueType
     EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
                            EVT VT) const override;
diff --git a/llvm/lib/Target/Mips/MipsSelectionDAGInfo.cpp b/llvm/lib/Target/Mips/MipsSelectionDAGInfo.cpp
index 03132c66b9273f..95d0eb61a239e9 100644
--- a/llvm/lib/Target/Mips/MipsSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsSelectionDAGInfo.cpp
@@ -7,25 +7,45 @@
 //===----------------------------------------------------------------------===//
 
 #include "MipsSelectionDAGInfo.h"
-#include "MipsISelLowering.h"
+
+#define GET_SDNODE_DESC
+#include "MipsGenSDNodeInfo.inc"
 
 using namespace llvm;
 
+MipsSelectionDAGInfo::MipsSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(MipsGenSDNodeInfo) {}
+
 MipsSelectionDAGInfo::~MipsSelectionDAGInfo() = default;
 
-bool MipsSelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
+const char *MipsSelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
+  // These nodes don't have corresponding entries in *.td files yet.
   switch (static_cast<MipsISD::NodeType>(Opcode)) {
+    // clang-format off
+  case MipsISD::FAbs:              return "MipsISD::FAbs";
+  case MipsISD::DynAlloc:          return "MipsISD::DynAlloc";
+  case MipsISD::DOUBLE_SELECT_I:   return "MipsISD::DOUBLE_SELECT_I";
+  case MipsISD::DOUBLE_SELECT_I64: return "MipsISD::DOUBLE_SELECT_I64";
+  case MipsISD::VCEQ:              return "MipsISD::VCEQ";
+  case MipsISD::VCLE_S:            return "MipsISD::VCLE_S";
+  case MipsISD::VCLE_U:            return "MipsISD::VCLE_U";
+  case MipsISD::VCLT_S:            return "MipsISD::VCLT_S";
+  case MipsISD::VCLT_U:            return "MipsISD::VCLT_U";
+    // clang-format on
+  }
+
+  return SelectionDAGGenTargetInfo::getTargetNodeName(Opcode);
+}
+
+void MipsSelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
+                                            const SDNode *N) const {
+  switch (N->getOpcode()) {
   default:
     break;
-  case MipsISD::LWL:
-  case MipsISD::LWR:
-  case MipsISD::SWL:
-  case MipsISD::SWR:
-  case MipsISD::LDL:
-  case MipsISD::LDR:
-  case MipsISD::SDL:
-  case MipsISD::SDR:
-    return true;
+  case MipsISD::ERet:
+    // invalid number of operands; expected at most 2, got 3
+    return;
   }
-  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+
+  SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
 }
diff --git a/llvm/lib/Target/Mips/MipsSelectionDAGInfo.h b/llvm/lib/Target/Mips/MipsSelectionDAGInfo.h
index cdf203774a29d1..e819a1a9e8801e 100644
--- a/llvm/lib/Target/Mips/MipsSelectionDAGInfo.h
+++ b/llvm/lib/Target/Mips/MipsSelectionDAGInfo.h
@@ -11,13 +11,42 @@
 
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 
+#define GET_SDNODE_ENUM
+#include "MipsGenSDNodeInfo.inc"
+
 namespace llvm {
+namespace MipsISD {
+
+enum NodeType : unsigned {
+  // Floating point Abs
+  FAbs = GENERATED_OPCODE_END,
+
+  DynAlloc,
 
-class MipsSelectionDAGInfo : public SelectionDAGTargetInfo {
+  // These take a vector and return a vector bitmask.
+  VCEQ,
+  VCLE_S,
+  VCLE_U,
+  VCLT_S,
+  VCLT_U,
+
+  // Double select nodes for machines without conditional-move.
+  DOUBLE_SELECT_I,
+  DOUBLE_SELECT_I64,
+};
+
+} // namespace MipsISD
+
+class MipsSelectionDAGInfo : public SelectionDAGGenTargetInfo {
 public:
+  MipsSelectionDAGInfo();
+
   ~MipsSelectionDAGInfo() override;
 
-  bool isTargetMemoryOpcode(unsigned Opcode) const override;
+  const char *getTargetNodeName(unsigned Opcode) const override;
+
+  void verifyTargetNode(const SelectionDAG &DAG,
+                        const SDNode *N) const override;
 };
 
 } // namespace llvm

>From e5f530a4261840b2cff09b02e849fc5414b69d54 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 03:11:28 +0300
Subject: [PATCH 16/27] MSP430

---
 llvm/lib/Target/MSP430/CMakeLists.txt         |  2 +
 llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp |  1 +
 llvm/lib/Target/MSP430/MSP430ISelLowering.cpp | 22 +-------
 llvm/lib/Target/MSP430/MSP430ISelLowering.h   | 54 -------------------
 .../Target/MSP430/MSP430SelectionDAGInfo.cpp  | 19 +++++++
 .../Target/MSP430/MSP430SelectionDAGInfo.h    | 28 ++++++++++
 llvm/lib/Target/MSP430/MSP430Subtarget.cpp    | 11 +++-
 llvm/lib/Target/MSP430/MSP430Subtarget.h      | 10 ++--
 8 files changed, 66 insertions(+), 81 deletions(-)
 create mode 100644 llvm/lib/Target/MSP430/MSP430SelectionDAGInfo.cpp
 create mode 100644 llvm/lib/Target/MSP430/MSP430SelectionDAGInfo.h

diff --git a/llvm/lib/Target/MSP430/CMakeLists.txt b/llvm/lib/Target/MSP430/CMakeLists.txt
index 1dfe8635acb32b..4081d3472fd785 100644
--- a/llvm/lib/Target/MSP430/CMakeLists.txt
+++ b/llvm/lib/Target/MSP430/CMakeLists.txt
@@ -10,6 +10,7 @@ tablegen(LLVM MSP430GenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM MSP430GenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM MSP430GenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM MSP430GenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM MSP430GenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM MSP430GenSubtargetInfo.inc -gen-subtarget)
 
 add_public_tablegen_target(MSP430CommonTableGen)
@@ -22,6 +23,7 @@ add_llvm_target(MSP430CodeGen
   MSP430FrameLowering.cpp
   MSP430MachineFunctionInfo.cpp
   MSP430RegisterInfo.cpp
+  MSP430SelectionDAGInfo.cpp
   MSP430Subtarget.cpp
   MSP430TargetMachine.cpp
   MSP430AsmPrinter.cpp
diff --git a/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
index 85ebe71fa967d2..2834a2ebb0cc65 100644
--- a/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "MSP430.h"
+#include "MSP430SelectionDAGInfo.h"
 #include "MSP430TargetMachine.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
index 31b793e9c0f2f4..314d31cd1c1d7a 100644
--- a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -13,6 +13,7 @@
 #include "MSP430ISelLowering.h"
 #include "MSP430.h"
 #include "MSP430MachineFunctionInfo.h"
+#include "MSP430SelectionDAGInfo.h"
 #include "MSP430Subtarget.h"
 #include "MSP430TargetMachine.h"
 #include "llvm/CodeGen/CallingConvLower.h"
@@ -1360,27 +1361,6 @@ bool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
   return false;
 }
 
-
-const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
-  switch ((MSP430ISD::NodeType)Opcode) {
-  case MSP430ISD::FIRST_NUMBER:       break;
-  case MSP430ISD::RET_GLUE:           return "MSP430ISD::RET_GLUE";
-  case MSP430ISD::RETI_GLUE:          return "MSP430ISD::RETI_GLUE";
-  case MSP430ISD::RRA:                return "MSP430ISD::RRA";
-  case MSP430ISD::RLA:                return "MSP430ISD::RLA";
-  case MSP430ISD::RRC:                return "MSP430ISD::RRC";
-  case MSP430ISD::RRCL:               return "MSP430ISD::RRCL";
-  case MSP430ISD::CALL:               return "MSP430ISD::CALL";
-  case MSP430ISD::Wrapper:            return "MSP430ISD::Wrapper";
-  case MSP430ISD::BR_CC:              return "MSP430ISD::BR_CC";
-  case MSP430ISD::CMP:                return "MSP430ISD::CMP";
-  case MSP430ISD::SETCC:              return "MSP430ISD::SETCC";
-  case MSP430ISD::SELECT_CC:          return "MSP430ISD::SELECT_CC";
-  case MSP430ISD::DADD:               return "MSP430ISD::DADD";
-  }
-  return nullptr;
-}
-
 bool MSP430TargetLowering::isTruncateFree(Type *Ty1,
                                           Type *Ty2) const {
   if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.h b/llvm/lib/Target/MSP430/MSP430ISelLowering.h
index 667ad60338619b..6d89538f6be6ec 100644
--- a/llvm/lib/Target/MSP430/MSP430ISelLowering.h
+++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.h
@@ -19,56 +19,6 @@
 #include "llvm/CodeGen/TargetLowering.h"
 
 namespace llvm {
-  namespace MSP430ISD {
-    enum NodeType : unsigned {
-      FIRST_NUMBER = ISD::BUILTIN_OP_END,
-
-      /// Return with a glue operand. Operand 0 is the chain operand.
-      RET_GLUE,
-
-      /// Same as RET_GLUE, but used for returning from ISRs.
-      RETI_GLUE,
-
-      /// Y = R{R,L}A X, rotate right (left) arithmetically
-      RRA, RLA,
-
-      /// Y = RRC X, rotate right via carry
-      RRC,
-
-      /// Rotate right via carry, carry gets cleared beforehand by clrc
-      RRCL,
-
-      /// CALL - These operations represent an abstract call
-      /// instruction, which includes a bunch of information.
-      CALL,
-
-      /// Wrapper - A wrapper node for TargetConstantPool, TargetExternalSymbol,
-      /// and TargetGlobalAddress.
-      Wrapper,
-
-      /// CMP - Compare instruction.
-      CMP,
-
-      /// SetCC - Operand 0 is condition code, and operand 1 is the flag
-      /// operand produced by a CMP instruction.
-      SETCC,
-
-      /// MSP430 conditional branches. Operand 0 is the chain operand, operand 1
-      /// is the block to branch if condition is true, operand 2 is the
-      /// condition code, and operand 3 is the flag operand produced by a CMP
-      /// instruction.
-      BR_CC,
-
-      /// SELECT_CC - Operand 0 and operand 1 are selection variable, operand 3
-      /// is condition code and operand 4 is flag operand.
-      SELECT_CC,
-
-      /// DADD - Decimal addition with carry
-      /// TODO Nothing generates a node of this type yet.
-      DADD,
-    };
-  }
-
   class MSP430Subtarget;
   class MSP430TargetLowering : public TargetLowering {
   public:
@@ -86,10 +36,6 @@ namespace llvm {
     /// LowerOperation - Provide custom lowering hooks for some operations.
     SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
 
-    /// getTargetNodeName - This method returns the name of a target specific
-    /// DAG node.
-    const char *getTargetNodeName(unsigned Opcode) const override;
-
     SDValue LowerShifts(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
diff --git a/llvm/lib/Target/MSP430/MSP430SelectionDAGInfo.cpp b/llvm/lib/Target/MSP430/MSP430SelectionDAGInfo.cpp
new file mode 100644
index 00000000000000..8b21077a96cf2d
--- /dev/null
+++ b/llvm/lib/Target/MSP430/MSP430SelectionDAGInfo.cpp
@@ -0,0 +1,19 @@
+//===- MSP430SelectionDAGInfo.cpp -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "MSP430SelectionDAGInfo.h"
+
+#define GET_SDNODE_DESC
+#include "MSP430GenSDNodeInfo.inc"
+
+using namespace llvm;
+
+MSP430SelectionDAGInfo::MSP430SelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(MSP430GenSDNodeInfo) {}
+
+MSP430SelectionDAGInfo::~MSP430SelectionDAGInfo() = default;
diff --git a/llvm/lib/Target/MSP430/MSP430SelectionDAGInfo.h b/llvm/lib/Target/MSP430/MSP430SelectionDAGInfo.h
new file mode 100644
index 00000000000000..16525ab43c91e4
--- /dev/null
+++ b/llvm/lib/Target/MSP430/MSP430SelectionDAGInfo.h
@@ -0,0 +1,28 @@
+//===- MSP430SelectionDAGInfo.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_MSP430_MSP430SELECTIONDAGINFO_H
+#define LLVM_LIB_TARGET_MSP430_MSP430SELECTIONDAGINFO_H
+
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+
+#define GET_SDNODE_ENUM
+#include "MSP430GenSDNodeInfo.inc"
+
+namespace llvm {
+
+class MSP430SelectionDAGInfo : public SelectionDAGGenTargetInfo {
+public:
+  MSP430SelectionDAGInfo();
+
+  ~MSP430SelectionDAGInfo() override;
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_MSP430_MSP430SELECTIONDAGINFO_H
diff --git a/llvm/lib/Target/MSP430/MSP430Subtarget.cpp b/llvm/lib/Target/MSP430/MSP430Subtarget.cpp
index ea16cf749ee4d5..89fc4b21cfb889 100644
--- a/llvm/lib/Target/MSP430/MSP430Subtarget.cpp
+++ b/llvm/lib/Target/MSP430/MSP430Subtarget.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "MSP430Subtarget.h"
+#include "MSP430SelectionDAGInfo.h"
 #include "llvm/MC/TargetRegistry.h"
 
 using namespace llvm;
@@ -58,4 +59,12 @@ MSP430Subtarget::MSP430Subtarget(const Triple &TT, const std::string &CPU,
                                  const std::string &FS, const TargetMachine &TM)
     : MSP430GenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS),
       InstrInfo(initializeSubtargetDependencies(CPU, FS)), TLInfo(TM, *this),
-      FrameLowering(*this) {}
+      FrameLowering(*this) {
+  TSInfo = std::make_unique<MSP430SelectionDAGInfo>();
+}
+
+MSP430Subtarget::~MSP430Subtarget() = default;
+
+const SelectionDAGTargetInfo *MSP430Subtarget::getSelectionDAGInfo() const {
+  return TSInfo.get();
+}
diff --git a/llvm/lib/Target/MSP430/MSP430Subtarget.h b/llvm/lib/Target/MSP430/MSP430Subtarget.h
index d99545a2224d41..f7a9896ac8edc4 100644
--- a/llvm/lib/Target/MSP430/MSP430Subtarget.h
+++ b/llvm/lib/Target/MSP430/MSP430Subtarget.h
@@ -17,7 +17,6 @@
 #include "MSP430ISelLowering.h"
 #include "MSP430InstrInfo.h"
 #include "MSP430RegisterInfo.h"
-#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/IR/DataLayout.h"
 #include <string>
@@ -40,7 +39,7 @@ class MSP430Subtarget : public MSP430GenSubtargetInfo {
   HWMultEnum HWMultMode = NoHWMult;
   MSP430InstrInfo InstrInfo;
   MSP430TargetLowering TLInfo;
-  SelectionDAGTargetInfo TSInfo;
+  std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
   MSP430FrameLowering FrameLowering;
 
 public:
@@ -50,6 +49,8 @@ class MSP430Subtarget : public MSP430GenSubtargetInfo {
   MSP430Subtarget(const Triple &TT, const std::string &CPU,
                   const std::string &FS, const TargetMachine &TM);
 
+  ~MSP430Subtarget() override;
+
   MSP430Subtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);
 
   /// ParseSubtargetFeatures - Parses features string setting specified
@@ -71,9 +72,8 @@ class MSP430Subtarget : public MSP430GenSubtargetInfo {
   const MSP430TargetLowering *getTargetLowering() const override {
     return &TLInfo;
   }
-  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
-    return &TSInfo;
-  }
+
+  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
 };
 } // End llvm namespace
 

>From d6a4660522fb8161289256772cbe02bdcaf177a7 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 01:02:11 +0300
Subject: [PATCH 17/27] NVPTX

---
 llvm/lib/Target/NVPTX/CMakeLists.txt          |   1 +
 llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h     |   1 +
 llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp   | 441 +-----------------
 llvm/lib/Target/NVPTX/NVPTXISelLowering.h     | 431 -----------------
 .../Target/NVPTX/NVPTXSelectionDAGInfo.cpp    | 426 ++++++++++++++++-
 llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.h | 392 +++++++++++++++-
 6 files changed, 821 insertions(+), 871 deletions(-)

diff --git a/llvm/lib/Target/NVPTX/CMakeLists.txt b/llvm/lib/Target/NVPTX/CMakeLists.txt
index dfbda845347322..8eaf87e705b3e8 100644
--- a/llvm/lib/Target/NVPTX/CMakeLists.txt
+++ b/llvm/lib/Target/NVPTX/CMakeLists.txt
@@ -6,6 +6,7 @@ tablegen(LLVM NVPTXGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM NVPTXGenDAGISel.inc -gen-dag-isel)
 tablegen(LLVM NVPTXGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM NVPTXGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM NVPTXGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM NVPTXGenSubtargetInfo.inc -gen-subtarget)
 
 add_public_tablegen_target(NVPTXCommonTableGen)
diff --git a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h
index 8cc270a6829009..65a07dbaaa7c1f 100644
--- a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h
+++ b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h
@@ -17,6 +17,7 @@
 #include "NVPTX.h"
 #include "NVPTXISelLowering.h"
 #include "NVPTXRegisterInfo.h"
+#include "NVPTXSelectionDAGInfo.h"
 #include "NVPTXTargetMachine.h"
 #include "llvm/ADT/MapVector.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
diff --git a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
index ce94dded815b8f..6fd501298d4bb7 100644
--- a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
@@ -14,6 +14,7 @@
 #include "NVPTXISelLowering.h"
 #include "MCTargetDesc/NVPTXBaseInfo.h"
 #include "NVPTX.h"
+#include "NVPTXSelectionDAGInfo.h"
 #include "NVPTXSubtarget.h"
 #include "NVPTXTargetMachine.h"
 #include "NVPTXTargetObjectFile.h"
@@ -917,440 +918,6 @@ NVPTXTargetLowering::NVPTXTargetLowering(const NVPTXTargetMachine &TM,
   setMaxDivRemBitWidthSupported(64);
 }
 
-const char *NVPTXTargetLowering::getTargetNodeName(unsigned Opcode) const {
-
-#define MAKE_CASE(V)                                                           \
-  case V:                                                                      \
-    return #V;
-
-  switch ((NVPTXISD::NodeType)Opcode) {
-  case NVPTXISD::FIRST_NUMBER:
-    break;
-
-    MAKE_CASE(NVPTXISD::CALL)
-    MAKE_CASE(NVPTXISD::RET_GLUE)
-    MAKE_CASE(NVPTXISD::LOAD_PARAM)
-    MAKE_CASE(NVPTXISD::Wrapper)
-    MAKE_CASE(NVPTXISD::DeclareParam)
-    MAKE_CASE(NVPTXISD::DeclareScalarParam)
-    MAKE_CASE(NVPTXISD::DeclareRet)
-    MAKE_CASE(NVPTXISD::DeclareScalarRet)
-    MAKE_CASE(NVPTXISD::DeclareRetParam)
-    MAKE_CASE(NVPTXISD::PrintCall)
-    MAKE_CASE(NVPTXISD::PrintConvergentCall)
-    MAKE_CASE(NVPTXISD::PrintCallUni)
-    MAKE_CASE(NVPTXISD::PrintConvergentCallUni)
-    MAKE_CASE(NVPTXISD::LoadParam)
-    MAKE_CASE(NVPTXISD::LoadParamV2)
-    MAKE_CASE(NVPTXISD::LoadParamV4)
-    MAKE_CASE(NVPTXISD::StoreParam)
-    MAKE_CASE(NVPTXISD::StoreParamV2)
-    MAKE_CASE(NVPTXISD::StoreParamV4)
-    MAKE_CASE(NVPTXISD::StoreParamS32)
-    MAKE_CASE(NVPTXISD::StoreParamU32)
-    MAKE_CASE(NVPTXISD::CallArgBegin)
-    MAKE_CASE(NVPTXISD::CallArg)
-    MAKE_CASE(NVPTXISD::LastCallArg)
-    MAKE_CASE(NVPTXISD::CallArgEnd)
-    MAKE_CASE(NVPTXISD::CallVoid)
-    MAKE_CASE(NVPTXISD::CallVal)
-    MAKE_CASE(NVPTXISD::CallSymbol)
-    MAKE_CASE(NVPTXISD::Prototype)
-    MAKE_CASE(NVPTXISD::MoveParam)
-    MAKE_CASE(NVPTXISD::StoreRetval)
-    MAKE_CASE(NVPTXISD::StoreRetvalV2)
-    MAKE_CASE(NVPTXISD::StoreRetvalV4)
-    MAKE_CASE(NVPTXISD::PseudoUseParam)
-    MAKE_CASE(NVPTXISD::RETURN)
-    MAKE_CASE(NVPTXISD::CallSeqBegin)
-    MAKE_CASE(NVPTXISD::CallSeqEnd)
-    MAKE_CASE(NVPTXISD::CallPrototype)
-    MAKE_CASE(NVPTXISD::ProxyReg)
-    MAKE_CASE(NVPTXISD::LoadV2)
-    MAKE_CASE(NVPTXISD::LoadV4)
-    MAKE_CASE(NVPTXISD::LDUV2)
-    MAKE_CASE(NVPTXISD::LDUV4)
-    MAKE_CASE(NVPTXISD::StoreV2)
-    MAKE_CASE(NVPTXISD::StoreV4)
-    MAKE_CASE(NVPTXISD::FSHL_CLAMP)
-    MAKE_CASE(NVPTXISD::FSHR_CLAMP)
-    MAKE_CASE(NVPTXISD::IMAD)
-    MAKE_CASE(NVPTXISD::BFE)
-    MAKE_CASE(NVPTXISD::BFI)
-    MAKE_CASE(NVPTXISD::PRMT)
-    MAKE_CASE(NVPTXISD::FCOPYSIGN)
-    MAKE_CASE(NVPTXISD::DYNAMIC_STACKALLOC)
-    MAKE_CASE(NVPTXISD::STACKRESTORE)
-    MAKE_CASE(NVPTXISD::STACKSAVE)
-    MAKE_CASE(NVPTXISD::SETP_F16X2)
-    MAKE_CASE(NVPTXISD::SETP_BF16X2)
-    MAKE_CASE(NVPTXISD::Dummy)
-    MAKE_CASE(NVPTXISD::MUL_WIDE_SIGNED)
-    MAKE_CASE(NVPTXISD::MUL_WIDE_UNSIGNED)
-    MAKE_CASE(NVPTXISD::BrxEnd)
-    MAKE_CASE(NVPTXISD::BrxItem)
-    MAKE_CASE(NVPTXISD::BrxStart)
-    MAKE_CASE(NVPTXISD::Tex1DFloatS32)
-    MAKE_CASE(NVPTXISD::Tex1DFloatFloat)
-    MAKE_CASE(NVPTXISD::Tex1DFloatFloatLevel)
-    MAKE_CASE(NVPTXISD::Tex1DFloatFloatGrad)
-    MAKE_CASE(NVPTXISD::Tex1DS32S32)
-    MAKE_CASE(NVPTXISD::Tex1DS32Float)
-    MAKE_CASE(NVPTXISD::Tex1DS32FloatLevel)
-    MAKE_CASE(NVPTXISD::Tex1DS32FloatGrad)
-    MAKE_CASE(NVPTXISD::Tex1DU32S32)
-    MAKE_CASE(NVPTXISD::Tex1DU32Float)
-    MAKE_CASE(NVPTXISD::Tex1DU32FloatLevel)
-    MAKE_CASE(NVPTXISD::Tex1DU32FloatGrad)
-    MAKE_CASE(NVPTXISD::Tex1DArrayFloatS32)
-    MAKE_CASE(NVPTXISD::Tex1DArrayFloatFloat)
-    MAKE_CASE(NVPTXISD::Tex1DArrayFloatFloatLevel)
-    MAKE_CASE(NVPTXISD::Tex1DArrayFloatFloatGrad)
-    MAKE_CASE(NVPTXISD::Tex1DArrayS32S32)
-    MAKE_CASE(NVPTXISD::Tex1DArrayS32Float)
-    MAKE_CASE(NVPTXISD::Tex1DArrayS32FloatLevel)
-    MAKE_CASE(NVPTXISD::Tex1DArrayS32FloatGrad)
-    MAKE_CASE(NVPTXISD::Tex1DArrayU32S32)
-    MAKE_CASE(NVPTXISD::Tex1DArrayU32Float)
-    MAKE_CASE(NVPTXISD::Tex1DArrayU32FloatLevel)
-    MAKE_CASE(NVPTXISD::Tex1DArrayU32FloatGrad)
-    MAKE_CASE(NVPTXISD::Tex2DFloatS32)
-    MAKE_CASE(NVPTXISD::Tex2DFloatFloat)
-    MAKE_CASE(NVPTXISD::Tex2DFloatFloatLevel)
-    MAKE_CASE(NVPTXISD::Tex2DFloatFloatGrad)
-    MAKE_CASE(NVPTXISD::Tex2DS32S32)
-    MAKE_CASE(NVPTXISD::Tex2DS32Float)
-    MAKE_CASE(NVPTXISD::Tex2DS32FloatLevel)
-    MAKE_CASE(NVPTXISD::Tex2DS32FloatGrad)
-    MAKE_CASE(NVPTXISD::Tex2DU32S32)
-    MAKE_CASE(NVPTXISD::Tex2DU32Float)
-    MAKE_CASE(NVPTXISD::Tex2DU32FloatLevel)
-    MAKE_CASE(NVPTXISD::Tex2DU32FloatGrad)
-    MAKE_CASE(NVPTXISD::Tex2DArrayFloatS32)
-    MAKE_CASE(NVPTXISD::Tex2DArrayFloatFloat)
-    MAKE_CASE(NVPTXISD::Tex2DArrayFloatFloatLevel)
-    MAKE_CASE(NVPTXISD::Tex2DArrayFloatFloatGrad)
-    MAKE_CASE(NVPTXISD::Tex2DArrayS32S32)
-    MAKE_CASE(NVPTXISD::Tex2DArrayS32Float)
-    MAKE_CASE(NVPTXISD::Tex2DArrayS32FloatLevel)
-    MAKE_CASE(NVPTXISD::Tex2DArrayS32FloatGrad)
-    MAKE_CASE(NVPTXISD::Tex2DArrayU32S32)
-    MAKE_CASE(NVPTXISD::Tex2DArrayU32Float)
-    MAKE_CASE(NVPTXISD::Tex2DArrayU32FloatLevel)
-    MAKE_CASE(NVPTXISD::Tex2DArrayU32FloatGrad)
-    MAKE_CASE(NVPTXISD::Tex3DFloatS32)
-    MAKE_CASE(NVPTXISD::Tex3DFloatFloat)
-    MAKE_CASE(NVPTXISD::Tex3DFloatFloatLevel)
-    MAKE_CASE(NVPTXISD::Tex3DFloatFloatGrad)
-    MAKE_CASE(NVPTXISD::Tex3DS32S32)
-    MAKE_CASE(NVPTXISD::Tex3DS32Float)
-    MAKE_CASE(NVPTXISD::Tex3DS32FloatLevel)
-    MAKE_CASE(NVPTXISD::Tex3DS32FloatGrad)
-    MAKE_CASE(NVPTXISD::Tex3DU32S32)
-    MAKE_CASE(NVPTXISD::Tex3DU32Float)
-    MAKE_CASE(NVPTXISD::Tex3DU32FloatLevel)
-    MAKE_CASE(NVPTXISD::Tex3DU32FloatGrad)
-    MAKE_CASE(NVPTXISD::TexCubeFloatFloat)
-    MAKE_CASE(NVPTXISD::TexCubeFloatFloatLevel)
-    MAKE_CASE(NVPTXISD::TexCubeS32Float)
-    MAKE_CASE(NVPTXISD::TexCubeS32FloatLevel)
-    MAKE_CASE(NVPTXISD::TexCubeU32Float)
-    MAKE_CASE(NVPTXISD::TexCubeU32FloatLevel)
-    MAKE_CASE(NVPTXISD::TexCubeArrayFloatFloat)
-    MAKE_CASE(NVPTXISD::TexCubeArrayFloatFloatLevel)
-    MAKE_CASE(NVPTXISD::TexCubeArrayS32Float)
-    MAKE_CASE(NVPTXISD::TexCubeArrayS32FloatLevel)
-    MAKE_CASE(NVPTXISD::TexCubeArrayU32Float)
-    MAKE_CASE(NVPTXISD::TexCubeArrayU32FloatLevel)
-    MAKE_CASE(NVPTXISD::Tld4R2DFloatFloat)
-    MAKE_CASE(NVPTXISD::Tld4G2DFloatFloat)
-    MAKE_CASE(NVPTXISD::Tld4B2DFloatFloat)
-    MAKE_CASE(NVPTXISD::Tld4A2DFloatFloat)
-    MAKE_CASE(NVPTXISD::Tld4R2DS64Float)
-    MAKE_CASE(NVPTXISD::Tld4G2DS64Float)
-    MAKE_CASE(NVPTXISD::Tld4B2DS64Float)
-    MAKE_CASE(NVPTXISD::Tld4A2DS64Float)
-    MAKE_CASE(NVPTXISD::Tld4R2DU64Float)
-    MAKE_CASE(NVPTXISD::Tld4G2DU64Float)
-    MAKE_CASE(NVPTXISD::Tld4B2DU64Float)
-    MAKE_CASE(NVPTXISD::Tld4A2DU64Float)
-
-    MAKE_CASE(NVPTXISD::TexUnified1DFloatS32)
-    MAKE_CASE(NVPTXISD::TexUnified1DFloatFloat)
-    MAKE_CASE(NVPTXISD::TexUnified1DFloatFloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnified1DFloatFloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnified1DS32S32)
-    MAKE_CASE(NVPTXISD::TexUnified1DS32Float)
-    MAKE_CASE(NVPTXISD::TexUnified1DS32FloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnified1DS32FloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnified1DU32S32)
-    MAKE_CASE(NVPTXISD::TexUnified1DU32Float)
-    MAKE_CASE(NVPTXISD::TexUnified1DU32FloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnified1DU32FloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnified1DArrayFloatS32)
-    MAKE_CASE(NVPTXISD::TexUnified1DArrayFloatFloat)
-    MAKE_CASE(NVPTXISD::TexUnified1DArrayFloatFloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnified1DArrayFloatFloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnified1DArrayS32S32)
-    MAKE_CASE(NVPTXISD::TexUnified1DArrayS32Float)
-    MAKE_CASE(NVPTXISD::TexUnified1DArrayS32FloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnified1DArrayS32FloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnified1DArrayU32S32)
-    MAKE_CASE(NVPTXISD::TexUnified1DArrayU32Float)
-    MAKE_CASE(NVPTXISD::TexUnified1DArrayU32FloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnified1DArrayU32FloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnified2DFloatS32)
-    MAKE_CASE(NVPTXISD::TexUnified2DFloatFloat)
-    MAKE_CASE(NVPTXISD::TexUnified2DFloatFloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnified2DFloatFloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnified2DS32S32)
-    MAKE_CASE(NVPTXISD::TexUnified2DS32Float)
-    MAKE_CASE(NVPTXISD::TexUnified2DS32FloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnified2DS32FloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnified2DU32S32)
-    MAKE_CASE(NVPTXISD::TexUnified2DU32Float)
-    MAKE_CASE(NVPTXISD::TexUnified2DU32FloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnified2DU32FloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnified2DArrayFloatS32)
-    MAKE_CASE(NVPTXISD::TexUnified2DArrayFloatFloat)
-    MAKE_CASE(NVPTXISD::TexUnified2DArrayFloatFloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnified2DArrayFloatFloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnified2DArrayS32S32)
-    MAKE_CASE(NVPTXISD::TexUnified2DArrayS32Float)
-    MAKE_CASE(NVPTXISD::TexUnified2DArrayS32FloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnified2DArrayS32FloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnified2DArrayU32S32)
-    MAKE_CASE(NVPTXISD::TexUnified2DArrayU32Float)
-    MAKE_CASE(NVPTXISD::TexUnified2DArrayU32FloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnified2DArrayU32FloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnified3DFloatS32)
-    MAKE_CASE(NVPTXISD::TexUnified3DFloatFloat)
-    MAKE_CASE(NVPTXISD::TexUnified3DFloatFloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnified3DFloatFloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnified3DS32S32)
-    MAKE_CASE(NVPTXISD::TexUnified3DS32Float)
-    MAKE_CASE(NVPTXISD::TexUnified3DS32FloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnified3DS32FloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnified3DU32S32)
-    MAKE_CASE(NVPTXISD::TexUnified3DU32Float)
-    MAKE_CASE(NVPTXISD::TexUnified3DU32FloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnified3DU32FloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnifiedCubeFloatFloat)
-    MAKE_CASE(NVPTXISD::TexUnifiedCubeFloatFloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnifiedCubeS32Float)
-    MAKE_CASE(NVPTXISD::TexUnifiedCubeS32FloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnifiedCubeU32Float)
-    MAKE_CASE(NVPTXISD::TexUnifiedCubeU32FloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnifiedCubeArrayFloatFloat)
-    MAKE_CASE(NVPTXISD::TexUnifiedCubeArrayFloatFloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnifiedCubeArrayS32Float)
-    MAKE_CASE(NVPTXISD::TexUnifiedCubeArrayS32FloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnifiedCubeArrayU32Float)
-    MAKE_CASE(NVPTXISD::TexUnifiedCubeArrayU32FloatLevel)
-    MAKE_CASE(NVPTXISD::TexUnifiedCubeFloatFloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnifiedCubeS32FloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnifiedCubeU32FloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnifiedCubeArrayFloatFloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnifiedCubeArrayS32FloatGrad)
-    MAKE_CASE(NVPTXISD::TexUnifiedCubeArrayU32FloatGrad)
-    MAKE_CASE(NVPTXISD::Tld4UnifiedR2DFloatFloat)
-    MAKE_CASE(NVPTXISD::Tld4UnifiedG2DFloatFloat)
-    MAKE_CASE(NVPTXISD::Tld4UnifiedB2DFloatFloat)
-    MAKE_CASE(NVPTXISD::Tld4UnifiedA2DFloatFloat)
-    MAKE_CASE(NVPTXISD::Tld4UnifiedR2DS64Float)
-    MAKE_CASE(NVPTXISD::Tld4UnifiedG2DS64Float)
-    MAKE_CASE(NVPTXISD::Tld4UnifiedB2DS64Float)
-    MAKE_CASE(NVPTXISD::Tld4UnifiedA2DS64Float)
-    MAKE_CASE(NVPTXISD::Tld4UnifiedR2DU64Float)
-    MAKE_CASE(NVPTXISD::Tld4UnifiedG2DU64Float)
-    MAKE_CASE(NVPTXISD::Tld4UnifiedB2DU64Float)
-    MAKE_CASE(NVPTXISD::Tld4UnifiedA2DU64Float)
-
-    MAKE_CASE(NVPTXISD::Suld1DI8Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DI16Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DI32Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DI64Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DV2I8Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DV2I16Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DV2I32Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DV2I64Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DV4I8Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DV4I16Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DV4I32Clamp)
-
-    MAKE_CASE(NVPTXISD::Suld1DArrayI8Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DArrayI16Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DArrayI32Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DArrayI64Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV2I8Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV2I16Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV2I32Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV2I64Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV4I8Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV4I16Clamp)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV4I32Clamp)
-
-    MAKE_CASE(NVPTXISD::Suld2DI8Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DI16Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DI32Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DI64Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DV2I8Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DV2I16Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DV2I32Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DV2I64Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DV4I8Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DV4I16Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DV4I32Clamp)
-
-    MAKE_CASE(NVPTXISD::Suld2DArrayI8Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DArrayI16Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DArrayI32Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DArrayI64Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV2I8Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV2I16Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV2I32Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV2I64Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV4I8Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV4I16Clamp)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV4I32Clamp)
-
-    MAKE_CASE(NVPTXISD::Suld3DI8Clamp)
-    MAKE_CASE(NVPTXISD::Suld3DI16Clamp)
-    MAKE_CASE(NVPTXISD::Suld3DI32Clamp)
-    MAKE_CASE(NVPTXISD::Suld3DI64Clamp)
-    MAKE_CASE(NVPTXISD::Suld3DV2I8Clamp)
-    MAKE_CASE(NVPTXISD::Suld3DV2I16Clamp)
-    MAKE_CASE(NVPTXISD::Suld3DV2I32Clamp)
-    MAKE_CASE(NVPTXISD::Suld3DV2I64Clamp)
-    MAKE_CASE(NVPTXISD::Suld3DV4I8Clamp)
-    MAKE_CASE(NVPTXISD::Suld3DV4I16Clamp)
-    MAKE_CASE(NVPTXISD::Suld3DV4I32Clamp)
-
-    MAKE_CASE(NVPTXISD::Suld1DI8Trap)
-    MAKE_CASE(NVPTXISD::Suld1DI16Trap)
-    MAKE_CASE(NVPTXISD::Suld1DI32Trap)
-    MAKE_CASE(NVPTXISD::Suld1DI64Trap)
-    MAKE_CASE(NVPTXISD::Suld1DV2I8Trap)
-    MAKE_CASE(NVPTXISD::Suld1DV2I16Trap)
-    MAKE_CASE(NVPTXISD::Suld1DV2I32Trap)
-    MAKE_CASE(NVPTXISD::Suld1DV2I64Trap)
-    MAKE_CASE(NVPTXISD::Suld1DV4I8Trap)
-    MAKE_CASE(NVPTXISD::Suld1DV4I16Trap)
-    MAKE_CASE(NVPTXISD::Suld1DV4I32Trap)
-
-    MAKE_CASE(NVPTXISD::Suld1DArrayI8Trap)
-    MAKE_CASE(NVPTXISD::Suld1DArrayI16Trap)
-    MAKE_CASE(NVPTXISD::Suld1DArrayI32Trap)
-    MAKE_CASE(NVPTXISD::Suld1DArrayI64Trap)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV2I8Trap)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV2I16Trap)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV2I32Trap)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV2I64Trap)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV4I8Trap)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV4I16Trap)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV4I32Trap)
-
-    MAKE_CASE(NVPTXISD::Suld2DI8Trap)
-    MAKE_CASE(NVPTXISD::Suld2DI16Trap)
-    MAKE_CASE(NVPTXISD::Suld2DI32Trap)
-    MAKE_CASE(NVPTXISD::Suld2DI64Trap)
-    MAKE_CASE(NVPTXISD::Suld2DV2I8Trap)
-    MAKE_CASE(NVPTXISD::Suld2DV2I16Trap)
-    MAKE_CASE(NVPTXISD::Suld2DV2I32Trap)
-    MAKE_CASE(NVPTXISD::Suld2DV2I64Trap)
-    MAKE_CASE(NVPTXISD::Suld2DV4I8Trap)
-    MAKE_CASE(NVPTXISD::Suld2DV4I16Trap)
-    MAKE_CASE(NVPTXISD::Suld2DV4I32Trap)
-
-    MAKE_CASE(NVPTXISD::Suld2DArrayI8Trap)
-    MAKE_CASE(NVPTXISD::Suld2DArrayI16Trap)
-    MAKE_CASE(NVPTXISD::Suld2DArrayI32Trap)
-    MAKE_CASE(NVPTXISD::Suld2DArrayI64Trap)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV2I8Trap)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV2I16Trap)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV2I32Trap)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV2I64Trap)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV4I8Trap)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV4I16Trap)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV4I32Trap)
-
-    MAKE_CASE(NVPTXISD::Suld3DI8Trap)
-    MAKE_CASE(NVPTXISD::Suld3DI16Trap)
-    MAKE_CASE(NVPTXISD::Suld3DI32Trap)
-    MAKE_CASE(NVPTXISD::Suld3DI64Trap)
-    MAKE_CASE(NVPTXISD::Suld3DV2I8Trap)
-    MAKE_CASE(NVPTXISD::Suld3DV2I16Trap)
-    MAKE_CASE(NVPTXISD::Suld3DV2I32Trap)
-    MAKE_CASE(NVPTXISD::Suld3DV2I64Trap)
-    MAKE_CASE(NVPTXISD::Suld3DV4I8Trap)
-    MAKE_CASE(NVPTXISD::Suld3DV4I16Trap)
-    MAKE_CASE(NVPTXISD::Suld3DV4I32Trap)
-
-    MAKE_CASE(NVPTXISD::Suld1DI8Zero)
-    MAKE_CASE(NVPTXISD::Suld1DI16Zero)
-    MAKE_CASE(NVPTXISD::Suld1DI32Zero)
-    MAKE_CASE(NVPTXISD::Suld1DI64Zero)
-    MAKE_CASE(NVPTXISD::Suld1DV2I8Zero)
-    MAKE_CASE(NVPTXISD::Suld1DV2I16Zero)
-    MAKE_CASE(NVPTXISD::Suld1DV2I32Zero)
-    MAKE_CASE(NVPTXISD::Suld1DV2I64Zero)
-    MAKE_CASE(NVPTXISD::Suld1DV4I8Zero)
-    MAKE_CASE(NVPTXISD::Suld1DV4I16Zero)
-    MAKE_CASE(NVPTXISD::Suld1DV4I32Zero)
-
-    MAKE_CASE(NVPTXISD::Suld1DArrayI8Zero)
-    MAKE_CASE(NVPTXISD::Suld1DArrayI16Zero)
-    MAKE_CASE(NVPTXISD::Suld1DArrayI32Zero)
-    MAKE_CASE(NVPTXISD::Suld1DArrayI64Zero)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV2I8Zero)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV2I16Zero)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV2I32Zero)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV2I64Zero)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV4I8Zero)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV4I16Zero)
-    MAKE_CASE(NVPTXISD::Suld1DArrayV4I32Zero)
-
-    MAKE_CASE(NVPTXISD::Suld2DI8Zero)
-    MAKE_CASE(NVPTXISD::Suld2DI16Zero)
-    MAKE_CASE(NVPTXISD::Suld2DI32Zero)
-    MAKE_CASE(NVPTXISD::Suld2DI64Zero)
-    MAKE_CASE(NVPTXISD::Suld2DV2I8Zero)
-    MAKE_CASE(NVPTXISD::Suld2DV2I16Zero)
-    MAKE_CASE(NVPTXISD::Suld2DV2I32Zero)
-    MAKE_CASE(NVPTXISD::Suld2DV2I64Zero)
-    MAKE_CASE(NVPTXISD::Suld2DV4I8Zero)
-    MAKE_CASE(NVPTXISD::Suld2DV4I16Zero)
-    MAKE_CASE(NVPTXISD::Suld2DV4I32Zero)
-
-    MAKE_CASE(NVPTXISD::Suld2DArrayI8Zero)
-    MAKE_CASE(NVPTXISD::Suld2DArrayI16Zero)
-    MAKE_CASE(NVPTXISD::Suld2DArrayI32Zero)
-    MAKE_CASE(NVPTXISD::Suld2DArrayI64Zero)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV2I8Zero)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV2I16Zero)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV2I32Zero)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV2I64Zero)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV4I8Zero)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV4I16Zero)
-    MAKE_CASE(NVPTXISD::Suld2DArrayV4I32Zero)
-
-    MAKE_CASE(NVPTXISD::Suld3DI8Zero)
-    MAKE_CASE(NVPTXISD::Suld3DI16Zero)
-    MAKE_CASE(NVPTXISD::Suld3DI32Zero)
-    MAKE_CASE(NVPTXISD::Suld3DI64Zero)
-    MAKE_CASE(NVPTXISD::Suld3DV2I8Zero)
-    MAKE_CASE(NVPTXISD::Suld3DV2I16Zero)
-    MAKE_CASE(NVPTXISD::Suld3DV2I32Zero)
-    MAKE_CASE(NVPTXISD::Suld3DV2I64Zero)
-    MAKE_CASE(NVPTXISD::Suld3DV4I8Zero)
-    MAKE_CASE(NVPTXISD::Suld3DV4I16Zero)
-    MAKE_CASE(NVPTXISD::Suld3DV4I32Zero)
-  }
-  return nullptr;
-
-#undef MAKE_CASE
-}
-
 TargetLoweringBase::LegalizeTypeAction
 NVPTXTargetLowering::getPreferredVectorAction(MVT VT) const {
   if (!VT.isScalableVector() && VT.getVectorNumElements() != 1 &&
@@ -1898,7 +1465,7 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
 
       if (VectorInfo[j] & PVF_LAST) {
         unsigned NumElts = StoreOperands.size() - 3;
-        NVPTXISD::NodeType Op;
+        unsigned Op;
         switch (NumElts) {
         case 1:
           Op = NVPTXISD::StoreParam;
@@ -2188,7 +1755,7 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
         unsigned NumElts = LoadVTs.size();
         LoadVTs.push_back(MVT::Other);
         LoadVTs.push_back(MVT::Glue);
-        NVPTXISD::NodeType Op;
+        unsigned Op;
         switch (NumElts) {
         case 1:
           Op = NVPTXISD::LoadParam;
@@ -3675,7 +3242,7 @@ NVPTXTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
 
     // That's the last element of this store op.
     if (VectorInfo[i] & PVF_LAST) {
-      NVPTXISD::NodeType Op;
+      unsigned Op;
       unsigned NumElts = StoreOperands.size() - 2;
       switch (NumElts) {
       case 1:
diff --git a/llvm/lib/Target/NVPTX/NVPTXISelLowering.h b/llvm/lib/Target/NVPTX/NVPTXISelLowering.h
index f7c59973f8d1a5..104169dd4d2772 100644
--- a/llvm/lib/Target/NVPTX/NVPTXISelLowering.h
+++ b/llvm/lib/Target/NVPTX/NVPTXISelLowering.h
@@ -19,435 +19,6 @@
 #include "llvm/CodeGen/TargetLowering.h"
 
 namespace llvm {
-namespace NVPTXISD {
-enum NodeType : unsigned {
-  // Start the numbering from where ISD NodeType finishes.
-  FIRST_NUMBER = ISD::BUILTIN_OP_END,
-  Wrapper,
-  CALL,
-  RET_GLUE,
-  LOAD_PARAM,
-  DeclareParam,
-  DeclareScalarParam,
-  DeclareRetParam,
-  DeclareRet,
-  DeclareScalarRet,
-  PrintCall,
-  PrintConvergentCall,
-  PrintCallUni,
-  PrintConvergentCallUni,
-  CallArgBegin,
-  CallArg,
-  LastCallArg,
-  CallArgEnd,
-  CallVoid,
-  CallVal,
-  CallSymbol,
-  Prototype,
-  MoveParam,
-  PseudoUseParam,
-  RETURN,
-  CallSeqBegin,
-  CallSeqEnd,
-  CallPrototype,
-  ProxyReg,
-  FSHL_CLAMP,
-  FSHR_CLAMP,
-  MUL_WIDE_SIGNED,
-  MUL_WIDE_UNSIGNED,
-  IMAD,
-  SETP_F16X2,
-  SETP_BF16X2,
-  BFE,
-  BFI,
-  PRMT,
-  FCOPYSIGN,
-  DYNAMIC_STACKALLOC,
-  STACKRESTORE,
-  STACKSAVE,
-  BrxStart,
-  BrxItem,
-  BrxEnd,
-  Dummy,
-
-  FIRST_MEMORY_OPCODE,
-  LoadV2 = FIRST_MEMORY_OPCODE,
-  LoadV4,
-  LDUV2, // LDU.v2
-  LDUV4, // LDU.v4
-  StoreV2,
-  StoreV4,
-  LoadParam,
-  LoadParamV2,
-  LoadParamV4,
-  StoreParam,
-  StoreParamV2,
-  StoreParamV4,
-  StoreParamS32, // to sext and store a <32bit value, not used currently
-  StoreParamU32, // to zext and store a <32bit value, not used currently
-  StoreRetval,
-  StoreRetvalV2,
-  StoreRetvalV4,
-
-  // Texture intrinsics
-  Tex1DFloatS32,
-  Tex1DFloatFloat,
-  Tex1DFloatFloatLevel,
-  Tex1DFloatFloatGrad,
-  Tex1DS32S32,
-  Tex1DS32Float,
-  Tex1DS32FloatLevel,
-  Tex1DS32FloatGrad,
-  Tex1DU32S32,
-  Tex1DU32Float,
-  Tex1DU32FloatLevel,
-  Tex1DU32FloatGrad,
-  Tex1DArrayFloatS32,
-  Tex1DArrayFloatFloat,
-  Tex1DArrayFloatFloatLevel,
-  Tex1DArrayFloatFloatGrad,
-  Tex1DArrayS32S32,
-  Tex1DArrayS32Float,
-  Tex1DArrayS32FloatLevel,
-  Tex1DArrayS32FloatGrad,
-  Tex1DArrayU32S32,
-  Tex1DArrayU32Float,
-  Tex1DArrayU32FloatLevel,
-  Tex1DArrayU32FloatGrad,
-  Tex2DFloatS32,
-  Tex2DFloatFloat,
-  Tex2DFloatFloatLevel,
-  Tex2DFloatFloatGrad,
-  Tex2DS32S32,
-  Tex2DS32Float,
-  Tex2DS32FloatLevel,
-  Tex2DS32FloatGrad,
-  Tex2DU32S32,
-  Tex2DU32Float,
-  Tex2DU32FloatLevel,
-  Tex2DU32FloatGrad,
-  Tex2DArrayFloatS32,
-  Tex2DArrayFloatFloat,
-  Tex2DArrayFloatFloatLevel,
-  Tex2DArrayFloatFloatGrad,
-  Tex2DArrayS32S32,
-  Tex2DArrayS32Float,
-  Tex2DArrayS32FloatLevel,
-  Tex2DArrayS32FloatGrad,
-  Tex2DArrayU32S32,
-  Tex2DArrayU32Float,
-  Tex2DArrayU32FloatLevel,
-  Tex2DArrayU32FloatGrad,
-  Tex3DFloatS32,
-  Tex3DFloatFloat,
-  Tex3DFloatFloatLevel,
-  Tex3DFloatFloatGrad,
-  Tex3DS32S32,
-  Tex3DS32Float,
-  Tex3DS32FloatLevel,
-  Tex3DS32FloatGrad,
-  Tex3DU32S32,
-  Tex3DU32Float,
-  Tex3DU32FloatLevel,
-  Tex3DU32FloatGrad,
-  TexCubeFloatFloat,
-  TexCubeFloatFloatLevel,
-  TexCubeS32Float,
-  TexCubeS32FloatLevel,
-  TexCubeU32Float,
-  TexCubeU32FloatLevel,
-  TexCubeArrayFloatFloat,
-  TexCubeArrayFloatFloatLevel,
-  TexCubeArrayS32Float,
-  TexCubeArrayS32FloatLevel,
-  TexCubeArrayU32Float,
-  TexCubeArrayU32FloatLevel,
-  Tld4R2DFloatFloat,
-  Tld4G2DFloatFloat,
-  Tld4B2DFloatFloat,
-  Tld4A2DFloatFloat,
-  Tld4R2DS64Float,
-  Tld4G2DS64Float,
-  Tld4B2DS64Float,
-  Tld4A2DS64Float,
-  Tld4R2DU64Float,
-  Tld4G2DU64Float,
-  Tld4B2DU64Float,
-  Tld4A2DU64Float,
-  TexUnified1DFloatS32,
-  TexUnified1DFloatFloat,
-  TexUnified1DFloatFloatLevel,
-  TexUnified1DFloatFloatGrad,
-  TexUnified1DS32S32,
-  TexUnified1DS32Float,
-  TexUnified1DS32FloatLevel,
-  TexUnified1DS32FloatGrad,
-  TexUnified1DU32S32,
-  TexUnified1DU32Float,
-  TexUnified1DU32FloatLevel,
-  TexUnified1DU32FloatGrad,
-  TexUnified1DArrayFloatS32,
-  TexUnified1DArrayFloatFloat,
-  TexUnified1DArrayFloatFloatLevel,
-  TexUnified1DArrayFloatFloatGrad,
-  TexUnified1DArrayS32S32,
-  TexUnified1DArrayS32Float,
-  TexUnified1DArrayS32FloatLevel,
-  TexUnified1DArrayS32FloatGrad,
-  TexUnified1DArrayU32S32,
-  TexUnified1DArrayU32Float,
-  TexUnified1DArrayU32FloatLevel,
-  TexUnified1DArrayU32FloatGrad,
-  TexUnified2DFloatS32,
-  TexUnified2DFloatFloat,
-  TexUnified2DFloatFloatLevel,
-  TexUnified2DFloatFloatGrad,
-  TexUnified2DS32S32,
-  TexUnified2DS32Float,
-  TexUnified2DS32FloatLevel,
-  TexUnified2DS32FloatGrad,
-  TexUnified2DU32S32,
-  TexUnified2DU32Float,
-  TexUnified2DU32FloatLevel,
-  TexUnified2DU32FloatGrad,
-  TexUnified2DArrayFloatS32,
-  TexUnified2DArrayFloatFloat,
-  TexUnified2DArrayFloatFloatLevel,
-  TexUnified2DArrayFloatFloatGrad,
-  TexUnified2DArrayS32S32,
-  TexUnified2DArrayS32Float,
-  TexUnified2DArrayS32FloatLevel,
-  TexUnified2DArrayS32FloatGrad,
-  TexUnified2DArrayU32S32,
-  TexUnified2DArrayU32Float,
-  TexUnified2DArrayU32FloatLevel,
-  TexUnified2DArrayU32FloatGrad,
-  TexUnified3DFloatS32,
-  TexUnified3DFloatFloat,
-  TexUnified3DFloatFloatLevel,
-  TexUnified3DFloatFloatGrad,
-  TexUnified3DS32S32,
-  TexUnified3DS32Float,
-  TexUnified3DS32FloatLevel,
-  TexUnified3DS32FloatGrad,
-  TexUnified3DU32S32,
-  TexUnified3DU32Float,
-  TexUnified3DU32FloatLevel,
-  TexUnified3DU32FloatGrad,
-  TexUnifiedCubeFloatFloat,
-  TexUnifiedCubeFloatFloatLevel,
-  TexUnifiedCubeS32Float,
-  TexUnifiedCubeS32FloatLevel,
-  TexUnifiedCubeU32Float,
-  TexUnifiedCubeU32FloatLevel,
-  TexUnifiedCubeArrayFloatFloat,
-  TexUnifiedCubeArrayFloatFloatLevel,
-  TexUnifiedCubeArrayS32Float,
-  TexUnifiedCubeArrayS32FloatLevel,
-  TexUnifiedCubeArrayU32Float,
-  TexUnifiedCubeArrayU32FloatLevel,
-  TexUnifiedCubeFloatFloatGrad,
-  TexUnifiedCubeS32FloatGrad,
-  TexUnifiedCubeU32FloatGrad,
-  TexUnifiedCubeArrayFloatFloatGrad,
-  TexUnifiedCubeArrayS32FloatGrad,
-  TexUnifiedCubeArrayU32FloatGrad,
-  Tld4UnifiedR2DFloatFloat,
-  Tld4UnifiedG2DFloatFloat,
-  Tld4UnifiedB2DFloatFloat,
-  Tld4UnifiedA2DFloatFloat,
-  Tld4UnifiedR2DS64Float,
-  Tld4UnifiedG2DS64Float,
-  Tld4UnifiedB2DS64Float,
-  Tld4UnifiedA2DS64Float,
-  Tld4UnifiedR2DU64Float,
-  Tld4UnifiedG2DU64Float,
-  Tld4UnifiedB2DU64Float,
-  Tld4UnifiedA2DU64Float,
-
-  // Surface intrinsics
-  Suld1DI8Clamp,
-  Suld1DI16Clamp,
-  Suld1DI32Clamp,
-  Suld1DI64Clamp,
-  Suld1DV2I8Clamp,
-  Suld1DV2I16Clamp,
-  Suld1DV2I32Clamp,
-  Suld1DV2I64Clamp,
-  Suld1DV4I8Clamp,
-  Suld1DV4I16Clamp,
-  Suld1DV4I32Clamp,
-
-  Suld1DArrayI8Clamp,
-  Suld1DArrayI16Clamp,
-  Suld1DArrayI32Clamp,
-  Suld1DArrayI64Clamp,
-  Suld1DArrayV2I8Clamp,
-  Suld1DArrayV2I16Clamp,
-  Suld1DArrayV2I32Clamp,
-  Suld1DArrayV2I64Clamp,
-  Suld1DArrayV4I8Clamp,
-  Suld1DArrayV4I16Clamp,
-  Suld1DArrayV4I32Clamp,
-
-  Suld2DI8Clamp,
-  Suld2DI16Clamp,
-  Suld2DI32Clamp,
-  Suld2DI64Clamp,
-  Suld2DV2I8Clamp,
-  Suld2DV2I16Clamp,
-  Suld2DV2I32Clamp,
-  Suld2DV2I64Clamp,
-  Suld2DV4I8Clamp,
-  Suld2DV4I16Clamp,
-  Suld2DV4I32Clamp,
-
-  Suld2DArrayI8Clamp,
-  Suld2DArrayI16Clamp,
-  Suld2DArrayI32Clamp,
-  Suld2DArrayI64Clamp,
-  Suld2DArrayV2I8Clamp,
-  Suld2DArrayV2I16Clamp,
-  Suld2DArrayV2I32Clamp,
-  Suld2DArrayV2I64Clamp,
-  Suld2DArrayV4I8Clamp,
-  Suld2DArrayV4I16Clamp,
-  Suld2DArrayV4I32Clamp,
-
-  Suld3DI8Clamp,
-  Suld3DI16Clamp,
-  Suld3DI32Clamp,
-  Suld3DI64Clamp,
-  Suld3DV2I8Clamp,
-  Suld3DV2I16Clamp,
-  Suld3DV2I32Clamp,
-  Suld3DV2I64Clamp,
-  Suld3DV4I8Clamp,
-  Suld3DV4I16Clamp,
-  Suld3DV4I32Clamp,
-
-  Suld1DI8Trap,
-  Suld1DI16Trap,
-  Suld1DI32Trap,
-  Suld1DI64Trap,
-  Suld1DV2I8Trap,
-  Suld1DV2I16Trap,
-  Suld1DV2I32Trap,
-  Suld1DV2I64Trap,
-  Suld1DV4I8Trap,
-  Suld1DV4I16Trap,
-  Suld1DV4I32Trap,
-
-  Suld1DArrayI8Trap,
-  Suld1DArrayI16Trap,
-  Suld1DArrayI32Trap,
-  Suld1DArrayI64Trap,
-  Suld1DArrayV2I8Trap,
-  Suld1DArrayV2I16Trap,
-  Suld1DArrayV2I32Trap,
-  Suld1DArrayV2I64Trap,
-  Suld1DArrayV4I8Trap,
-  Suld1DArrayV4I16Trap,
-  Suld1DArrayV4I32Trap,
-
-  Suld2DI8Trap,
-  Suld2DI16Trap,
-  Suld2DI32Trap,
-  Suld2DI64Trap,
-  Suld2DV2I8Trap,
-  Suld2DV2I16Trap,
-  Suld2DV2I32Trap,
-  Suld2DV2I64Trap,
-  Suld2DV4I8Trap,
-  Suld2DV4I16Trap,
-  Suld2DV4I32Trap,
-
-  Suld2DArrayI8Trap,
-  Suld2DArrayI16Trap,
-  Suld2DArrayI32Trap,
-  Suld2DArrayI64Trap,
-  Suld2DArrayV2I8Trap,
-  Suld2DArrayV2I16Trap,
-  Suld2DArrayV2I32Trap,
-  Suld2DArrayV2I64Trap,
-  Suld2DArrayV4I8Trap,
-  Suld2DArrayV4I16Trap,
-  Suld2DArrayV4I32Trap,
-
-  Suld3DI8Trap,
-  Suld3DI16Trap,
-  Suld3DI32Trap,
-  Suld3DI64Trap,
-  Suld3DV2I8Trap,
-  Suld3DV2I16Trap,
-  Suld3DV2I32Trap,
-  Suld3DV2I64Trap,
-  Suld3DV4I8Trap,
-  Suld3DV4I16Trap,
-  Suld3DV4I32Trap,
-
-  Suld1DI8Zero,
-  Suld1DI16Zero,
-  Suld1DI32Zero,
-  Suld1DI64Zero,
-  Suld1DV2I8Zero,
-  Suld1DV2I16Zero,
-  Suld1DV2I32Zero,
-  Suld1DV2I64Zero,
-  Suld1DV4I8Zero,
-  Suld1DV4I16Zero,
-  Suld1DV4I32Zero,
-
-  Suld1DArrayI8Zero,
-  Suld1DArrayI16Zero,
-  Suld1DArrayI32Zero,
-  Suld1DArrayI64Zero,
-  Suld1DArrayV2I8Zero,
-  Suld1DArrayV2I16Zero,
-  Suld1DArrayV2I32Zero,
-  Suld1DArrayV2I64Zero,
-  Suld1DArrayV4I8Zero,
-  Suld1DArrayV4I16Zero,
-  Suld1DArrayV4I32Zero,
-
-  Suld2DI8Zero,
-  Suld2DI16Zero,
-  Suld2DI32Zero,
-  Suld2DI64Zero,
-  Suld2DV2I8Zero,
-  Suld2DV2I16Zero,
-  Suld2DV2I32Zero,
-  Suld2DV2I64Zero,
-  Suld2DV4I8Zero,
-  Suld2DV4I16Zero,
-  Suld2DV4I32Zero,
-
-  Suld2DArrayI8Zero,
-  Suld2DArrayI16Zero,
-  Suld2DArrayI32Zero,
-  Suld2DArrayI64Zero,
-  Suld2DArrayV2I8Zero,
-  Suld2DArrayV2I16Zero,
-  Suld2DArrayV2I32Zero,
-  Suld2DArrayV2I64Zero,
-  Suld2DArrayV4I8Zero,
-  Suld2DArrayV4I16Zero,
-  Suld2DArrayV4I32Zero,
-
-  Suld3DI8Zero,
-  Suld3DI16Zero,
-  Suld3DI32Zero,
-  Suld3DI64Zero,
-  Suld3DV2I8Zero,
-  Suld3DV2I16Zero,
-  Suld3DV2I32Zero,
-  Suld3DV2I64Zero,
-  Suld3DV4I8Zero,
-  Suld3DV4I16Zero,
-  Suld3DV4I32Zero,
-  LAST_MEMORY_OPCODE = Suld3DV4I32Zero,
-};
-}
 
 class NVPTXSubtarget;
 
@@ -462,8 +33,6 @@ class NVPTXTargetLowering : public TargetLowering {
 
   SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
 
-  const char *getTargetNodeName(unsigned Opcode) const override;
-
   bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I,
                           MachineFunction &MF,
                           unsigned Intrinsic) const override;
diff --git a/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.cpp b/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.cpp
index c0941cc5738fa5..034ff7da6f9ee9 100644
--- a/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.cpp
@@ -7,15 +7,437 @@
 //===----------------------------------------------------------------------===//
 
 #include "NVPTXSelectionDAGInfo.h"
-#include "NVPTXISelLowering.h"
+
+#define GET_SDNODE_DESC
+#include "NVPTXGenSDNodeInfo.inc"
 
 using namespace llvm;
 
+NVPTXSelectionDAGInfo::NVPTXSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(NVPTXGenSDNodeInfo) {}
+
 NVPTXSelectionDAGInfo::~NVPTXSelectionDAGInfo() = default;
 
+const char *NVPTXSelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
+#define MAKE_CASE(V)                                                           \
+  case V:                                                                      \
+    return #V;
+
+  // These nodes don't have corresponding entries in *.td files yet.
+  switch (static_cast<NVPTXISD::NodeType>(Opcode)) {
+    MAKE_CASE(NVPTXISD::LOAD_PARAM)
+    MAKE_CASE(NVPTXISD::DeclareScalarRet)
+    MAKE_CASE(NVPTXISD::CallSymbol)
+    MAKE_CASE(NVPTXISD::CallSeqBegin)
+    MAKE_CASE(NVPTXISD::CallSeqEnd)
+    MAKE_CASE(NVPTXISD::LoadV2)
+    MAKE_CASE(NVPTXISD::LoadV4)
+    MAKE_CASE(NVPTXISD::LDUV2)
+    MAKE_CASE(NVPTXISD::LDUV4)
+    MAKE_CASE(NVPTXISD::StoreV2)
+    MAKE_CASE(NVPTXISD::StoreV4)
+    MAKE_CASE(NVPTXISD::SETP_F16X2)
+    MAKE_CASE(NVPTXISD::SETP_BF16X2)
+    MAKE_CASE(NVPTXISD::Dummy)
+    MAKE_CASE(NVPTXISD::Tex1DFloatS32)
+    MAKE_CASE(NVPTXISD::Tex1DFloatFloat)
+    MAKE_CASE(NVPTXISD::Tex1DFloatFloatLevel)
+    MAKE_CASE(NVPTXISD::Tex1DFloatFloatGrad)
+    MAKE_CASE(NVPTXISD::Tex1DS32S32)
+    MAKE_CASE(NVPTXISD::Tex1DS32Float)
+    MAKE_CASE(NVPTXISD::Tex1DS32FloatLevel)
+    MAKE_CASE(NVPTXISD::Tex1DS32FloatGrad)
+    MAKE_CASE(NVPTXISD::Tex1DU32S32)
+    MAKE_CASE(NVPTXISD::Tex1DU32Float)
+    MAKE_CASE(NVPTXISD::Tex1DU32FloatLevel)
+    MAKE_CASE(NVPTXISD::Tex1DU32FloatGrad)
+    MAKE_CASE(NVPTXISD::Tex1DArrayFloatS32)
+    MAKE_CASE(NVPTXISD::Tex1DArrayFloatFloat)
+    MAKE_CASE(NVPTXISD::Tex1DArrayFloatFloatLevel)
+    MAKE_CASE(NVPTXISD::Tex1DArrayFloatFloatGrad)
+    MAKE_CASE(NVPTXISD::Tex1DArrayS32S32)
+    MAKE_CASE(NVPTXISD::Tex1DArrayS32Float)
+    MAKE_CASE(NVPTXISD::Tex1DArrayS32FloatLevel)
+    MAKE_CASE(NVPTXISD::Tex1DArrayS32FloatGrad)
+    MAKE_CASE(NVPTXISD::Tex1DArrayU32S32)
+    MAKE_CASE(NVPTXISD::Tex1DArrayU32Float)
+    MAKE_CASE(NVPTXISD::Tex1DArrayU32FloatLevel)
+    MAKE_CASE(NVPTXISD::Tex1DArrayU32FloatGrad)
+    MAKE_CASE(NVPTXISD::Tex2DFloatS32)
+    MAKE_CASE(NVPTXISD::Tex2DFloatFloat)
+    MAKE_CASE(NVPTXISD::Tex2DFloatFloatLevel)
+    MAKE_CASE(NVPTXISD::Tex2DFloatFloatGrad)
+    MAKE_CASE(NVPTXISD::Tex2DS32S32)
+    MAKE_CASE(NVPTXISD::Tex2DS32Float)
+    MAKE_CASE(NVPTXISD::Tex2DS32FloatLevel)
+    MAKE_CASE(NVPTXISD::Tex2DS32FloatGrad)
+    MAKE_CASE(NVPTXISD::Tex2DU32S32)
+    MAKE_CASE(NVPTXISD::Tex2DU32Float)
+    MAKE_CASE(NVPTXISD::Tex2DU32FloatLevel)
+    MAKE_CASE(NVPTXISD::Tex2DU32FloatGrad)
+    MAKE_CASE(NVPTXISD::Tex2DArrayFloatS32)
+    MAKE_CASE(NVPTXISD::Tex2DArrayFloatFloat)
+    MAKE_CASE(NVPTXISD::Tex2DArrayFloatFloatLevel)
+    MAKE_CASE(NVPTXISD::Tex2DArrayFloatFloatGrad)
+    MAKE_CASE(NVPTXISD::Tex2DArrayS32S32)
+    MAKE_CASE(NVPTXISD::Tex2DArrayS32Float)
+    MAKE_CASE(NVPTXISD::Tex2DArrayS32FloatLevel)
+    MAKE_CASE(NVPTXISD::Tex2DArrayS32FloatGrad)
+    MAKE_CASE(NVPTXISD::Tex2DArrayU32S32)
+    MAKE_CASE(NVPTXISD::Tex2DArrayU32Float)
+    MAKE_CASE(NVPTXISD::Tex2DArrayU32FloatLevel)
+    MAKE_CASE(NVPTXISD::Tex2DArrayU32FloatGrad)
+    MAKE_CASE(NVPTXISD::Tex3DFloatS32)
+    MAKE_CASE(NVPTXISD::Tex3DFloatFloat)
+    MAKE_CASE(NVPTXISD::Tex3DFloatFloatLevel)
+    MAKE_CASE(NVPTXISD::Tex3DFloatFloatGrad)
+    MAKE_CASE(NVPTXISD::Tex3DS32S32)
+    MAKE_CASE(NVPTXISD::Tex3DS32Float)
+    MAKE_CASE(NVPTXISD::Tex3DS32FloatLevel)
+    MAKE_CASE(NVPTXISD::Tex3DS32FloatGrad)
+    MAKE_CASE(NVPTXISD::Tex3DU32S32)
+    MAKE_CASE(NVPTXISD::Tex3DU32Float)
+    MAKE_CASE(NVPTXISD::Tex3DU32FloatLevel)
+    MAKE_CASE(NVPTXISD::Tex3DU32FloatGrad)
+    MAKE_CASE(NVPTXISD::TexCubeFloatFloat)
+    MAKE_CASE(NVPTXISD::TexCubeFloatFloatLevel)
+    MAKE_CASE(NVPTXISD::TexCubeS32Float)
+    MAKE_CASE(NVPTXISD::TexCubeS32FloatLevel)
+    MAKE_CASE(NVPTXISD::TexCubeU32Float)
+    MAKE_CASE(NVPTXISD::TexCubeU32FloatLevel)
+    MAKE_CASE(NVPTXISD::TexCubeArrayFloatFloat)
+    MAKE_CASE(NVPTXISD::TexCubeArrayFloatFloatLevel)
+    MAKE_CASE(NVPTXISD::TexCubeArrayS32Float)
+    MAKE_CASE(NVPTXISD::TexCubeArrayS32FloatLevel)
+    MAKE_CASE(NVPTXISD::TexCubeArrayU32Float)
+    MAKE_CASE(NVPTXISD::TexCubeArrayU32FloatLevel)
+    MAKE_CASE(NVPTXISD::Tld4R2DFloatFloat)
+    MAKE_CASE(NVPTXISD::Tld4G2DFloatFloat)
+    MAKE_CASE(NVPTXISD::Tld4B2DFloatFloat)
+    MAKE_CASE(NVPTXISD::Tld4A2DFloatFloat)
+    MAKE_CASE(NVPTXISD::Tld4R2DS64Float)
+    MAKE_CASE(NVPTXISD::Tld4G2DS64Float)
+    MAKE_CASE(NVPTXISD::Tld4B2DS64Float)
+    MAKE_CASE(NVPTXISD::Tld4A2DS64Float)
+    MAKE_CASE(NVPTXISD::Tld4R2DU64Float)
+    MAKE_CASE(NVPTXISD::Tld4G2DU64Float)
+    MAKE_CASE(NVPTXISD::Tld4B2DU64Float)
+    MAKE_CASE(NVPTXISD::Tld4A2DU64Float)
+
+    MAKE_CASE(NVPTXISD::TexUnified1DFloatS32)
+    MAKE_CASE(NVPTXISD::TexUnified1DFloatFloat)
+    MAKE_CASE(NVPTXISD::TexUnified1DFloatFloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnified1DFloatFloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnified1DS32S32)
+    MAKE_CASE(NVPTXISD::TexUnified1DS32Float)
+    MAKE_CASE(NVPTXISD::TexUnified1DS32FloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnified1DS32FloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnified1DU32S32)
+    MAKE_CASE(NVPTXISD::TexUnified1DU32Float)
+    MAKE_CASE(NVPTXISD::TexUnified1DU32FloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnified1DU32FloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnified1DArrayFloatS32)
+    MAKE_CASE(NVPTXISD::TexUnified1DArrayFloatFloat)
+    MAKE_CASE(NVPTXISD::TexUnified1DArrayFloatFloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnified1DArrayFloatFloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnified1DArrayS32S32)
+    MAKE_CASE(NVPTXISD::TexUnified1DArrayS32Float)
+    MAKE_CASE(NVPTXISD::TexUnified1DArrayS32FloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnified1DArrayS32FloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnified1DArrayU32S32)
+    MAKE_CASE(NVPTXISD::TexUnified1DArrayU32Float)
+    MAKE_CASE(NVPTXISD::TexUnified1DArrayU32FloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnified1DArrayU32FloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnified2DFloatS32)
+    MAKE_CASE(NVPTXISD::TexUnified2DFloatFloat)
+    MAKE_CASE(NVPTXISD::TexUnified2DFloatFloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnified2DFloatFloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnified2DS32S32)
+    MAKE_CASE(NVPTXISD::TexUnified2DS32Float)
+    MAKE_CASE(NVPTXISD::TexUnified2DS32FloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnified2DS32FloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnified2DU32S32)
+    MAKE_CASE(NVPTXISD::TexUnified2DU32Float)
+    MAKE_CASE(NVPTXISD::TexUnified2DU32FloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnified2DU32FloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnified2DArrayFloatS32)
+    MAKE_CASE(NVPTXISD::TexUnified2DArrayFloatFloat)
+    MAKE_CASE(NVPTXISD::TexUnified2DArrayFloatFloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnified2DArrayFloatFloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnified2DArrayS32S32)
+    MAKE_CASE(NVPTXISD::TexUnified2DArrayS32Float)
+    MAKE_CASE(NVPTXISD::TexUnified2DArrayS32FloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnified2DArrayS32FloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnified2DArrayU32S32)
+    MAKE_CASE(NVPTXISD::TexUnified2DArrayU32Float)
+    MAKE_CASE(NVPTXISD::TexUnified2DArrayU32FloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnified2DArrayU32FloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnified3DFloatS32)
+    MAKE_CASE(NVPTXISD::TexUnified3DFloatFloat)
+    MAKE_CASE(NVPTXISD::TexUnified3DFloatFloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnified3DFloatFloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnified3DS32S32)
+    MAKE_CASE(NVPTXISD::TexUnified3DS32Float)
+    MAKE_CASE(NVPTXISD::TexUnified3DS32FloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnified3DS32FloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnified3DU32S32)
+    MAKE_CASE(NVPTXISD::TexUnified3DU32Float)
+    MAKE_CASE(NVPTXISD::TexUnified3DU32FloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnified3DU32FloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnifiedCubeFloatFloat)
+    MAKE_CASE(NVPTXISD::TexUnifiedCubeFloatFloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnifiedCubeS32Float)
+    MAKE_CASE(NVPTXISD::TexUnifiedCubeS32FloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnifiedCubeU32Float)
+    MAKE_CASE(NVPTXISD::TexUnifiedCubeU32FloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnifiedCubeArrayFloatFloat)
+    MAKE_CASE(NVPTXISD::TexUnifiedCubeArrayFloatFloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnifiedCubeArrayS32Float)
+    MAKE_CASE(NVPTXISD::TexUnifiedCubeArrayS32FloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnifiedCubeArrayU32Float)
+    MAKE_CASE(NVPTXISD::TexUnifiedCubeArrayU32FloatLevel)
+    MAKE_CASE(NVPTXISD::TexUnifiedCubeFloatFloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnifiedCubeS32FloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnifiedCubeU32FloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnifiedCubeArrayFloatFloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnifiedCubeArrayS32FloatGrad)
+    MAKE_CASE(NVPTXISD::TexUnifiedCubeArrayU32FloatGrad)
+    MAKE_CASE(NVPTXISD::Tld4UnifiedR2DFloatFloat)
+    MAKE_CASE(NVPTXISD::Tld4UnifiedG2DFloatFloat)
+    MAKE_CASE(NVPTXISD::Tld4UnifiedB2DFloatFloat)
+    MAKE_CASE(NVPTXISD::Tld4UnifiedA2DFloatFloat)
+    MAKE_CASE(NVPTXISD::Tld4UnifiedR2DS64Float)
+    MAKE_CASE(NVPTXISD::Tld4UnifiedG2DS64Float)
+    MAKE_CASE(NVPTXISD::Tld4UnifiedB2DS64Float)
+    MAKE_CASE(NVPTXISD::Tld4UnifiedA2DS64Float)
+    MAKE_CASE(NVPTXISD::Tld4UnifiedR2DU64Float)
+    MAKE_CASE(NVPTXISD::Tld4UnifiedG2DU64Float)
+    MAKE_CASE(NVPTXISD::Tld4UnifiedB2DU64Float)
+    MAKE_CASE(NVPTXISD::Tld4UnifiedA2DU64Float)
+
+    MAKE_CASE(NVPTXISD::Suld1DI8Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DI16Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DI32Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DI64Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DV2I8Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DV2I16Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DV2I32Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DV2I64Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DV4I8Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DV4I16Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DV4I32Clamp)
+
+    MAKE_CASE(NVPTXISD::Suld1DArrayI8Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DArrayI16Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DArrayI32Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DArrayI64Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV2I8Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV2I16Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV2I32Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV2I64Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV4I8Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV4I16Clamp)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV4I32Clamp)
+
+    MAKE_CASE(NVPTXISD::Suld2DI8Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DI16Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DI32Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DI64Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DV2I8Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DV2I16Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DV2I32Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DV2I64Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DV4I8Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DV4I16Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DV4I32Clamp)
+
+    MAKE_CASE(NVPTXISD::Suld2DArrayI8Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DArrayI16Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DArrayI32Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DArrayI64Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV2I8Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV2I16Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV2I32Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV2I64Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV4I8Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV4I16Clamp)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV4I32Clamp)
+
+    MAKE_CASE(NVPTXISD::Suld3DI8Clamp)
+    MAKE_CASE(NVPTXISD::Suld3DI16Clamp)
+    MAKE_CASE(NVPTXISD::Suld3DI32Clamp)
+    MAKE_CASE(NVPTXISD::Suld3DI64Clamp)
+    MAKE_CASE(NVPTXISD::Suld3DV2I8Clamp)
+    MAKE_CASE(NVPTXISD::Suld3DV2I16Clamp)
+    MAKE_CASE(NVPTXISD::Suld3DV2I32Clamp)
+    MAKE_CASE(NVPTXISD::Suld3DV2I64Clamp)
+    MAKE_CASE(NVPTXISD::Suld3DV4I8Clamp)
+    MAKE_CASE(NVPTXISD::Suld3DV4I16Clamp)
+    MAKE_CASE(NVPTXISD::Suld3DV4I32Clamp)
+
+    MAKE_CASE(NVPTXISD::Suld1DI8Trap)
+    MAKE_CASE(NVPTXISD::Suld1DI16Trap)
+    MAKE_CASE(NVPTXISD::Suld1DI32Trap)
+    MAKE_CASE(NVPTXISD::Suld1DI64Trap)
+    MAKE_CASE(NVPTXISD::Suld1DV2I8Trap)
+    MAKE_CASE(NVPTXISD::Suld1DV2I16Trap)
+    MAKE_CASE(NVPTXISD::Suld1DV2I32Trap)
+    MAKE_CASE(NVPTXISD::Suld1DV2I64Trap)
+    MAKE_CASE(NVPTXISD::Suld1DV4I8Trap)
+    MAKE_CASE(NVPTXISD::Suld1DV4I16Trap)
+    MAKE_CASE(NVPTXISD::Suld1DV4I32Trap)
+
+    MAKE_CASE(NVPTXISD::Suld1DArrayI8Trap)
+    MAKE_CASE(NVPTXISD::Suld1DArrayI16Trap)
+    MAKE_CASE(NVPTXISD::Suld1DArrayI32Trap)
+    MAKE_CASE(NVPTXISD::Suld1DArrayI64Trap)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV2I8Trap)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV2I16Trap)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV2I32Trap)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV2I64Trap)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV4I8Trap)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV4I16Trap)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV4I32Trap)
+
+    MAKE_CASE(NVPTXISD::Suld2DI8Trap)
+    MAKE_CASE(NVPTXISD::Suld2DI16Trap)
+    MAKE_CASE(NVPTXISD::Suld2DI32Trap)
+    MAKE_CASE(NVPTXISD::Suld2DI64Trap)
+    MAKE_CASE(NVPTXISD::Suld2DV2I8Trap)
+    MAKE_CASE(NVPTXISD::Suld2DV2I16Trap)
+    MAKE_CASE(NVPTXISD::Suld2DV2I32Trap)
+    MAKE_CASE(NVPTXISD::Suld2DV2I64Trap)
+    MAKE_CASE(NVPTXISD::Suld2DV4I8Trap)
+    MAKE_CASE(NVPTXISD::Suld2DV4I16Trap)
+    MAKE_CASE(NVPTXISD::Suld2DV4I32Trap)
+
+    MAKE_CASE(NVPTXISD::Suld2DArrayI8Trap)
+    MAKE_CASE(NVPTXISD::Suld2DArrayI16Trap)
+    MAKE_CASE(NVPTXISD::Suld2DArrayI32Trap)
+    MAKE_CASE(NVPTXISD::Suld2DArrayI64Trap)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV2I8Trap)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV2I16Trap)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV2I32Trap)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV2I64Trap)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV4I8Trap)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV4I16Trap)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV4I32Trap)
+
+    MAKE_CASE(NVPTXISD::Suld3DI8Trap)
+    MAKE_CASE(NVPTXISD::Suld3DI16Trap)
+    MAKE_CASE(NVPTXISD::Suld3DI32Trap)
+    MAKE_CASE(NVPTXISD::Suld3DI64Trap)
+    MAKE_CASE(NVPTXISD::Suld3DV2I8Trap)
+    MAKE_CASE(NVPTXISD::Suld3DV2I16Trap)
+    MAKE_CASE(NVPTXISD::Suld3DV2I32Trap)
+    MAKE_CASE(NVPTXISD::Suld3DV2I64Trap)
+    MAKE_CASE(NVPTXISD::Suld3DV4I8Trap)
+    MAKE_CASE(NVPTXISD::Suld3DV4I16Trap)
+    MAKE_CASE(NVPTXISD::Suld3DV4I32Trap)
+
+    MAKE_CASE(NVPTXISD::Suld1DI8Zero)
+    MAKE_CASE(NVPTXISD::Suld1DI16Zero)
+    MAKE_CASE(NVPTXISD::Suld1DI32Zero)
+    MAKE_CASE(NVPTXISD::Suld1DI64Zero)
+    MAKE_CASE(NVPTXISD::Suld1DV2I8Zero)
+    MAKE_CASE(NVPTXISD::Suld1DV2I16Zero)
+    MAKE_CASE(NVPTXISD::Suld1DV2I32Zero)
+    MAKE_CASE(NVPTXISD::Suld1DV2I64Zero)
+    MAKE_CASE(NVPTXISD::Suld1DV4I8Zero)
+    MAKE_CASE(NVPTXISD::Suld1DV4I16Zero)
+    MAKE_CASE(NVPTXISD::Suld1DV4I32Zero)
+
+    MAKE_CASE(NVPTXISD::Suld1DArrayI8Zero)
+    MAKE_CASE(NVPTXISD::Suld1DArrayI16Zero)
+    MAKE_CASE(NVPTXISD::Suld1DArrayI32Zero)
+    MAKE_CASE(NVPTXISD::Suld1DArrayI64Zero)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV2I8Zero)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV2I16Zero)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV2I32Zero)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV2I64Zero)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV4I8Zero)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV4I16Zero)
+    MAKE_CASE(NVPTXISD::Suld1DArrayV4I32Zero)
+
+    MAKE_CASE(NVPTXISD::Suld2DI8Zero)
+    MAKE_CASE(NVPTXISD::Suld2DI16Zero)
+    MAKE_CASE(NVPTXISD::Suld2DI32Zero)
+    MAKE_CASE(NVPTXISD::Suld2DI64Zero)
+    MAKE_CASE(NVPTXISD::Suld2DV2I8Zero)
+    MAKE_CASE(NVPTXISD::Suld2DV2I16Zero)
+    MAKE_CASE(NVPTXISD::Suld2DV2I32Zero)
+    MAKE_CASE(NVPTXISD::Suld2DV2I64Zero)
+    MAKE_CASE(NVPTXISD::Suld2DV4I8Zero)
+    MAKE_CASE(NVPTXISD::Suld2DV4I16Zero)
+    MAKE_CASE(NVPTXISD::Suld2DV4I32Zero)
+
+    MAKE_CASE(NVPTXISD::Suld2DArrayI8Zero)
+    MAKE_CASE(NVPTXISD::Suld2DArrayI16Zero)
+    MAKE_CASE(NVPTXISD::Suld2DArrayI32Zero)
+    MAKE_CASE(NVPTXISD::Suld2DArrayI64Zero)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV2I8Zero)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV2I16Zero)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV2I32Zero)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV2I64Zero)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV4I8Zero)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV4I16Zero)
+    MAKE_CASE(NVPTXISD::Suld2DArrayV4I32Zero)
+
+    MAKE_CASE(NVPTXISD::Suld3DI8Zero)
+    MAKE_CASE(NVPTXISD::Suld3DI16Zero)
+    MAKE_CASE(NVPTXISD::Suld3DI32Zero)
+    MAKE_CASE(NVPTXISD::Suld3DI64Zero)
+    MAKE_CASE(NVPTXISD::Suld3DV2I8Zero)
+    MAKE_CASE(NVPTXISD::Suld3DV2I16Zero)
+    MAKE_CASE(NVPTXISD::Suld3DV2I32Zero)
+    MAKE_CASE(NVPTXISD::Suld3DV2I64Zero)
+    MAKE_CASE(NVPTXISD::Suld3DV4I8Zero)
+    MAKE_CASE(NVPTXISD::Suld3DV4I16Zero)
+    MAKE_CASE(NVPTXISD::Suld3DV4I32Zero)
+  }
+#undef MAKE_CASE
+
+  return SelectionDAGGenTargetInfo::getTargetNodeName(Opcode);
+}
+
 bool NVPTXSelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
+  // These nodes don't have corresponding entries in *.td files.
   if (Opcode >= NVPTXISD::FIRST_MEMORY_OPCODE &&
       Opcode <= NVPTXISD::LAST_MEMORY_OPCODE)
     return true;
-  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+
+  // These nodes lack SDNPMemOperand property in *.td files.
+  switch (static_cast<NVPTXISD::GenNodeType>(Opcode)) {
+  default:
+    break;
+  case NVPTXISD::LoadParam:
+  case NVPTXISD::LoadParamV2:
+  case NVPTXISD::LoadParamV4:
+  case NVPTXISD::StoreParam:
+  case NVPTXISD::StoreParamV2:
+  case NVPTXISD::StoreParamV4:
+  case NVPTXISD::StoreParamS32:
+  case NVPTXISD::StoreParamU32:
+  case NVPTXISD::StoreRetval:
+  case NVPTXISD::StoreRetvalV2:
+  case NVPTXISD::StoreRetvalV4:
+    return true;
+  }
+
+  return SelectionDAGGenTargetInfo::isTargetMemoryOpcode(Opcode);
+}
+
+void NVPTXSelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
+                                             const SDNode *N) const {
+  switch (N->getOpcode()) {
+  default:
+    break;
+  case NVPTXISD::ProxyReg:
+    // invalid number of results; expected 3, got 1
+  case NVPTXISD::BrxEnd:
+    // invalid number of results; expected 1, got 2
+    return;
+  }
+
+  return SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
 }
diff --git a/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.h b/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.h
index bf743e12318606..8b232110abce16 100644
--- a/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.h
+++ b/llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.h
@@ -11,13 +11,403 @@
 
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 
+#define GET_SDNODE_ENUM
+#include "NVPTXGenSDNodeInfo.inc"
+
 namespace llvm {
+namespace NVPTXISD {
+
+enum NodeType : unsigned {
+  LOAD_PARAM = GENERATED_OPCODE_END,
+  DeclareScalarRet,
+  CallSymbol,
+  CallSeqBegin,
+  CallSeqEnd,
+  SETP_F16X2,
+  SETP_BF16X2,
+  Dummy,
+
+  FIRST_MEMORY_OPCODE,
+  LoadV2 = FIRST_MEMORY_OPCODE,
+  LoadV4,
+  LDUV2, // LDU.v2
+  LDUV4, // LDU.v4
+  StoreV2,
+  StoreV4,
+
+  // Texture intrinsics
+  Tex1DFloatS32,
+  Tex1DFloatFloat,
+  Tex1DFloatFloatLevel,
+  Tex1DFloatFloatGrad,
+  Tex1DS32S32,
+  Tex1DS32Float,
+  Tex1DS32FloatLevel,
+  Tex1DS32FloatGrad,
+  Tex1DU32S32,
+  Tex1DU32Float,
+  Tex1DU32FloatLevel,
+  Tex1DU32FloatGrad,
+  Tex1DArrayFloatS32,
+  Tex1DArrayFloatFloat,
+  Tex1DArrayFloatFloatLevel,
+  Tex1DArrayFloatFloatGrad,
+  Tex1DArrayS32S32,
+  Tex1DArrayS32Float,
+  Tex1DArrayS32FloatLevel,
+  Tex1DArrayS32FloatGrad,
+  Tex1DArrayU32S32,
+  Tex1DArrayU32Float,
+  Tex1DArrayU32FloatLevel,
+  Tex1DArrayU32FloatGrad,
+  Tex2DFloatS32,
+  Tex2DFloatFloat,
+  Tex2DFloatFloatLevel,
+  Tex2DFloatFloatGrad,
+  Tex2DS32S32,
+  Tex2DS32Float,
+  Tex2DS32FloatLevel,
+  Tex2DS32FloatGrad,
+  Tex2DU32S32,
+  Tex2DU32Float,
+  Tex2DU32FloatLevel,
+  Tex2DU32FloatGrad,
+  Tex2DArrayFloatS32,
+  Tex2DArrayFloatFloat,
+  Tex2DArrayFloatFloatLevel,
+  Tex2DArrayFloatFloatGrad,
+  Tex2DArrayS32S32,
+  Tex2DArrayS32Float,
+  Tex2DArrayS32FloatLevel,
+  Tex2DArrayS32FloatGrad,
+  Tex2DArrayU32S32,
+  Tex2DArrayU32Float,
+  Tex2DArrayU32FloatLevel,
+  Tex2DArrayU32FloatGrad,
+  Tex3DFloatS32,
+  Tex3DFloatFloat,
+  Tex3DFloatFloatLevel,
+  Tex3DFloatFloatGrad,
+  Tex3DS32S32,
+  Tex3DS32Float,
+  Tex3DS32FloatLevel,
+  Tex3DS32FloatGrad,
+  Tex3DU32S32,
+  Tex3DU32Float,
+  Tex3DU32FloatLevel,
+  Tex3DU32FloatGrad,
+  TexCubeFloatFloat,
+  TexCubeFloatFloatLevel,
+  TexCubeS32Float,
+  TexCubeS32FloatLevel,
+  TexCubeU32Float,
+  TexCubeU32FloatLevel,
+  TexCubeArrayFloatFloat,
+  TexCubeArrayFloatFloatLevel,
+  TexCubeArrayS32Float,
+  TexCubeArrayS32FloatLevel,
+  TexCubeArrayU32Float,
+  TexCubeArrayU32FloatLevel,
+  Tld4R2DFloatFloat,
+  Tld4G2DFloatFloat,
+  Tld4B2DFloatFloat,
+  Tld4A2DFloatFloat,
+  Tld4R2DS64Float,
+  Tld4G2DS64Float,
+  Tld4B2DS64Float,
+  Tld4A2DS64Float,
+  Tld4R2DU64Float,
+  Tld4G2DU64Float,
+  Tld4B2DU64Float,
+  Tld4A2DU64Float,
+  TexUnified1DFloatS32,
+  TexUnified1DFloatFloat,
+  TexUnified1DFloatFloatLevel,
+  TexUnified1DFloatFloatGrad,
+  TexUnified1DS32S32,
+  TexUnified1DS32Float,
+  TexUnified1DS32FloatLevel,
+  TexUnified1DS32FloatGrad,
+  TexUnified1DU32S32,
+  TexUnified1DU32Float,
+  TexUnified1DU32FloatLevel,
+  TexUnified1DU32FloatGrad,
+  TexUnified1DArrayFloatS32,
+  TexUnified1DArrayFloatFloat,
+  TexUnified1DArrayFloatFloatLevel,
+  TexUnified1DArrayFloatFloatGrad,
+  TexUnified1DArrayS32S32,
+  TexUnified1DArrayS32Float,
+  TexUnified1DArrayS32FloatLevel,
+  TexUnified1DArrayS32FloatGrad,
+  TexUnified1DArrayU32S32,
+  TexUnified1DArrayU32Float,
+  TexUnified1DArrayU32FloatLevel,
+  TexUnified1DArrayU32FloatGrad,
+  TexUnified2DFloatS32,
+  TexUnified2DFloatFloat,
+  TexUnified2DFloatFloatLevel,
+  TexUnified2DFloatFloatGrad,
+  TexUnified2DS32S32,
+  TexUnified2DS32Float,
+  TexUnified2DS32FloatLevel,
+  TexUnified2DS32FloatGrad,
+  TexUnified2DU32S32,
+  TexUnified2DU32Float,
+  TexUnified2DU32FloatLevel,
+  TexUnified2DU32FloatGrad,
+  TexUnified2DArrayFloatS32,
+  TexUnified2DArrayFloatFloat,
+  TexUnified2DArrayFloatFloatLevel,
+  TexUnified2DArrayFloatFloatGrad,
+  TexUnified2DArrayS32S32,
+  TexUnified2DArrayS32Float,
+  TexUnified2DArrayS32FloatLevel,
+  TexUnified2DArrayS32FloatGrad,
+  TexUnified2DArrayU32S32,
+  TexUnified2DArrayU32Float,
+  TexUnified2DArrayU32FloatLevel,
+  TexUnified2DArrayU32FloatGrad,
+  TexUnified3DFloatS32,
+  TexUnified3DFloatFloat,
+  TexUnified3DFloatFloatLevel,
+  TexUnified3DFloatFloatGrad,
+  TexUnified3DS32S32,
+  TexUnified3DS32Float,
+  TexUnified3DS32FloatLevel,
+  TexUnified3DS32FloatGrad,
+  TexUnified3DU32S32,
+  TexUnified3DU32Float,
+  TexUnified3DU32FloatLevel,
+  TexUnified3DU32FloatGrad,
+  TexUnifiedCubeFloatFloat,
+  TexUnifiedCubeFloatFloatLevel,
+  TexUnifiedCubeS32Float,
+  TexUnifiedCubeS32FloatLevel,
+  TexUnifiedCubeU32Float,
+  TexUnifiedCubeU32FloatLevel,
+  TexUnifiedCubeArrayFloatFloat,
+  TexUnifiedCubeArrayFloatFloatLevel,
+  TexUnifiedCubeArrayS32Float,
+  TexUnifiedCubeArrayS32FloatLevel,
+  TexUnifiedCubeArrayU32Float,
+  TexUnifiedCubeArrayU32FloatLevel,
+  TexUnifiedCubeFloatFloatGrad,
+  TexUnifiedCubeS32FloatGrad,
+  TexUnifiedCubeU32FloatGrad,
+  TexUnifiedCubeArrayFloatFloatGrad,
+  TexUnifiedCubeArrayS32FloatGrad,
+  TexUnifiedCubeArrayU32FloatGrad,
+  Tld4UnifiedR2DFloatFloat,
+  Tld4UnifiedG2DFloatFloat,
+  Tld4UnifiedB2DFloatFloat,
+  Tld4UnifiedA2DFloatFloat,
+  Tld4UnifiedR2DS64Float,
+  Tld4UnifiedG2DS64Float,
+  Tld4UnifiedB2DS64Float,
+  Tld4UnifiedA2DS64Float,
+  Tld4UnifiedR2DU64Float,
+  Tld4UnifiedG2DU64Float,
+  Tld4UnifiedB2DU64Float,
+  Tld4UnifiedA2DU64Float,
+
+  // Surface intrinsics
+  Suld1DI8Clamp,
+  Suld1DI16Clamp,
+  Suld1DI32Clamp,
+  Suld1DI64Clamp,
+  Suld1DV2I8Clamp,
+  Suld1DV2I16Clamp,
+  Suld1DV2I32Clamp,
+  Suld1DV2I64Clamp,
+  Suld1DV4I8Clamp,
+  Suld1DV4I16Clamp,
+  Suld1DV4I32Clamp,
+
+  Suld1DArrayI8Clamp,
+  Suld1DArrayI16Clamp,
+  Suld1DArrayI32Clamp,
+  Suld1DArrayI64Clamp,
+  Suld1DArrayV2I8Clamp,
+  Suld1DArrayV2I16Clamp,
+  Suld1DArrayV2I32Clamp,
+  Suld1DArrayV2I64Clamp,
+  Suld1DArrayV4I8Clamp,
+  Suld1DArrayV4I16Clamp,
+  Suld1DArrayV4I32Clamp,
+
+  Suld2DI8Clamp,
+  Suld2DI16Clamp,
+  Suld2DI32Clamp,
+  Suld2DI64Clamp,
+  Suld2DV2I8Clamp,
+  Suld2DV2I16Clamp,
+  Suld2DV2I32Clamp,
+  Suld2DV2I64Clamp,
+  Suld2DV4I8Clamp,
+  Suld2DV4I16Clamp,
+  Suld2DV4I32Clamp,
+
+  Suld2DArrayI8Clamp,
+  Suld2DArrayI16Clamp,
+  Suld2DArrayI32Clamp,
+  Suld2DArrayI64Clamp,
+  Suld2DArrayV2I8Clamp,
+  Suld2DArrayV2I16Clamp,
+  Suld2DArrayV2I32Clamp,
+  Suld2DArrayV2I64Clamp,
+  Suld2DArrayV4I8Clamp,
+  Suld2DArrayV4I16Clamp,
+  Suld2DArrayV4I32Clamp,
+
+  Suld3DI8Clamp,
+  Suld3DI16Clamp,
+  Suld3DI32Clamp,
+  Suld3DI64Clamp,
+  Suld3DV2I8Clamp,
+  Suld3DV2I16Clamp,
+  Suld3DV2I32Clamp,
+  Suld3DV2I64Clamp,
+  Suld3DV4I8Clamp,
+  Suld3DV4I16Clamp,
+  Suld3DV4I32Clamp,
+
+  Suld1DI8Trap,
+  Suld1DI16Trap,
+  Suld1DI32Trap,
+  Suld1DI64Trap,
+  Suld1DV2I8Trap,
+  Suld1DV2I16Trap,
+  Suld1DV2I32Trap,
+  Suld1DV2I64Trap,
+  Suld1DV4I8Trap,
+  Suld1DV4I16Trap,
+  Suld1DV4I32Trap,
+
+  Suld1DArrayI8Trap,
+  Suld1DArrayI16Trap,
+  Suld1DArrayI32Trap,
+  Suld1DArrayI64Trap,
+  Suld1DArrayV2I8Trap,
+  Suld1DArrayV2I16Trap,
+  Suld1DArrayV2I32Trap,
+  Suld1DArrayV2I64Trap,
+  Suld1DArrayV4I8Trap,
+  Suld1DArrayV4I16Trap,
+  Suld1DArrayV4I32Trap,
+
+  Suld2DI8Trap,
+  Suld2DI16Trap,
+  Suld2DI32Trap,
+  Suld2DI64Trap,
+  Suld2DV2I8Trap,
+  Suld2DV2I16Trap,
+  Suld2DV2I32Trap,
+  Suld2DV2I64Trap,
+  Suld2DV4I8Trap,
+  Suld2DV4I16Trap,
+  Suld2DV4I32Trap,
 
-class NVPTXSelectionDAGInfo : public SelectionDAGTargetInfo {
+  Suld2DArrayI8Trap,
+  Suld2DArrayI16Trap,
+  Suld2DArrayI32Trap,
+  Suld2DArrayI64Trap,
+  Suld2DArrayV2I8Trap,
+  Suld2DArrayV2I16Trap,
+  Suld2DArrayV2I32Trap,
+  Suld2DArrayV2I64Trap,
+  Suld2DArrayV4I8Trap,
+  Suld2DArrayV4I16Trap,
+  Suld2DArrayV4I32Trap,
+
+  Suld3DI8Trap,
+  Suld3DI16Trap,
+  Suld3DI32Trap,
+  Suld3DI64Trap,
+  Suld3DV2I8Trap,
+  Suld3DV2I16Trap,
+  Suld3DV2I32Trap,
+  Suld3DV2I64Trap,
+  Suld3DV4I8Trap,
+  Suld3DV4I16Trap,
+  Suld3DV4I32Trap,
+
+  Suld1DI8Zero,
+  Suld1DI16Zero,
+  Suld1DI32Zero,
+  Suld1DI64Zero,
+  Suld1DV2I8Zero,
+  Suld1DV2I16Zero,
+  Suld1DV2I32Zero,
+  Suld1DV2I64Zero,
+  Suld1DV4I8Zero,
+  Suld1DV4I16Zero,
+  Suld1DV4I32Zero,
+
+  Suld1DArrayI8Zero,
+  Suld1DArrayI16Zero,
+  Suld1DArrayI32Zero,
+  Suld1DArrayI64Zero,
+  Suld1DArrayV2I8Zero,
+  Suld1DArrayV2I16Zero,
+  Suld1DArrayV2I32Zero,
+  Suld1DArrayV2I64Zero,
+  Suld1DArrayV4I8Zero,
+  Suld1DArrayV4I16Zero,
+  Suld1DArrayV4I32Zero,
+
+  Suld2DI8Zero,
+  Suld2DI16Zero,
+  Suld2DI32Zero,
+  Suld2DI64Zero,
+  Suld2DV2I8Zero,
+  Suld2DV2I16Zero,
+  Suld2DV2I32Zero,
+  Suld2DV2I64Zero,
+  Suld2DV4I8Zero,
+  Suld2DV4I16Zero,
+  Suld2DV4I32Zero,
+
+  Suld2DArrayI8Zero,
+  Suld2DArrayI16Zero,
+  Suld2DArrayI32Zero,
+  Suld2DArrayI64Zero,
+  Suld2DArrayV2I8Zero,
+  Suld2DArrayV2I16Zero,
+  Suld2DArrayV2I32Zero,
+  Suld2DArrayV2I64Zero,
+  Suld2DArrayV4I8Zero,
+  Suld2DArrayV4I16Zero,
+  Suld2DArrayV4I32Zero,
+
+  Suld3DI8Zero,
+  Suld3DI16Zero,
+  Suld3DI32Zero,
+  Suld3DI64Zero,
+  Suld3DV2I8Zero,
+  Suld3DV2I16Zero,
+  Suld3DV2I32Zero,
+  Suld3DV2I64Zero,
+  Suld3DV4I8Zero,
+  Suld3DV4I16Zero,
+  Suld3DV4I32Zero,
+  LAST_MEMORY_OPCODE = Suld3DV4I32Zero,
+};
+
+} // namespace NVPTXISD
+
+class NVPTXSelectionDAGInfo : public SelectionDAGGenTargetInfo {
 public:
+  NVPTXSelectionDAGInfo();
+
   ~NVPTXSelectionDAGInfo() override;
 
+  const char *getTargetNodeName(unsigned Opcode) const override;
+
   bool isTargetMemoryOpcode(unsigned Opcode) const override;
+
+  void verifyTargetNode(const SelectionDAG &DAG,
+                        const SDNode *N) const override;
 };
 
 } // namespace llvm

>From e51ba0a0f616740cadb20f4b3effde6826e2e568 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 01:02:16 +0300
Subject: [PATCH 18/27] PowerPC

---
 llvm/lib/Target/PowerPC/CMakeLists.txt        |   1 +
 llvm/lib/Target/PowerPC/PPCFastISel.cpp       |   1 +
 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp   |   1 +
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp   | 178 +-----
 llvm/lib/Target/PowerPC/PPCISelLowering.h     | 581 ------------------
 llvm/lib/Target/PowerPC/PPCInstrInfo.td       |  36 +-
 .../Target/PowerPC/PPCSelectionDAGInfo.cpp    |  68 +-
 llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h |  57 +-
 8 files changed, 128 insertions(+), 795 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/CMakeLists.txt b/llvm/lib/Target/PowerPC/CMakeLists.txt
index 3808a26a0b92a0..d1611e93cbd2e4 100644
--- a/llvm/lib/Target/PowerPC/CMakeLists.txt
+++ b/llvm/lib/Target/PowerPC/CMakeLists.txt
@@ -11,6 +11,7 @@ tablegen(LLVM PPCGenFastISel.inc -gen-fast-isel)
 tablegen(LLVM PPCGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM PPCGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM PPCGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM PPCGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM PPCGenSubtargetInfo.inc -gen-subtarget)
 tablegen(LLVM PPCGenExegesis.inc -gen-exegesis)
 tablegen(LLVM PPCGenRegisterBank.inc -gen-register-bank)
diff --git a/llvm/lib/Target/PowerPC/PPCFastISel.cpp b/llvm/lib/Target/PowerPC/PPCFastISel.cpp
index 43e9a44a940b86..f0e86e4d171abf 100644
--- a/llvm/lib/Target/PowerPC/PPCFastISel.cpp
+++ b/llvm/lib/Target/PowerPC/PPCFastISel.cpp
@@ -17,6 +17,7 @@
 #include "PPCCallingConv.h"
 #include "PPCISelLowering.h"
 #include "PPCMachineFunctionInfo.h"
+#include "PPCSelectionDAGInfo.h"
 #include "PPCSubtarget.h"
 #include "llvm/CodeGen/CallingConvLower.h"
 #include "llvm/CodeGen/FastISel.h"
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 2475b8ad11f10a..cbea7b3905dd06 100644
--- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -16,6 +16,7 @@
 #include "PPC.h"
 #include "PPCISelLowering.h"
 #include "PPCMachineFunctionInfo.h"
+#include "PPCSelectionDAGInfo.h"
 #include "PPCSubtarget.h"
 #include "PPCTargetMachine.h"
 #include "llvm/ADT/APInt.h"
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 69bc2cce6c2c7d..3dc3abb4158e32 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -21,6 +21,7 @@
 #include "PPCMachineFunctionInfo.h"
 #include "PPCPerfectShuffle.h"
 #include "PPCRegisterInfo.h"
+#include "PPCSelectionDAGInfo.h"
 #include "PPCSubtarget.h"
 #include "PPCTargetMachine.h"
 #include "llvm/ADT/APFloat.h"
@@ -1681,183 +1682,6 @@ bool PPCTargetLowering::shallExtractConstSplatVectorElementToStore(
   return false;
 }
 
-const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
-  switch ((PPCISD::NodeType)Opcode) {
-  case PPCISD::FIRST_NUMBER:    break;
-  case PPCISD::FSEL:            return "PPCISD::FSEL";
-  case PPCISD::XSMAXC:          return "PPCISD::XSMAXC";
-  case PPCISD::XSMINC:          return "PPCISD::XSMINC";
-  case PPCISD::FCFID:           return "PPCISD::FCFID";
-  case PPCISD::FCFIDU:          return "PPCISD::FCFIDU";
-  case PPCISD::FCFIDS:          return "PPCISD::FCFIDS";
-  case PPCISD::FCFIDUS:         return "PPCISD::FCFIDUS";
-  case PPCISD::FCTIDZ:          return "PPCISD::FCTIDZ";
-  case PPCISD::FCTIWZ:          return "PPCISD::FCTIWZ";
-  case PPCISD::FCTIDUZ:         return "PPCISD::FCTIDUZ";
-  case PPCISD::FCTIWUZ:         return "PPCISD::FCTIWUZ";
-  case PPCISD::FRE:             return "PPCISD::FRE";
-  case PPCISD::FRSQRTE:         return "PPCISD::FRSQRTE";
-  case PPCISD::FTSQRT:
-    return "PPCISD::FTSQRT";
-  case PPCISD::FSQRT:
-    return "PPCISD::FSQRT";
-  case PPCISD::STFIWX:          return "PPCISD::STFIWX";
-  case PPCISD::VPERM:           return "PPCISD::VPERM";
-  case PPCISD::XXSPLT:          return "PPCISD::XXSPLT";
-  case PPCISD::XXSPLTI_SP_TO_DP:
-    return "PPCISD::XXSPLTI_SP_TO_DP";
-  case PPCISD::XXSPLTI32DX:
-    return "PPCISD::XXSPLTI32DX";
-  case PPCISD::VECINSERT:       return "PPCISD::VECINSERT";
-  case PPCISD::XXPERMDI:        return "PPCISD::XXPERMDI";
-  case PPCISD::XXPERM:
-    return "PPCISD::XXPERM";
-  case PPCISD::VECSHL:          return "PPCISD::VECSHL";
-  case PPCISD::CMPB:            return "PPCISD::CMPB";
-  case PPCISD::Hi:              return "PPCISD::Hi";
-  case PPCISD::Lo:              return "PPCISD::Lo";
-  case PPCISD::TOC_ENTRY:       return "PPCISD::TOC_ENTRY";
-  case PPCISD::ATOMIC_CMP_SWAP_8: return "PPCISD::ATOMIC_CMP_SWAP_8";
-  case PPCISD::ATOMIC_CMP_SWAP_16: return "PPCISD::ATOMIC_CMP_SWAP_16";
-  case PPCISD::DYNALLOC:        return "PPCISD::DYNALLOC";
-  case PPCISD::DYNAREAOFFSET:   return "PPCISD::DYNAREAOFFSET";
-  case PPCISD::PROBED_ALLOCA:   return "PPCISD::PROBED_ALLOCA";
-  case PPCISD::GlobalBaseReg:   return "PPCISD::GlobalBaseReg";
-  case PPCISD::SRL:             return "PPCISD::SRL";
-  case PPCISD::SRA:             return "PPCISD::SRA";
-  case PPCISD::SHL:             return "PPCISD::SHL";
-  case PPCISD::SRA_ADDZE:       return "PPCISD::SRA_ADDZE";
-  case PPCISD::CALL:            return "PPCISD::CALL";
-  case PPCISD::CALL_NOP:        return "PPCISD::CALL_NOP";
-  case PPCISD::CALL_NOTOC:      return "PPCISD::CALL_NOTOC";
-  case PPCISD::CALL_RM:
-    return "PPCISD::CALL_RM";
-  case PPCISD::CALL_NOP_RM:
-    return "PPCISD::CALL_NOP_RM";
-  case PPCISD::CALL_NOTOC_RM:
-    return "PPCISD::CALL_NOTOC_RM";
-  case PPCISD::MTCTR:           return "PPCISD::MTCTR";
-  case PPCISD::BCTRL:           return "PPCISD::BCTRL";
-  case PPCISD::BCTRL_LOAD_TOC:  return "PPCISD::BCTRL_LOAD_TOC";
-  case PPCISD::BCTRL_RM:
-    return "PPCISD::BCTRL_RM";
-  case PPCISD::BCTRL_LOAD_TOC_RM:
-    return "PPCISD::BCTRL_LOAD_TOC_RM";
-  case PPCISD::RET_GLUE:        return "PPCISD::RET_GLUE";
-  case PPCISD::READ_TIME_BASE:  return "PPCISD::READ_TIME_BASE";
-  case PPCISD::EH_SJLJ_SETJMP:  return "PPCISD::EH_SJLJ_SETJMP";
-  case PPCISD::EH_SJLJ_LONGJMP: return "PPCISD::EH_SJLJ_LONGJMP";
-  case PPCISD::MFOCRF:          return "PPCISD::MFOCRF";
-  case PPCISD::MFVSR:           return "PPCISD::MFVSR";
-  case PPCISD::MTVSRA:          return "PPCISD::MTVSRA";
-  case PPCISD::MTVSRZ:          return "PPCISD::MTVSRZ";
-  case PPCISD::SINT_VEC_TO_FP:  return "PPCISD::SINT_VEC_TO_FP";
-  case PPCISD::UINT_VEC_TO_FP:  return "PPCISD::UINT_VEC_TO_FP";
-  case PPCISD::SCALAR_TO_VECTOR_PERMUTED:
-    return "PPCISD::SCALAR_TO_VECTOR_PERMUTED";
-  case PPCISD::ANDI_rec_1_EQ_BIT:
-    return "PPCISD::ANDI_rec_1_EQ_BIT";
-  case PPCISD::ANDI_rec_1_GT_BIT:
-    return "PPCISD::ANDI_rec_1_GT_BIT";
-  case PPCISD::VCMP:            return "PPCISD::VCMP";
-  case PPCISD::VCMP_rec:        return "PPCISD::VCMP_rec";
-  case PPCISD::LBRX:            return "PPCISD::LBRX";
-  case PPCISD::STBRX:           return "PPCISD::STBRX";
-  case PPCISD::LFIWAX:          return "PPCISD::LFIWAX";
-  case PPCISD::LFIWZX:          return "PPCISD::LFIWZX";
-  case PPCISD::LXSIZX:          return "PPCISD::LXSIZX";
-  case PPCISD::STXSIX:          return "PPCISD::STXSIX";
-  case PPCISD::VEXTS:           return "PPCISD::VEXTS";
-  case PPCISD::LXVD2X:          return "PPCISD::LXVD2X";
-  case PPCISD::STXVD2X:         return "PPCISD::STXVD2X";
-  case PPCISD::LOAD_VEC_BE:     return "PPCISD::LOAD_VEC_BE";
-  case PPCISD::STORE_VEC_BE:    return "PPCISD::STORE_VEC_BE";
-  case PPCISD::ST_VSR_SCAL_INT:
-                                return "PPCISD::ST_VSR_SCAL_INT";
-  case PPCISD::COND_BRANCH:     return "PPCISD::COND_BRANCH";
-  case PPCISD::BDNZ:            return "PPCISD::BDNZ";
-  case PPCISD::BDZ:             return "PPCISD::BDZ";
-  case PPCISD::MFFS:            return "PPCISD::MFFS";
-  case PPCISD::FADDRTZ:         return "PPCISD::FADDRTZ";
-  case PPCISD::TC_RETURN:       return "PPCISD::TC_RETURN";
-  case PPCISD::CR6SET:          return "PPCISD::CR6SET";
-  case PPCISD::CR6UNSET:        return "PPCISD::CR6UNSET";
-  case PPCISD::PPC32_GOT:       return "PPCISD::PPC32_GOT";
-  case PPCISD::PPC32_PICGOT:    return "PPCISD::PPC32_PICGOT";
-  case PPCISD::ADDIS_GOT_TPREL_HA: return "PPCISD::ADDIS_GOT_TPREL_HA";
-  case PPCISD::LD_GOT_TPREL_L:  return "PPCISD::LD_GOT_TPREL_L";
-  case PPCISD::ADD_TLS:         return "PPCISD::ADD_TLS";
-  case PPCISD::ADDIS_TLSGD_HA:  return "PPCISD::ADDIS_TLSGD_HA";
-  case PPCISD::ADDI_TLSGD_L:    return "PPCISD::ADDI_TLSGD_L";
-  case PPCISD::GET_TLS_ADDR:    return "PPCISD::GET_TLS_ADDR";
-  case PPCISD::GET_TLS_MOD_AIX: return "PPCISD::GET_TLS_MOD_AIX";
-  case PPCISD::GET_TPOINTER:    return "PPCISD::GET_TPOINTER";
-  case PPCISD::ADDI_TLSGD_L_ADDR: return "PPCISD::ADDI_TLSGD_L_ADDR";
-  case PPCISD::TLSGD_AIX:       return "PPCISD::TLSGD_AIX";
-  case PPCISD::TLSLD_AIX:       return "PPCISD::TLSLD_AIX";
-  case PPCISD::ADDIS_TLSLD_HA:  return "PPCISD::ADDIS_TLSLD_HA";
-  case PPCISD::ADDI_TLSLD_L:    return "PPCISD::ADDI_TLSLD_L";
-  case PPCISD::GET_TLSLD_ADDR:  return "PPCISD::GET_TLSLD_ADDR";
-  case PPCISD::ADDI_TLSLD_L_ADDR: return "PPCISD::ADDI_TLSLD_L_ADDR";
-  case PPCISD::ADDIS_DTPREL_HA: return "PPCISD::ADDIS_DTPREL_HA";
-  case PPCISD::ADDI_DTPREL_L:   return "PPCISD::ADDI_DTPREL_L";
-  case PPCISD::PADDI_DTPREL:
-    return "PPCISD::PADDI_DTPREL";
-  case PPCISD::VADD_SPLAT:      return "PPCISD::VADD_SPLAT";
-  case PPCISD::SC:              return "PPCISD::SC";
-  case PPCISD::CLRBHRB:         return "PPCISD::CLRBHRB";
-  case PPCISD::MFBHRBE:         return "PPCISD::MFBHRBE";
-  case PPCISD::RFEBB:           return "PPCISD::RFEBB";
-  case PPCISD::XXSWAPD:         return "PPCISD::XXSWAPD";
-  case PPCISD::SWAP_NO_CHAIN:   return "PPCISD::SWAP_NO_CHAIN";
-  case PPCISD::BUILD_FP128:     return "PPCISD::BUILD_FP128";
-  case PPCISD::BUILD_SPE64:     return "PPCISD::BUILD_SPE64";
-  case PPCISD::EXTRACT_SPE:     return "PPCISD::EXTRACT_SPE";
-  case PPCISD::EXTSWSLI:        return "PPCISD::EXTSWSLI";
-  case PPCISD::LD_VSX_LH:       return "PPCISD::LD_VSX_LH";
-  case PPCISD::FP_EXTEND_HALF:  return "PPCISD::FP_EXTEND_HALF";
-  case PPCISD::MAT_PCREL_ADDR:  return "PPCISD::MAT_PCREL_ADDR";
-  case PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR:
-    return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
-  case PPCISD::TLS_LOCAL_EXEC_MAT_ADDR:
-    return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
-  case PPCISD::ACC_BUILD:       return "PPCISD::ACC_BUILD";
-  case PPCISD::PAIR_BUILD:      return "PPCISD::PAIR_BUILD";
-  case PPCISD::EXTRACT_VSX_REG: return "PPCISD::EXTRACT_VSX_REG";
-  case PPCISD::XXMFACC:         return "PPCISD::XXMFACC";
-  case PPCISD::LD_SPLAT:        return "PPCISD::LD_SPLAT";
-  case PPCISD::ZEXT_LD_SPLAT:   return "PPCISD::ZEXT_LD_SPLAT";
-  case PPCISD::SEXT_LD_SPLAT:   return "PPCISD::SEXT_LD_SPLAT";
-  case PPCISD::FNMSUB:          return "PPCISD::FNMSUB";
-  case PPCISD::STRICT_FADDRTZ:
-    return "PPCISD::STRICT_FADDRTZ";
-  case PPCISD::STRICT_FCTIDZ:
-    return "PPCISD::STRICT_FCTIDZ";
-  case PPCISD::STRICT_FCTIWZ:
-    return "PPCISD::STRICT_FCTIWZ";
-  case PPCISD::STRICT_FCTIDUZ:
-    return "PPCISD::STRICT_FCTIDUZ";
-  case PPCISD::STRICT_FCTIWUZ:
-    return "PPCISD::STRICT_FCTIWUZ";
-  case PPCISD::STRICT_FCFID:
-    return "PPCISD::STRICT_FCFID";
-  case PPCISD::STRICT_FCFIDU:
-    return "PPCISD::STRICT_FCFIDU";
-  case PPCISD::STRICT_FCFIDS:
-    return "PPCISD::STRICT_FCFIDS";
-  case PPCISD::STRICT_FCFIDUS:
-    return "PPCISD::STRICT_FCFIDUS";
-  case PPCISD::LXVRZX:          return "PPCISD::LXVRZX";
-  case PPCISD::STORE_COND:
-    return "PPCISD::STORE_COND";
-  case PPCISD::SETBC:
-    return "PPCISD::SETBC";
-  case PPCISD::SETBCR:
-    return "PPCISD::SETBCR";
-  }
-  return nullptr;
-}
-
 EVT PPCTargetLowering::getSetCCResultType(const DataLayout &DL, LLVMContext &C,
                                           EVT VT) const {
   if (!VT.isVector())
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index 7ee1b9bbbce511..aa1c8d2f5e355f 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -34,583 +34,6 @@
 
 namespace llvm {
 
-  namespace PPCISD {
-
-  // When adding a NEW PPCISD node please add it to the correct position in
-  // the enum. The order of elements in this enum matters!
-  // Values that are added between FIRST_MEMORY_OPCODE and LAST_MEMORY_OPCODE
-  // are considered memory opcodes and are treated differently than other
-  // entries.
-  enum NodeType : unsigned {
-    // Start the numbering where the builtin ops and target ops leave off.
-    FIRST_NUMBER = ISD::BUILTIN_OP_END,
-
-    /// FSEL - Traditional three-operand fsel node.
-    ///
-    FSEL,
-
-    /// XSMAXC[DQ]P, XSMINC[DQ]P - C-type min/max instructions.
-    XSMAXC,
-    XSMINC,
-
-    /// FCFID - The FCFID instruction, taking an f64 operand and producing
-    /// and f64 value containing the FP representation of the integer that
-    /// was temporarily in the f64 operand.
-    FCFID,
-
-    /// Newer FCFID[US] integer-to-floating-point conversion instructions for
-    /// unsigned integers and single-precision outputs.
-    FCFIDU,
-    FCFIDS,
-    FCFIDUS,
-
-    /// FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64
-    /// operand, producing an f64 value containing the integer representation
-    /// of that FP value.
-    FCTIDZ,
-    FCTIWZ,
-
-    /// Newer FCTI[D,W]UZ floating-point-to-integer conversion instructions for
-    /// unsigned integers with round toward zero.
-    FCTIDUZ,
-    FCTIWUZ,
-
-    /// VEXTS, ByteWidth - takes an input in VSFRC and produces an output in
-    /// VSFRC that is sign-extended from ByteWidth to a 64-byte integer.
-    VEXTS,
-
-    /// Reciprocal estimate instructions (unary FP ops).
-    FRE,
-    FRSQRTE,
-
-    /// Test instruction for software square root.
-    FTSQRT,
-
-    /// Square root instruction.
-    FSQRT,
-
-    /// VPERM - The PPC VPERM Instruction.
-    ///
-    VPERM,
-
-    /// XXSPLT - The PPC VSX splat instructions
-    ///
-    XXSPLT,
-
-    /// XXSPLTI_SP_TO_DP - The PPC VSX splat instructions for immediates for
-    /// converting immediate single precision numbers to double precision
-    /// vector or scalar.
-    XXSPLTI_SP_TO_DP,
-
-    /// XXSPLTI32DX - The PPC XXSPLTI32DX instruction.
-    ///
-    XXSPLTI32DX,
-
-    /// VECINSERT - The PPC vector insert instruction
-    ///
-    VECINSERT,
-
-    /// VECSHL - The PPC vector shift left instruction
-    ///
-    VECSHL,
-
-    /// XXPERMDI - The PPC XXPERMDI instruction
-    ///
-    XXPERMDI,
-    XXPERM,
-
-    /// The CMPB instruction (takes two operands of i32 or i64).
-    CMPB,
-
-    /// Hi/Lo - These represent the high and low 16-bit parts of a global
-    /// address respectively.  These nodes have two operands, the first of
-    /// which must be a TargetGlobalAddress, and the second of which must be a
-    /// Constant.  Selected naively, these turn into 'lis G+C' and 'li G+C',
-    /// though these are usually folded into other nodes.
-    Hi,
-    Lo,
-
-    /// The following two target-specific nodes are used for calls through
-    /// function pointers in the 64-bit SVR4 ABI.
-
-    /// OPRC, CHAIN = DYNALLOC(CHAIN, NEGSIZE, FRAME_INDEX)
-    /// This instruction is lowered in PPCRegisterInfo::eliminateFrameIndex to
-    /// compute an allocation on the stack.
-    DYNALLOC,
-
-    /// This instruction is lowered in PPCRegisterInfo::eliminateFrameIndex to
-    /// compute an offset from native SP to the address  of the most recent
-    /// dynamic alloca.
-    DYNAREAOFFSET,
-
-    /// To avoid stack clash, allocation is performed by block and each block is
-    /// probed.
-    PROBED_ALLOCA,
-
-    /// The result of the mflr at function entry, used for PIC code.
-    GlobalBaseReg,
-
-    /// These nodes represent PPC shifts.
-    ///
-    /// For scalar types, only the last `n + 1` bits of the shift amounts
-    /// are used, where n is log2(sizeof(element) * 8). See sld/slw, etc.
-    /// for exact behaviors.
-    ///
-    /// For vector types, only the last n bits are used. See vsld.
-    SRL,
-    SRA,
-    SHL,
-
-    /// FNMSUB - Negated multiply-subtract instruction.
-    FNMSUB,
-
-    /// EXTSWSLI = The PPC extswsli instruction, which does an extend-sign
-    /// word and shift left immediate.
-    EXTSWSLI,
-
-    /// The combination of sra[wd]i and addze used to implemented signed
-    /// integer division by a power of 2. The first operand is the dividend,
-    /// and the second is the constant shift amount (representing the
-    /// divisor).
-    SRA_ADDZE,
-
-    /// CALL - A direct function call.
-    /// CALL_NOP is a call with the special NOP which follows 64-bit
-    /// CALL_NOTOC the caller does not use the TOC.
-    /// SVR4 calls and 32-bit/64-bit AIX calls.
-    CALL,
-    CALL_NOP,
-    CALL_NOTOC,
-
-    /// CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a
-    /// MTCTR instruction.
-    MTCTR,
-
-    /// CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a
-    /// BCTRL instruction.
-    BCTRL,
-
-    /// CHAIN,FLAG = BCTRL(CHAIN, ADDR, INFLAG) - The combination of a bctrl
-    /// instruction and the TOC reload required on 64-bit ELF, 32-bit AIX
-    /// and 64-bit AIX.
-    BCTRL_LOAD_TOC,
-
-    /// The variants that implicitly define rounding mode for calls with
-    /// strictfp semantics.
-    CALL_RM,
-    CALL_NOP_RM,
-    CALL_NOTOC_RM,
-    BCTRL_RM,
-    BCTRL_LOAD_TOC_RM,
-
-    /// Return with a glue operand, matched by 'blr'
-    RET_GLUE,
-
-    /// R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
-    /// This copies the bits corresponding to the specified CRREG into the
-    /// resultant GPR.  Bits corresponding to other CR regs are undefined.
-    MFOCRF,
-
-    /// Direct move from a VSX register to a GPR
-    MFVSR,
-
-    /// Direct move from a GPR to a VSX register (algebraic)
-    MTVSRA,
-
-    /// Direct move from a GPR to a VSX register (zero)
-    MTVSRZ,
-
-    /// Direct move of 2 consecutive GPR to a VSX register.
-    BUILD_FP128,
-
-    /// BUILD_SPE64 and EXTRACT_SPE are analogous to BUILD_PAIR and
-    /// EXTRACT_ELEMENT but take f64 arguments instead of i64, as i64 is
-    /// unsupported for this target.
-    /// Merge 2 GPRs to a single SPE register.
-    BUILD_SPE64,
-
-    /// Extract SPE register component, second argument is high or low.
-    EXTRACT_SPE,
-
-    /// Extract a subvector from signed integer vector and convert to FP.
-    /// It is primarily used to convert a (widened) illegal integer vector
-    /// type to a legal floating point vector type.
-    /// For example v2i32 -> widened to v4i32 -> v2f64
-    SINT_VEC_TO_FP,
-
-    /// Extract a subvector from unsigned integer vector and convert to FP.
-    /// As with SINT_VEC_TO_FP, used for converting illegal types.
-    UINT_VEC_TO_FP,
-
-    /// PowerPC instructions that have SCALAR_TO_VECTOR semantics tend to
-    /// place the value into the least significant element of the most
-    /// significant doubleword in the vector. This is not element zero for
-    /// anything smaller than a doubleword on either endianness. This node has
-    /// the same semantics as SCALAR_TO_VECTOR except that the value remains in
-    /// the aforementioned location in the vector register.
-    SCALAR_TO_VECTOR_PERMUTED,
-
-    // FIXME: Remove these once the ANDI glue bug is fixed:
-    /// i1 = ANDI_rec_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the
-    /// eq or gt bit of CR0 after executing andi. x, 1. This is used to
-    /// implement truncation of i32 or i64 to i1.
-    ANDI_rec_1_EQ_BIT,
-    ANDI_rec_1_GT_BIT,
-
-    // READ_TIME_BASE - A read of the 64-bit time-base register on a 32-bit
-    // target (returns (Lo, Hi)). It takes a chain operand.
-    READ_TIME_BASE,
-
-    // EH_SJLJ_SETJMP - SjLj exception handling setjmp.
-    EH_SJLJ_SETJMP,
-
-    // EH_SJLJ_LONGJMP - SjLj exception handling longjmp.
-    EH_SJLJ_LONGJMP,
-
-    /// RESVEC = VCMP(LHS, RHS, OPC) - Represents one of the altivec VCMP*
-    /// instructions.  For lack of better number, we use the opcode number
-    /// encoding for the OPC field to identify the compare.  For example, 838
-    /// is VCMPGTSH.
-    VCMP,
-
-    /// RESVEC, OUTFLAG = VCMP_rec(LHS, RHS, OPC) - Represents one of the
-    /// altivec VCMP*_rec instructions.  For lack of better number, we use the
-    /// opcode number encoding for the OPC field to identify the compare.  For
-    /// example, 838 is VCMPGTSH.
-    VCMP_rec,
-
-    /// CHAIN = COND_BRANCH CHAIN, CRRC, OPC, DESTBB [, INFLAG] - This
-    /// corresponds to the COND_BRANCH pseudo instruction.  CRRC is the
-    /// condition register to branch on, OPC is the branch opcode to use (e.g.
-    /// PPC::BLE), DESTBB is the destination block to branch to, and INFLAG is
-    /// an optional input flag argument.
-    COND_BRANCH,
-
-    /// CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based
-    /// loops.
-    BDNZ,
-    BDZ,
-
-    /// F8RC = FADDRTZ F8RC, F8RC - This is an FADD done with rounding
-    /// towards zero.  Used only as part of the long double-to-int
-    /// conversion sequence.
-    FADDRTZ,
-
-    /// F8RC = MFFS - This moves the FPSCR (not modeled) into the register.
-    MFFS,
-
-    /// TC_RETURN - A tail call return.
-    ///   operand #0 chain
-    ///   operand #1 callee (register or absolute)
-    ///   operand #2 stack adjustment
-    ///   operand #3 optional in flag
-    TC_RETURN,
-
-    /// ch, gl = CR6[UN]SET ch, inglue - Toggle CR bit 6 for SVR4 vararg calls
-    CR6SET,
-    CR6UNSET,
-
-    /// GPRC = address of _GLOBAL_OFFSET_TABLE_. Used by initial-exec TLS
-    /// for non-position independent code on PPC32.
-    PPC32_GOT,
-
-    /// GPRC = address of _GLOBAL_OFFSET_TABLE_. Used by general dynamic and
-    /// local dynamic TLS and position indendepent code on PPC32.
-    PPC32_PICGOT,
-
-    /// G8RC = ADDIS_GOT_TPREL_HA %x2, Symbol - Used by the initial-exec
-    /// TLS model, produces an ADDIS8 instruction that adds the GOT
-    /// base to sym\@got\@tprel\@ha.
-    ADDIS_GOT_TPREL_HA,
-
-    /// G8RC = LD_GOT_TPREL_L Symbol, G8RReg - Used by the initial-exec
-    /// TLS model, produces a LD instruction with base register G8RReg
-    /// and offset sym\@got\@tprel\@l.  This completes the addition that
-    /// finds the offset of "sym" relative to the thread pointer.
-    LD_GOT_TPREL_L,
-
-    /// G8RC = ADD_TLS G8RReg, Symbol - Can be used by the initial-exec
-    /// and local-exec TLS models, produces an ADD instruction that adds
-    /// the contents of G8RReg to the thread pointer.  Symbol contains a
-    /// relocation sym\@tls which is to be replaced by the thread pointer
-    /// and identifies to the linker that the instruction is part of a
-    /// TLS sequence.
-    ADD_TLS,
-
-    /// G8RC = ADDIS_TLSGD_HA %x2, Symbol - For the general-dynamic TLS
-    /// model, produces an ADDIS8 instruction that adds the GOT base
-    /// register to sym\@got\@tlsgd\@ha.
-    ADDIS_TLSGD_HA,
-
-    /// %x3 = ADDI_TLSGD_L G8RReg, Symbol - For the general-dynamic TLS
-    /// model, produces an ADDI8 instruction that adds G8RReg to
-    /// sym\@got\@tlsgd\@l and stores the result in X3.  Hidden by
-    /// ADDIS_TLSGD_L_ADDR until after register assignment.
-    ADDI_TLSGD_L,
-
-    /// %x3 = GET_TLS_ADDR %x3, Symbol - For the general-dynamic TLS
-    /// model, produces a call to __tls_get_addr(sym\@tlsgd).  Hidden by
-    /// ADDIS_TLSGD_L_ADDR until after register assignment.
-    GET_TLS_ADDR,
-
-    /// %x3 = GET_TPOINTER - Used for the local- and initial-exec TLS model on
-    /// 32-bit AIX, produces a call to .__get_tpointer to retrieve the thread
-    /// pointer. At the end of the call, the thread pointer is found in R3.
-    GET_TPOINTER,
-
-    /// G8RC = ADDI_TLSGD_L_ADDR G8RReg, Symbol, Symbol - Op that
-    /// combines ADDI_TLSGD_L and GET_TLS_ADDR until expansion following
-    /// register assignment.
-    ADDI_TLSGD_L_ADDR,
-
-    /// GPRC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY
-    /// G8RC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY
-    /// Op that combines two register copies of TOC entries
-    /// (region handle into R3 and variable offset into R4) followed by a
-    /// GET_TLS_ADDR node which will be expanded to a call to .__tls_get_addr.
-    /// This node is used in 64-bit mode as well (in which case the result is
-    /// G8RC and inputs are X3/X4).
-    TLSGD_AIX,
-
-    /// %x3 = GET_TLS_MOD_AIX _$TLSML - For the AIX local-dynamic TLS model,
-    /// produces a call to .__tls_get_mod(_$TLSML\@ml).
-    GET_TLS_MOD_AIX,
-
-    /// [GP|G8]RC = TLSLD_AIX, TOC_ENTRY(module handle)
-    /// Op that requires a single input of the module handle TOC entry in R3,
-    /// and generates a GET_TLS_MOD_AIX node which will be expanded into a call
-    /// to .__tls_get_mod. This node is used in both 32-bit and 64-bit modes.
-    /// The only difference is the register class.
-    TLSLD_AIX,
-
-    /// G8RC = ADDIS_TLSLD_HA %x2, Symbol - For the local-dynamic TLS
-    /// model, produces an ADDIS8 instruction that adds the GOT base
-    /// register to sym\@got\@tlsld\@ha.
-    ADDIS_TLSLD_HA,
-
-    /// %x3 = ADDI_TLSLD_L G8RReg, Symbol - For the local-dynamic TLS
-    /// model, produces an ADDI8 instruction that adds G8RReg to
-    /// sym\@got\@tlsld\@l and stores the result in X3.  Hidden by
-    /// ADDIS_TLSLD_L_ADDR until after register assignment.
-    ADDI_TLSLD_L,
-
-    /// %x3 = GET_TLSLD_ADDR %x3, Symbol - For the local-dynamic TLS
-    /// model, produces a call to __tls_get_addr(sym\@tlsld).  Hidden by
-    /// ADDIS_TLSLD_L_ADDR until after register assignment.
-    GET_TLSLD_ADDR,
-
-    /// G8RC = ADDI_TLSLD_L_ADDR G8RReg, Symbol, Symbol - Op that
-    /// combines ADDI_TLSLD_L and GET_TLSLD_ADDR until expansion
-    /// following register assignment.
-    ADDI_TLSLD_L_ADDR,
-
-    /// G8RC = ADDIS_DTPREL_HA %x3, Symbol - For the local-dynamic TLS
-    /// model, produces an ADDIS8 instruction that adds X3 to
-    /// sym\@dtprel\@ha.
-    ADDIS_DTPREL_HA,
-
-    /// G8RC = ADDI_DTPREL_L G8RReg, Symbol - For the local-dynamic TLS
-    /// model, produces an ADDI8 instruction that adds G8RReg to
-    /// sym\@got\@dtprel\@l.
-    ADDI_DTPREL_L,
-
-    /// G8RC = PADDI_DTPREL %x3, Symbol - For the pc-rel based local-dynamic TLS
-    /// model, produces a PADDI8 instruction that adds X3 to sym\@dtprel.
-    PADDI_DTPREL,
-
-    /// VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded
-    /// during instruction selection to optimize a BUILD_VECTOR into
-    /// operations on splats.  This is necessary to avoid losing these
-    /// optimizations due to constant folding.
-    VADD_SPLAT,
-
-    /// CHAIN = SC CHAIN, Imm128 - System call.  The 7-bit unsigned
-    /// operand identifies the operating system entry point.
-    SC,
-
-    /// CHAIN = CLRBHRB CHAIN - Clear branch history rolling buffer.
-    CLRBHRB,
-
-    /// GPRC, CHAIN = MFBHRBE CHAIN, Entry, Dummy - Move from branch
-    /// history rolling buffer entry.
-    MFBHRBE,
-
-    /// CHAIN = RFEBB CHAIN, State - Return from event-based branch.
-    RFEBB,
-
-    /// VSRC, CHAIN = XXSWAPD CHAIN, VSRC - Occurs only for little
-    /// endian.  Maps to an xxswapd instruction that corrects an lxvd2x
-    /// or stxvd2x instruction.  The chain is necessary because the
-    /// sequence replaces a load and needs to provide the same number
-    /// of outputs.
-    XXSWAPD,
-
-    /// An SDNode for swaps that are not associated with any loads/stores
-    /// and thereby have no chain.
-    SWAP_NO_CHAIN,
-
-    /// FP_EXTEND_HALF(VECTOR, IDX) - Custom extend upper (IDX=0) half or
-    /// lower (IDX=1) half of v4f32 to v2f64.
-    FP_EXTEND_HALF,
-
-    /// MAT_PCREL_ADDR = Materialize a PC Relative address. This can be done
-    /// either through an add like PADDI or through a PC Relative load like
-    /// PLD.
-    MAT_PCREL_ADDR,
-
-    /// TLS_DYNAMIC_MAT_PCREL_ADDR = Materialize a PC Relative address for
-    /// TLS global address when using dynamic access models. This can be done
-    /// through an add like PADDI.
-    TLS_DYNAMIC_MAT_PCREL_ADDR,
-
-    /// TLS_LOCAL_EXEC_MAT_ADDR = Materialize an address for TLS global address
-    /// when using local exec access models, and when prefixed instructions are
-    /// available. This is used with ADD_TLS to produce an add like PADDI.
-    TLS_LOCAL_EXEC_MAT_ADDR,
-
-    /// ACC_BUILD = Build an accumulator register from 4 VSX registers.
-    ACC_BUILD,
-
-    /// PAIR_BUILD = Build a vector pair register from 2 VSX registers.
-    PAIR_BUILD,
-
-    /// EXTRACT_VSX_REG = Extract one of the underlying vsx registers of
-    /// an accumulator or pair register. This node is needed because
-    /// EXTRACT_SUBVECTOR expects the input and output vectors to have the same
-    /// element type.
-    EXTRACT_VSX_REG,
-
-    /// XXMFACC = This corresponds to the xxmfacc instruction.
-    XXMFACC,
-
-    // Constrained conversion from floating point to int
-    STRICT_FCTIDZ,
-    STRICT_FCTIWZ,
-    STRICT_FCTIDUZ,
-    STRICT_FCTIWUZ,
-
-    /// Constrained integer-to-floating-point conversion instructions.
-    STRICT_FCFID,
-    STRICT_FCFIDU,
-    STRICT_FCFIDS,
-    STRICT_FCFIDUS,
-
-    /// Constrained floating point add in round-to-zero mode.
-    STRICT_FADDRTZ,
-
-    /// SETBC - The ISA 3.1 (P10) SETBC instruction.
-    SETBC,
-
-    /// SETBCR - The ISA 3.1 (P10) SETBCR instruction.
-    SETBCR,
-
-    // NOTE: The nodes below may require PC-Rel specific patterns if the
-    // address could be PC-Relative. When adding new nodes below, consider
-    // whether or not the address can be PC-Relative and add the corresponding
-    // PC-relative patterns and tests.
-
-    /// CHAIN = STBRX CHAIN, GPRC, Ptr, Type - This is a
-    /// byte-swapping store instruction.  It byte-swaps the low "Type" bits of
-    /// the GPRC input, then stores it through Ptr.  Type can be either i16 or
-    /// i32.
-    FIRST_MEMORY_OPCODE,
-    STBRX = FIRST_MEMORY_OPCODE,
-
-    /// GPRC, CHAIN = LBRX CHAIN, Ptr, Type - This is a
-    /// byte-swapping load instruction.  It loads "Type" bits, byte swaps it,
-    /// then puts it in the bottom bits of the GPRC.  TYPE can be either i16
-    /// or i32.
-    LBRX,
-
-    /// STFIWX - The STFIWX instruction.  The first operand is an input token
-    /// chain, then an f64 value to store, then an address to store it to.
-    STFIWX,
-
-    /// GPRC, CHAIN = LFIWAX CHAIN, Ptr - This is a floating-point
-    /// load which sign-extends from a 32-bit integer value into the
-    /// destination 64-bit register.
-    LFIWAX,
-
-    /// GPRC, CHAIN = LFIWZX CHAIN, Ptr - This is a floating-point
-    /// load which zero-extends from a 32-bit integer value into the
-    /// destination 64-bit register.
-    LFIWZX,
-
-    /// GPRC, CHAIN = LXSIZX, CHAIN, Ptr, ByteWidth - This is a load of an
-    /// integer smaller than 64 bits into a VSR. The integer is zero-extended.
-    /// This can be used for converting loaded integers to floating point.
-    LXSIZX,
-
-    /// STXSIX - The STXSI[bh]X instruction. The first operand is an input
-    /// chain, then an f64 value to store, then an address to store it to,
-    /// followed by a byte-width for the store.
-    STXSIX,
-
-    /// VSRC, CHAIN = LXVD2X_LE CHAIN, Ptr - Occurs only for little endian.
-    /// Maps directly to an lxvd2x instruction that will be followed by
-    /// an xxswapd.
-    LXVD2X,
-
-    /// LXVRZX - Load VSX Vector Rightmost and Zero Extend
-    /// This node represents v1i128 BUILD_VECTOR of a zero extending load
-    /// instruction from <byte, halfword, word, or doubleword> to i128.
-    /// Allows utilization of the Load VSX Vector Rightmost Instructions.
-    LXVRZX,
-
-    /// VSRC, CHAIN = LOAD_VEC_BE CHAIN, Ptr - Occurs only for little endian.
-    /// Maps directly to one of lxvd2x/lxvw4x/lxvh8x/lxvb16x depending on
-    /// the vector type to load vector in big-endian element order.
-    LOAD_VEC_BE,
-
-    /// VSRC, CHAIN = LD_VSX_LH CHAIN, Ptr - This is a floating-point load of a
-    /// v2f32 value into the lower half of a VSR register.
-    LD_VSX_LH,
-
-    /// VSRC, CHAIN = LD_SPLAT, CHAIN, Ptr - a splatting load memory
-    /// instructions such as LXVDSX, LXVWSX.
-    LD_SPLAT,
-
-    /// VSRC, CHAIN = ZEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory
-    /// that zero-extends.
-    ZEXT_LD_SPLAT,
-
-    /// VSRC, CHAIN = SEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory
-    /// that sign-extends.
-    SEXT_LD_SPLAT,
-
-    /// CHAIN = STXVD2X CHAIN, VSRC, Ptr - Occurs only for little endian.
-    /// Maps directly to an stxvd2x instruction that will be preceded by
-    /// an xxswapd.
-    STXVD2X,
-
-    /// CHAIN = STORE_VEC_BE CHAIN, VSRC, Ptr - Occurs only for little endian.
-    /// Maps directly to one of stxvd2x/stxvw4x/stxvh8x/stxvb16x depending on
-    /// the vector type to store vector in big-endian element order.
-    STORE_VEC_BE,
-
-    /// Store scalar integers from VSR.
-    ST_VSR_SCAL_INT,
-
-    /// ATOMIC_CMP_SWAP - the exact same as the target-independent nodes
-    /// except they ensure that the compare input is zero-extended for
-    /// sub-word versions because the atomic loads zero-extend.
-    ATOMIC_CMP_SWAP_8,
-    ATOMIC_CMP_SWAP_16,
-
-    /// CHAIN,Glue = STORE_COND CHAIN, GPR, Ptr
-    /// The store conditional instruction ST[BHWD]ARX that produces a glue
-    /// result to attach it to a conditional branch.
-    STORE_COND,
-
-    /// GPRC = TOC_ENTRY GA, TOC
-    /// Loads the entry for GA from the TOC, where the TOC base is given by
-    /// the last operand.
-    TOC_ENTRY,
-    LAST_MEMORY_OPCODE = TOC_ENTRY,
-  };
-
-  } // end namespace PPCISD
-
   /// Define some predicates that are used for node matching.
   namespace PPC {
 
@@ -755,10 +178,6 @@ namespace llvm {
     explicit PPCTargetLowering(const PPCTargetMachine &TM,
                                const PPCSubtarget &STI);
 
-    /// getTargetNodeName() - This method returns the name of a target specific
-    /// DAG node.
-    const char *getTargetNodeName(unsigned Opcode) const override;
-
     bool isSelectSupported(SelectSupportKind Kind) const override {
       // PowerPC does not support scalar condition selects on vectors.
       return (Kind != SelectSupportKind::ScalarCondVectorVal);
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index be90a5c562c570..fd26baf7f869bc 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -142,14 +142,16 @@ def PPCfctiwz : SDNode<"PPCISD::FCTIWZ", SDTFPUnaryOp, []>;
 def PPCfctiduz: SDNode<"PPCISD::FCTIDUZ",SDTFPUnaryOp, []>;
 def PPCfctiwuz: SDNode<"PPCISD::FCTIWUZ",SDTFPUnaryOp, []>;
 
-def PPCstrict_fcfid : SDNode<"PPCISD::STRICT_FCFID",
-                             SDTFPUnaryOp, [SDNPHasChain]>;
-def PPCstrict_fcfidu : SDNode<"PPCISD::STRICT_FCFIDU",
-                              SDTFPUnaryOp, [SDNPHasChain]>;
-def PPCstrict_fcfids : SDNode<"PPCISD::STRICT_FCFIDS",
-                             SDTFPRoundOp, [SDNPHasChain]>;
-def PPCstrict_fcfidus : SDNode<"PPCISD::STRICT_FCFIDUS",
-                              SDTFPRoundOp, [SDNPHasChain]>;
+let IsStrictFP = true in {
+  def PPCstrict_fcfid  : SDNode<"PPCISD::STRICT_FCFID",
+                                SDTFPUnaryOp, [SDNPHasChain]>;
+  def PPCstrict_fcfidu : SDNode<"PPCISD::STRICT_FCFIDU",
+                                SDTFPUnaryOp, [SDNPHasChain]>;
+  def PPCstrict_fcfids : SDNode<"PPCISD::STRICT_FCFIDS",
+                                SDTFPRoundOp, [SDNPHasChain]>;
+  def PPCstrict_fcfidus : SDNode<"PPCISD::STRICT_FCFIDUS",
+                                 SDTFPRoundOp, [SDNPHasChain]>;
+}
 
 def PPCany_fcfid : PatFrags<(ops node:$op),
                              [(PPCfcfid node:$op),
@@ -186,6 +188,8 @@ def PPCmffs   : SDNode<"PPCISD::MFFS",
 
 // Perform FADD in round-to-zero mode.
 def PPCfaddrtz: SDNode<"PPCISD::FADDRTZ", SDTFPBinOp, []>;
+
+let IsStrictFP = true in
 def PPCstrict_faddrtz: SDNode<"PPCISD::STRICT_FADDRTZ", SDTFPBinOp,
                               [SDNPHasChain]>;
 
@@ -251,14 +255,16 @@ def PPCfnmsub     : SDNode<"PPCISD::FNMSUB"    , SDTFPTernaryOp>;
 
 def PPCextswsli : SDNode<"PPCISD::EXTSWSLI" , SDT_PPCextswsli>;
 
-def PPCstrict_fctidz : SDNode<"PPCISD::STRICT_FCTIDZ",
-                              SDTFPUnaryOp, [SDNPHasChain]>;
-def PPCstrict_fctiwz : SDNode<"PPCISD::STRICT_FCTIWZ",
-                              SDTFPUnaryOp, [SDNPHasChain]>;
-def PPCstrict_fctiduz : SDNode<"PPCISD::STRICT_FCTIDUZ",
-                               SDTFPUnaryOp, [SDNPHasChain]>;
-def PPCstrict_fctiwuz : SDNode<"PPCISD::STRICT_FCTIWUZ",
+let IsStrictFP = true in {
+  def PPCstrict_fctidz : SDNode<"PPCISD::STRICT_FCTIDZ",
+                                SDTFPUnaryOp, [SDNPHasChain]>;
+  def PPCstrict_fctiwz : SDNode<"PPCISD::STRICT_FCTIWZ",
                                 SDTFPUnaryOp, [SDNPHasChain]>;
+  def PPCstrict_fctiduz : SDNode<"PPCISD::STRICT_FCTIDUZ",
+                                 SDTFPUnaryOp, [SDNPHasChain]>;
+  def PPCstrict_fctiwuz : SDNode<"PPCISD::STRICT_FCTIWUZ",
+                                 SDTFPUnaryOp, [SDNPHasChain]>;
+}
 
 def PPCany_fctidz : PatFrags<(ops node:$op),
                              [(PPCstrict_fctidz node:$op),
diff --git a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
index 2ef6b07b9f7bf9..3e5ba1d1b356c9 100644
--- a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
@@ -7,33 +7,63 @@
 //===----------------------------------------------------------------------===//
 
 #include "PPCSelectionDAGInfo.h"
-#include "PPCISelLowering.h"
+
+#define GET_SDNODE_DESC
+#include "PPCGenSDNodeInfo.inc"
 
 using namespace llvm;
 
+PPCSelectionDAGInfo::PPCSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(PPCGenSDNodeInfo) {}
+
 PPCSelectionDAGInfo::~PPCSelectionDAGInfo() = default;
 
-bool PPCSelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
-  if (Opcode >= PPCISD::FIRST_MEMORY_OPCODE &&
-      Opcode <= PPCISD::LAST_MEMORY_OPCODE)
-    return true;
-  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+const char *PPCSelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
+  switch (static_cast<PPCISD::NodeType>(Opcode)) {
+  case PPCISD::GlobalBaseReg:
+    return "PPCISD::GlobalBaseReg";
+  case PPCISD::SRA_ADDZE:
+    return "PPCISD::SRA_ADDZE";
+  case PPCISD::READ_TIME_BASE:
+    return "PPCISD::READ_TIME_BASE";
+  case PPCISD::MFOCRF:
+    return "PPCISD::MFOCRF";
+  case PPCISD::ANDI_rec_1_EQ_BIT:
+    return "PPCISD::ANDI_rec_1_EQ_BIT";
+  case PPCISD::ANDI_rec_1_GT_BIT:
+    return "PPCISD::ANDI_rec_1_GT_BIT";
+  case PPCISD::BDNZ:
+    return "PPCISD::BDNZ";
+  case PPCISD::BDZ:
+    return "PPCISD::BDZ";
+  case PPCISD::PPC32_PICGOT:
+    return "PPCISD::PPC32_PICGOT";
+  case PPCISD::VADD_SPLAT:
+    return "PPCISD::VADD_SPLAT";
+  }
+
+  return SelectionDAGGenTargetInfo::getTargetNodeName(Opcode);
 }
 
-bool PPCSelectionDAGInfo::isTargetStrictFPOpcode(unsigned Opcode) const {
-  switch (static_cast<PPCISD::NodeType>(Opcode)) {
+void PPCSelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
+                                           const SDNode *N) const {
+  switch (N->getOpcode()) {
   default:
     break;
-  case PPCISD::STRICT_FCTIDZ:
-  case PPCISD::STRICT_FCTIWZ:
-  case PPCISD::STRICT_FCTIDUZ:
-  case PPCISD::STRICT_FCTIWUZ:
-  case PPCISD::STRICT_FCFID:
-  case PPCISD::STRICT_FCFIDU:
-  case PPCISD::STRICT_FCFIDS:
-  case PPCISD::STRICT_FCFIDUS:
-  case PPCISD::STRICT_FADDRTZ:
-    return true;
+  case PPCISD::DYNAREAOFFSET:
+    // invalid number of results; expected 2, got 1
+  case PPCISD::TOC_ENTRY:
+    // invalid number of results; expected 1, got 2
+  case PPCISD::STORE_COND:
+    // invalid number of results; expected 2, got 3
+  case PPCISD::LD_SPLAT:
+  case PPCISD::SEXT_LD_SPLAT:
+  case PPCISD::ZEXT_LD_SPLAT:
+    // invalid number of operands; expected 2, got 3
+  case PPCISD::ST_VSR_SCAL_INT:
+    // invalid number of operands; expected 4, got 5
+    return;
   }
-  return SelectionDAGTargetInfo::isTargetStrictFPOpcode(Opcode);
+
+  SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
 }
diff --git a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h
index 6d37c50fa6c1be..7138e831302c9a 100644
--- a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h
+++ b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h
@@ -11,15 +11,66 @@
 
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 
+#define GET_SDNODE_ENUM
+#include "PPCGenSDNodeInfo.inc"
+
 namespace llvm {
+namespace PPCISD {
+
+enum NodeType : unsigned {
+  /// The result of the mflr at function entry, used for PIC code.
+  GlobalBaseReg = GENERATED_OPCODE_END,
+
+  /// The combination of sra[wd]i and addze used to implemented signed
+  /// integer division by a power of 2. The first operand is the dividend,
+  /// and the second is the constant shift amount (representing the
+  /// divisor).
+  SRA_ADDZE,
+
+  /// R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
+  /// This copies the bits corresponding to the specified CRREG into the
+  /// resultant GPR.  Bits corresponding to other CR regs are undefined.
+  MFOCRF,
+
+  // FIXME: Remove these once the ANDI glue bug is fixed:
+  /// i1 = ANDI_rec_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the
+  /// eq or gt bit of CR0 after executing andi. x, 1. This is used to
+  /// implement truncation of i32 or i64 to i1.
+  ANDI_rec_1_EQ_BIT,
+  ANDI_rec_1_GT_BIT,
+
+  // READ_TIME_BASE - A read of the 64-bit time-base register on a 32-bit
+  // target (returns (Lo, Hi)). It takes a chain operand.
+  READ_TIME_BASE,
 
-class PPCSelectionDAGInfo : public SelectionDAGTargetInfo {
+  /// CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based
+  /// loops.
+  BDNZ,
+  BDZ,
+
+  /// GPRC = address of _GLOBAL_OFFSET_TABLE_. Used by general dynamic and
+  /// local dynamic TLS and position indendepent code on PPC32.
+  PPC32_PICGOT,
+
+  /// VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded
+  /// during instruction selection to optimize a BUILD_VECTOR into
+  /// operations on splats.  This is necessary to avoid losing these
+  /// optimizations due to constant folding.
+  VADD_SPLAT,
+};
+
+} // namespace PPCISD
+
+class PPCSelectionDAGInfo : public SelectionDAGGenTargetInfo {
 public:
+  PPCSelectionDAGInfo();
+
   ~PPCSelectionDAGInfo() override;
 
-  bool isTargetMemoryOpcode(unsigned Opcode) const override;
+  const char *getTargetNodeName(unsigned Opcode) const override;
 
-  bool isTargetStrictFPOpcode(unsigned Opcode) const override;
+  void verifyTargetNode(const SelectionDAG &DAG,
+                        const SDNode *N) const override;
 };
 
 } // namespace llvm

>From 9db023c02918785df89645776d034afcfa23df23 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 01:02:20 +0300
Subject: [PATCH 19/27] RISCV

---
 llvm/lib/Target/RISCV/CMakeLists.txt          |   1 +
 llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h     |   1 +
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   | 338 +------------
 llvm/lib/Target/RISCV/RISCVISelLowering.h     | 478 ------------------
 llvm/lib/Target/RISCV/RISCVInstrInfoF.td      |  14 +-
 .../Target/RISCV/RISCVInstrInfoVVLPatterns.td | 405 +++++++++------
 .../Target/RISCV/RISCVSelectionDAGInfo.cpp    |  36 +-
 llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h |  61 ++-
 8 files changed, 343 insertions(+), 991 deletions(-)

diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt
index 44661647a86310..63500b9eb54534 100644
--- a/llvm/lib/Target/RISCV/CMakeLists.txt
+++ b/llvm/lib/Target/RISCV/CMakeLists.txt
@@ -13,6 +13,7 @@ tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM RISCVGenMCPseudoLowering.inc -gen-pseudo-lowering)
 tablegen(LLVM RISCVGenRegisterBank.inc -gen-register-bank)
 tablegen(LLVM RISCVGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM RISCVGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM RISCVGenSearchableTables.inc -gen-searchable-tables)
 tablegen(LLVM RISCVGenSubtargetInfo.inc -gen-subtarget)
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
index 2e738d8d25a6dc..486f7d7bc5843d 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
@@ -14,6 +14,7 @@
 #define LLVM_LIB_TARGET_RISCV_RISCVISELDAGTODAG_H
 
 #include "RISCV.h"
+#include "RISCVSelectionDAGInfo.h"
 #include "RISCVTargetMachine.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
 #include "llvm/Support/KnownBits.h"
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 3b38737a4e48a5..56a711cd98e52a 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -6390,49 +6390,6 @@ static unsigned getRISCVVLOp(SDValue Op) {
 #undef VP_CASE
 }
 
-/// Return true if a RISC-V target specified op has a passthru operand.
-static bool hasPassthruOp(unsigned Opcode) {
-  assert(Opcode > RISCVISD::FIRST_NUMBER &&
-         Opcode <= RISCVISD::LAST_STRICTFP_OPCODE &&
-         "not a RISC-V target specific op");
-  static_assert(
-      RISCVISD::LAST_VL_VECTOR_OP - RISCVISD::FIRST_VL_VECTOR_OP == 127 &&
-      RISCVISD::LAST_STRICTFP_OPCODE - RISCVISD::FIRST_STRICTFP_OPCODE == 21 &&
-      "adding target specific op should update this function");
-  if (Opcode >= RISCVISD::ADD_VL && Opcode <= RISCVISD::VFMAX_VL)
-    return true;
-  if (Opcode == RISCVISD::FCOPYSIGN_VL)
-    return true;
-  if (Opcode >= RISCVISD::VWMUL_VL && Opcode <= RISCVISD::VFWSUB_W_VL)
-    return true;
-  if (Opcode == RISCVISD::SETCC_VL)
-    return true;
-  if (Opcode >= RISCVISD::STRICT_FADD_VL && Opcode <= RISCVISD::STRICT_FDIV_VL)
-    return true;
-  if (Opcode == RISCVISD::VMERGE_VL)
-    return true;
-  return false;
-}
-
-/// Return true if a RISC-V target specified op has a mask operand.
-static bool hasMaskOp(unsigned Opcode) {
-  assert(Opcode > RISCVISD::FIRST_NUMBER &&
-         Opcode <= RISCVISD::LAST_STRICTFP_OPCODE &&
-         "not a RISC-V target specific op");
-  static_assert(
-      RISCVISD::LAST_VL_VECTOR_OP - RISCVISD::FIRST_VL_VECTOR_OP == 127 &&
-      RISCVISD::LAST_STRICTFP_OPCODE - RISCVISD::FIRST_STRICTFP_OPCODE == 21 &&
-      "adding target specific op should update this function");
-  if (Opcode >= RISCVISD::TRUNCATE_VECTOR_VL && Opcode <= RISCVISD::SETCC_VL)
-    return true;
-  if (Opcode >= RISCVISD::VRGATHER_VX_VL && Opcode <= RISCVISD::VFIRST_VL)
-    return true;
-  if (Opcode >= RISCVISD::STRICT_FADD_VL &&
-      Opcode <= RISCVISD::STRICT_VFROUND_NOEXCEPT_VL)
-    return true;
-  return false;
-}
-
 static bool isPromotedOpNeedingSplit(SDValue Op,
                                      const RISCVSubtarget &Subtarget) {
   if (Op.getValueType() == MVT::nxv32f16 &&
@@ -11717,9 +11674,12 @@ SDValue RISCVTargetLowering::lowerFixedLengthVectorSelectToRVV(
 
 SDValue RISCVTargetLowering::lowerToScalableOp(SDValue Op,
                                                SelectionDAG &DAG) const {
+  const auto &TSInfo =
+      static_cast<const RISCVSelectionDAGInfo &>(DAG.getSelectionDAGInfo());
+
   unsigned NewOpc = getRISCVVLOp(Op);
-  bool HasPassthruOp = hasPassthruOp(NewOpc);
-  bool HasMask = hasMaskOp(NewOpc);
+  bool HasPassthruOp = TSInfo.hasPassthruOp(NewOpc);
+  bool HasMask = TSInfo.hasMaskOp(NewOpc);
 
   MVT VT = Op.getSimpleValueType();
   MVT ContainerVT = getContainerForFixedLengthVector(VT);
@@ -11770,8 +11730,11 @@ SDValue RISCVTargetLowering::lowerToScalableOp(SDValue Op,
 // * Fixed-length vectors are converted to their scalable-vector container
 //   types.
 SDValue RISCVTargetLowering::lowerVPOp(SDValue Op, SelectionDAG &DAG) const {
+  const auto &TSInfo =
+      static_cast<const RISCVSelectionDAGInfo &>(DAG.getSelectionDAGInfo());
+
   unsigned RISCVISDOpc = getRISCVVLOp(Op);
-  bool HasPassthruOp = hasPassthruOp(RISCVISDOpc);
+  bool HasPassthruOp = TSInfo.hasPassthruOp(RISCVISDOpc);
 
   SDLoc DL(Op);
   MVT VT = Op.getSimpleValueType();
@@ -12670,7 +12633,7 @@ SDValue RISCVTargetLowering::lowerEH_DWARF_CFA(SDValue Op,
 
 // Returns the opcode of the target-specific SDNode that implements the 32-bit
 // form of the given Opcode.
-static RISCVISD::NodeType getRISCVWOpcode(unsigned Opcode) {
+static unsigned getRISCVWOpcode(unsigned Opcode) {
   switch (Opcode) {
   default:
     llvm_unreachable("Unexpected opcode");
@@ -12701,7 +12664,7 @@ static RISCVISD::NodeType getRISCVWOpcode(unsigned Opcode) {
 static SDValue customLegalizeToWOp(SDNode *N, SelectionDAG &DAG,
                                    unsigned ExtOpc = ISD::ANY_EXTEND) {
   SDLoc DL(N);
-  RISCVISD::NodeType WOpcode = getRISCVWOpcode(N->getOpcode());
+  unsigned WOpcode = getRISCVWOpcode(N->getOpcode());
   SDValue NewOp0 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(0));
   SDValue NewOp1 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(1));
   SDValue NewRes = DAG.getNode(WOpcode, DL, MVT::i64, NewOp0, NewOp1);
@@ -16924,15 +16887,9 @@ static SDValue combineToVWMACC(SDNode *N, SelectionDAG &DAG,
   if (AddMask != MulMask || AddVL != MulVL)
     return SDValue();
 
-  unsigned Opc = RISCVISD::VWMACC_VL + MulOp.getOpcode() - RISCVISD::VWMUL_VL;
-  static_assert(RISCVISD::VWMACC_VL + 1 == RISCVISD::VWMACCU_VL,
-                "Unexpected opcode after VWMACC_VL");
-  static_assert(RISCVISD::VWMACC_VL + 2 == RISCVISD::VWMACCSU_VL,
-                "Unexpected opcode after VWMACC_VL!");
-  static_assert(RISCVISD::VWMUL_VL + 1 == RISCVISD::VWMULU_VL,
-                "Unexpected opcode after VWMUL_VL!");
-  static_assert(RISCVISD::VWMUL_VL + 2 == RISCVISD::VWMULSU_VL,
-                "Unexpected opcode after VWMUL_VL!");
+  const auto &TSInfo =
+      static_cast<const RISCVSelectionDAGInfo &>(DAG.getSelectionDAGInfo());
+  unsigned Opc = TSInfo.getMAccOpcode(MulOp.getOpcode());
 
   SDLoc DL(N);
   EVT VT = N->getValueType(0);
@@ -20462,273 +20419,6 @@ bool RISCVTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const {
   return CI->isTailCall();
 }
 
-const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
-#define NODE_NAME_CASE(NODE)                                                   \
-  case RISCVISD::NODE:                                                         \
-    return "RISCVISD::" #NODE;
-  // clang-format off
-  switch ((RISCVISD::NodeType)Opcode) {
-  case RISCVISD::FIRST_NUMBER:
-    break;
-  NODE_NAME_CASE(RET_GLUE)
-  NODE_NAME_CASE(SRET_GLUE)
-  NODE_NAME_CASE(MRET_GLUE)
-  NODE_NAME_CASE(CALL)
-  NODE_NAME_CASE(TAIL)
-  NODE_NAME_CASE(SELECT_CC)
-  NODE_NAME_CASE(BR_CC)
-  NODE_NAME_CASE(BuildGPRPair)
-  NODE_NAME_CASE(SplitGPRPair)
-  NODE_NAME_CASE(BuildPairF64)
-  NODE_NAME_CASE(SplitF64)
-  NODE_NAME_CASE(ADD_LO)
-  NODE_NAME_CASE(HI)
-  NODE_NAME_CASE(LLA)
-  NODE_NAME_CASE(ADD_TPREL)
-  NODE_NAME_CASE(MULHSU)
-  NODE_NAME_CASE(SHL_ADD)
-  NODE_NAME_CASE(SLLW)
-  NODE_NAME_CASE(SRAW)
-  NODE_NAME_CASE(SRLW)
-  NODE_NAME_CASE(DIVW)
-  NODE_NAME_CASE(DIVUW)
-  NODE_NAME_CASE(REMUW)
-  NODE_NAME_CASE(ROLW)
-  NODE_NAME_CASE(RORW)
-  NODE_NAME_CASE(CLZW)
-  NODE_NAME_CASE(CTZW)
-  NODE_NAME_CASE(ABSW)
-  NODE_NAME_CASE(FMV_H_X)
-  NODE_NAME_CASE(FMV_X_ANYEXTH)
-  NODE_NAME_CASE(FMV_X_SIGNEXTH)
-  NODE_NAME_CASE(FMV_W_X_RV64)
-  NODE_NAME_CASE(FMV_X_ANYEXTW_RV64)
-  NODE_NAME_CASE(FCVT_X)
-  NODE_NAME_CASE(FCVT_XU)
-  NODE_NAME_CASE(FCVT_W_RV64)
-  NODE_NAME_CASE(FCVT_WU_RV64)
-  NODE_NAME_CASE(STRICT_FCVT_W_RV64)
-  NODE_NAME_CASE(STRICT_FCVT_WU_RV64)
-  NODE_NAME_CASE(FROUND)
-  NODE_NAME_CASE(FCLASS)
-  NODE_NAME_CASE(FSGNJX)
-  NODE_NAME_CASE(FMAX)
-  NODE_NAME_CASE(FMIN)
-  NODE_NAME_CASE(FLI)
-  NODE_NAME_CASE(READ_COUNTER_WIDE)
-  NODE_NAME_CASE(BREV8)
-  NODE_NAME_CASE(ORC_B)
-  NODE_NAME_CASE(ZIP)
-  NODE_NAME_CASE(UNZIP)
-  NODE_NAME_CASE(CLMUL)
-  NODE_NAME_CASE(CLMULH)
-  NODE_NAME_CASE(CLMULR)
-  NODE_NAME_CASE(MOPR)
-  NODE_NAME_CASE(MOPRR)
-  NODE_NAME_CASE(SHA256SIG0)
-  NODE_NAME_CASE(SHA256SIG1)
-  NODE_NAME_CASE(SHA256SUM0)
-  NODE_NAME_CASE(SHA256SUM1)
-  NODE_NAME_CASE(SM4KS)
-  NODE_NAME_CASE(SM4ED)
-  NODE_NAME_CASE(SM3P0)
-  NODE_NAME_CASE(SM3P1)
-  NODE_NAME_CASE(TH_LWD)
-  NODE_NAME_CASE(TH_LWUD)
-  NODE_NAME_CASE(TH_LDD)
-  NODE_NAME_CASE(TH_SWD)
-  NODE_NAME_CASE(TH_SDD)
-  NODE_NAME_CASE(VMV_V_V_VL)
-  NODE_NAME_CASE(VMV_V_X_VL)
-  NODE_NAME_CASE(VFMV_V_F_VL)
-  NODE_NAME_CASE(VMV_X_S)
-  NODE_NAME_CASE(VMV_S_X_VL)
-  NODE_NAME_CASE(VFMV_S_F_VL)
-  NODE_NAME_CASE(SPLAT_VECTOR_SPLIT_I64_VL)
-  NODE_NAME_CASE(READ_VLENB)
-  NODE_NAME_CASE(TRUNCATE_VECTOR_VL)
-  NODE_NAME_CASE(TRUNCATE_VECTOR_VL_SSAT)
-  NODE_NAME_CASE(TRUNCATE_VECTOR_VL_USAT)
-  NODE_NAME_CASE(VSLIDEUP_VL)
-  NODE_NAME_CASE(VSLIDE1UP_VL)
-  NODE_NAME_CASE(VSLIDEDOWN_VL)
-  NODE_NAME_CASE(VSLIDE1DOWN_VL)
-  NODE_NAME_CASE(VFSLIDE1UP_VL)
-  NODE_NAME_CASE(VFSLIDE1DOWN_VL)
-  NODE_NAME_CASE(VID_VL)
-  NODE_NAME_CASE(VFNCVT_ROD_VL)
-  NODE_NAME_CASE(VECREDUCE_ADD_VL)
-  NODE_NAME_CASE(VECREDUCE_UMAX_VL)
-  NODE_NAME_CASE(VECREDUCE_SMAX_VL)
-  NODE_NAME_CASE(VECREDUCE_UMIN_VL)
-  NODE_NAME_CASE(VECREDUCE_SMIN_VL)
-  NODE_NAME_CASE(VECREDUCE_AND_VL)
-  NODE_NAME_CASE(VECREDUCE_OR_VL)
-  NODE_NAME_CASE(VECREDUCE_XOR_VL)
-  NODE_NAME_CASE(VECREDUCE_FADD_VL)
-  NODE_NAME_CASE(VECREDUCE_SEQ_FADD_VL)
-  NODE_NAME_CASE(VECREDUCE_FMIN_VL)
-  NODE_NAME_CASE(VECREDUCE_FMAX_VL)
-  NODE_NAME_CASE(ADD_VL)
-  NODE_NAME_CASE(AND_VL)
-  NODE_NAME_CASE(MUL_VL)
-  NODE_NAME_CASE(OR_VL)
-  NODE_NAME_CASE(SDIV_VL)
-  NODE_NAME_CASE(SHL_VL)
-  NODE_NAME_CASE(SREM_VL)
-  NODE_NAME_CASE(SRA_VL)
-  NODE_NAME_CASE(SRL_VL)
-  NODE_NAME_CASE(ROTL_VL)
-  NODE_NAME_CASE(ROTR_VL)
-  NODE_NAME_CASE(SUB_VL)
-  NODE_NAME_CASE(UDIV_VL)
-  NODE_NAME_CASE(UREM_VL)
-  NODE_NAME_CASE(XOR_VL)
-  NODE_NAME_CASE(AVGFLOORS_VL)
-  NODE_NAME_CASE(AVGFLOORU_VL)
-  NODE_NAME_CASE(AVGCEILS_VL)
-  NODE_NAME_CASE(AVGCEILU_VL)
-  NODE_NAME_CASE(SADDSAT_VL)
-  NODE_NAME_CASE(UADDSAT_VL)
-  NODE_NAME_CASE(SSUBSAT_VL)
-  NODE_NAME_CASE(USUBSAT_VL)
-  NODE_NAME_CASE(FADD_VL)
-  NODE_NAME_CASE(FSUB_VL)
-  NODE_NAME_CASE(FMUL_VL)
-  NODE_NAME_CASE(FDIV_VL)
-  NODE_NAME_CASE(FNEG_VL)
-  NODE_NAME_CASE(FABS_VL)
-  NODE_NAME_CASE(FSQRT_VL)
-  NODE_NAME_CASE(FCLASS_VL)
-  NODE_NAME_CASE(VFMADD_VL)
-  NODE_NAME_CASE(VFNMADD_VL)
-  NODE_NAME_CASE(VFMSUB_VL)
-  NODE_NAME_CASE(VFNMSUB_VL)
-  NODE_NAME_CASE(VFWMADD_VL)
-  NODE_NAME_CASE(VFWNMADD_VL)
-  NODE_NAME_CASE(VFWMSUB_VL)
-  NODE_NAME_CASE(VFWNMSUB_VL)
-  NODE_NAME_CASE(FCOPYSIGN_VL)
-  NODE_NAME_CASE(SMIN_VL)
-  NODE_NAME_CASE(SMAX_VL)
-  NODE_NAME_CASE(UMIN_VL)
-  NODE_NAME_CASE(UMAX_VL)
-  NODE_NAME_CASE(BITREVERSE_VL)
-  NODE_NAME_CASE(BSWAP_VL)
-  NODE_NAME_CASE(CTLZ_VL)
-  NODE_NAME_CASE(CTTZ_VL)
-  NODE_NAME_CASE(CTPOP_VL)
-  NODE_NAME_CASE(VFMIN_VL)
-  NODE_NAME_CASE(VFMAX_VL)
-  NODE_NAME_CASE(MULHS_VL)
-  NODE_NAME_CASE(MULHU_VL)
-  NODE_NAME_CASE(VFCVT_RTZ_X_F_VL)
-  NODE_NAME_CASE(VFCVT_RTZ_XU_F_VL)
-  NODE_NAME_CASE(VFCVT_RM_X_F_VL)
-  NODE_NAME_CASE(VFCVT_RM_XU_F_VL)
-  NODE_NAME_CASE(VFROUND_NOEXCEPT_VL)
-  NODE_NAME_CASE(SINT_TO_FP_VL)
-  NODE_NAME_CASE(UINT_TO_FP_VL)
-  NODE_NAME_CASE(VFCVT_RM_F_XU_VL)
-  NODE_NAME_CASE(VFCVT_RM_F_X_VL)
-  NODE_NAME_CASE(FP_EXTEND_VL)
-  NODE_NAME_CASE(FP_ROUND_VL)
-  NODE_NAME_CASE(STRICT_FADD_VL)
-  NODE_NAME_CASE(STRICT_FSUB_VL)
-  NODE_NAME_CASE(STRICT_FMUL_VL)
-  NODE_NAME_CASE(STRICT_FDIV_VL)
-  NODE_NAME_CASE(STRICT_FSQRT_VL)
-  NODE_NAME_CASE(STRICT_VFMADD_VL)
-  NODE_NAME_CASE(STRICT_VFNMADD_VL)
-  NODE_NAME_CASE(STRICT_VFMSUB_VL)
-  NODE_NAME_CASE(STRICT_VFNMSUB_VL)
-  NODE_NAME_CASE(STRICT_FP_ROUND_VL)
-  NODE_NAME_CASE(STRICT_FP_EXTEND_VL)
-  NODE_NAME_CASE(STRICT_VFNCVT_ROD_VL)
-  NODE_NAME_CASE(STRICT_SINT_TO_FP_VL)
-  NODE_NAME_CASE(STRICT_UINT_TO_FP_VL)
-  NODE_NAME_CASE(STRICT_VFCVT_RM_X_F_VL)
-  NODE_NAME_CASE(STRICT_VFCVT_RTZ_X_F_VL)
-  NODE_NAME_CASE(STRICT_VFCVT_RTZ_XU_F_VL)
-  NODE_NAME_CASE(STRICT_FSETCC_VL)
-  NODE_NAME_CASE(STRICT_FSETCCS_VL)
-  NODE_NAME_CASE(STRICT_VFROUND_NOEXCEPT_VL)
-  NODE_NAME_CASE(VWMUL_VL)
-  NODE_NAME_CASE(VWMULU_VL)
-  NODE_NAME_CASE(VWMULSU_VL)
-  NODE_NAME_CASE(VWADD_VL)
-  NODE_NAME_CASE(VWADDU_VL)
-  NODE_NAME_CASE(VWSUB_VL)
-  NODE_NAME_CASE(VWSUBU_VL)
-  NODE_NAME_CASE(VWADD_W_VL)
-  NODE_NAME_CASE(VWADDU_W_VL)
-  NODE_NAME_CASE(VWSUB_W_VL)
-  NODE_NAME_CASE(VWSUBU_W_VL)
-  NODE_NAME_CASE(VWSLL_VL)
-  NODE_NAME_CASE(VFWMUL_VL)
-  NODE_NAME_CASE(VFWADD_VL)
-  NODE_NAME_CASE(VFWSUB_VL)
-  NODE_NAME_CASE(VFWADD_W_VL)
-  NODE_NAME_CASE(VFWSUB_W_VL)
-  NODE_NAME_CASE(VWMACC_VL)
-  NODE_NAME_CASE(VWMACCU_VL)
-  NODE_NAME_CASE(VWMACCSU_VL)
-  NODE_NAME_CASE(SETCC_VL)
-  NODE_NAME_CASE(VMERGE_VL)
-  NODE_NAME_CASE(VMAND_VL)
-  NODE_NAME_CASE(VMOR_VL)
-  NODE_NAME_CASE(VMXOR_VL)
-  NODE_NAME_CASE(VMCLR_VL)
-  NODE_NAME_CASE(VMSET_VL)
-  NODE_NAME_CASE(VRGATHER_VX_VL)
-  NODE_NAME_CASE(VRGATHER_VV_VL)
-  NODE_NAME_CASE(VRGATHEREI16_VV_VL)
-  NODE_NAME_CASE(VSEXT_VL)
-  NODE_NAME_CASE(VZEXT_VL)
-  NODE_NAME_CASE(VCPOP_VL)
-  NODE_NAME_CASE(VFIRST_VL)
-  NODE_NAME_CASE(READ_CSR)
-  NODE_NAME_CASE(WRITE_CSR)
-  NODE_NAME_CASE(SWAP_CSR)
-  NODE_NAME_CASE(CZERO_EQZ)
-  NODE_NAME_CASE(CZERO_NEZ)
-  NODE_NAME_CASE(SW_GUARDED_BRIND)
-  NODE_NAME_CASE(SW_GUARDED_CALL)
-  NODE_NAME_CASE(SW_GUARDED_TAIL)
-  NODE_NAME_CASE(TUPLE_INSERT)
-  NODE_NAME_CASE(TUPLE_EXTRACT)
-  NODE_NAME_CASE(SF_VC_XV_SE)
-  NODE_NAME_CASE(SF_VC_IV_SE)
-  NODE_NAME_CASE(SF_VC_VV_SE)
-  NODE_NAME_CASE(SF_VC_FV_SE)
-  NODE_NAME_CASE(SF_VC_XVV_SE)
-  NODE_NAME_CASE(SF_VC_IVV_SE)
-  NODE_NAME_CASE(SF_VC_VVV_SE)
-  NODE_NAME_CASE(SF_VC_FVV_SE)
-  NODE_NAME_CASE(SF_VC_XVW_SE)
-  NODE_NAME_CASE(SF_VC_IVW_SE)
-  NODE_NAME_CASE(SF_VC_VVW_SE)
-  NODE_NAME_CASE(SF_VC_FVW_SE)
-  NODE_NAME_CASE(SF_VC_V_X_SE)
-  NODE_NAME_CASE(SF_VC_V_I_SE)
-  NODE_NAME_CASE(SF_VC_V_XV_SE)
-  NODE_NAME_CASE(SF_VC_V_IV_SE)
-  NODE_NAME_CASE(SF_VC_V_VV_SE)
-  NODE_NAME_CASE(SF_VC_V_FV_SE)
-  NODE_NAME_CASE(SF_VC_V_XVV_SE)
-  NODE_NAME_CASE(SF_VC_V_IVV_SE)
-  NODE_NAME_CASE(SF_VC_V_VVV_SE)
-  NODE_NAME_CASE(SF_VC_V_FVV_SE)
-  NODE_NAME_CASE(SF_VC_V_XVW_SE)
-  NODE_NAME_CASE(SF_VC_V_IVW_SE)
-  NODE_NAME_CASE(SF_VC_V_VVW_SE)
-  NODE_NAME_CASE(SF_VC_V_FVW_SE)
-  }
-  // clang-format on
-  return nullptr;
-#undef NODE_NAME_CASE
-}
-
 /// getConstraintType - Given a constraint letter, return the type of
 /// constraint it is for this target.
 RISCVTargetLowering::ConstraintType
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index 3e9e2ca67f645b..1aa6098fab0993 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -26,481 +26,6 @@ class InstructionCost;
 class RISCVSubtarget;
 struct RISCVRegisterInfo;
 
-namespace RISCVISD {
-// clang-format off
-enum NodeType : unsigned {
-  FIRST_NUMBER = ISD::BUILTIN_OP_END,
-  RET_GLUE,
-  SRET_GLUE,
-  MRET_GLUE,
-  CALL,
-  TAIL,
-  /// Select with condition operator - This selects between a true value and
-  /// a false value (ops #3 and #4) based on the boolean result of comparing
-  /// the lhs and rhs (ops #0 and #1) of a conditional expression with the
-  /// condition code in op #2, a XLenVT constant from the ISD::CondCode enum.
-  /// The lhs and rhs are XLenVT integers. The true and false values can be
-  /// integer or floating point.
-  SELECT_CC,
-  BR_CC,
-
-  /// Turn a pair of `i<xlen>`s into an even-odd register pair (`untyped`).
-  /// - Output: `untyped` even-odd register pair
-  /// - Input 0: `i<xlen>` low-order bits, for even register.
-  /// - Input 1: `i<xlen>` high-order bits, for odd register.
-  BuildGPRPair,
-
-  /// Turn an even-odd register pair (`untyped`) into a pair of `i<xlen>`s.
-  /// - Output 0: `i<xlen>` low-order bits, from even register.
-  /// - Output 1: `i<xlen>` high-order bits, from odd register.
-  /// - Input: `untyped` even-odd register pair
-  SplitGPRPair,
-
-  /// Turns a pair of `i32`s into an `f64`. Needed for rv32d/ilp32.
-  /// - Output: `f64`.
-  /// - Input 0: low-order bits (31-0) (as `i32`), for even register.
-  /// - Input 1: high-order bits (63-32) (as `i32`), for odd register.
-  BuildPairF64,
-
-  /// Turns a `f64` into a pair of `i32`s. Needed for rv32d/ilp32.
-  /// - Output 0: low-order bits (31-0) (as `i32`), from even register.
-  /// - Output 1: high-order bits (63-32) (as `i32`), from odd register.
-  /// - Input 0: `f64`.
-  SplitF64,
-
-  // Add the Lo 12 bits from an address. Selected to ADDI.
-  ADD_LO,
-  // Get the Hi 20 bits from an address. Selected to LUI.
-  HI,
-
-  // Represents an AUIPC+ADDI pair. Selected to PseudoLLA.
-  LLA,
-
-  // Selected as PseudoAddTPRel. Used to emit a TP-relative relocation.
-  ADD_TPREL,
-
-  // Multiply high for signedxunsigned.
-  MULHSU,
-
-  // Represents (ADD (SHL a, b), c) with the arguments appearing in the order
-  // a, b, c.  'b' must be a constant.  Maps to sh1add/sh2add/sh3add with zba
-  // or addsl with XTheadBa.
-  SHL_ADD,
-
-  // RV64I shifts, directly matching the semantics of the named RISC-V
-  // instructions.
-  SLLW,
-  SRAW,
-  SRLW,
-  // 32-bit operations from RV64M that can't be simply matched with a pattern
-  // at instruction selection time. These have undefined behavior for division
-  // by 0 or overflow (divw) like their target independent counterparts.
-  DIVW,
-  DIVUW,
-  REMUW,
-  // RV64IB rotates, directly matching the semantics of the named RISC-V
-  // instructions.
-  ROLW,
-  RORW,
-  // RV64IZbb bit counting instructions directly matching the semantics of the
-  // named RISC-V instructions.
-  CLZW,
-  CTZW,
-
-  // RV64IZbb absolute value for i32. Expanded to (max (negw X), X) during isel.
-  ABSW,
-
-  // FPR<->GPR transfer operations when the FPR is smaller than XLEN, needed as
-  // XLEN is the only legal integer width.
-  //
-  // FMV_H_X matches the semantics of the FMV.H.X.
-  // FMV_X_ANYEXTH is similar to FMV.X.H but has an any-extended result.
-  // FMV_X_SIGNEXTH is similar to FMV.X.H and has a sign-extended result.
-  // FMV_W_X_RV64 matches the semantics of the FMV.W.X.
-  // FMV_X_ANYEXTW_RV64 is similar to FMV.X.W but has an any-extended result.
-  //
-  // This is a more convenient semantic for producing dagcombines that remove
-  // unnecessary GPR->FPR->GPR moves.
-  FMV_H_X,
-  FMV_X_ANYEXTH,
-  FMV_X_SIGNEXTH,
-  FMV_W_X_RV64,
-  FMV_X_ANYEXTW_RV64,
-  // FP to XLen int conversions. Corresponds to fcvt.l(u).s/d/h on RV64 and
-  // fcvt.w(u).s/d/h on RV32. Unlike FP_TO_S/UINT these saturate out of
-  // range inputs. These are used for FP_TO_S/UINT_SAT lowering. Rounding mode
-  // is passed as a TargetConstant operand using the RISCVFPRndMode enum.
-  FCVT_X,
-  FCVT_XU,
-  // FP to 32 bit int conversions for RV64. These are used to keep track of the
-  // result being sign extended to 64 bit. These saturate out of range inputs.
-  // Used for FP_TO_S/UINT and FP_TO_S/UINT_SAT lowering. Rounding mode
-  // is passed as a TargetConstant operand using the RISCVFPRndMode enum.
-  FCVT_W_RV64,
-  FCVT_WU_RV64,
-
-  // Rounds an FP value to its corresponding integer in the same FP format.
-  // First operand is the value to round, the second operand is the largest
-  // integer that can be represented exactly in the FP format. This will be
-  // expanded into multiple instructions and basic blocks with a custom
-  // inserter.
-  FROUND,
-
-  FCLASS,
-  FSGNJX,
-
-  // Floating point fmax and fmin matching the RISC-V instruction semantics.
-  FMAX, FMIN,
-
-  // Zfa fli instruction for constant materialization.
-  FLI,
-
-  // A read of the 64-bit counter CSR on a 32-bit target (returns (Lo, Hi)).
-  // It takes a chain operand and another two target constant operands (the
-  // CSR numbers of the low and high parts of the counter).
-  READ_COUNTER_WIDE,
-
-  // brev8, orc.b, zip, and unzip from Zbb and Zbkb. All operands are i32 or
-  // XLenVT.
-  BREV8,
-  ORC_B,
-  ZIP,
-  UNZIP,
-
-  // Scalar cryptography
-  CLMUL, CLMULH, CLMULR,
-  SHA256SIG0, SHA256SIG1, SHA256SUM0, SHA256SUM1,
-  SM4KS, SM4ED,
-  SM3P0, SM3P1,
-
-  // May-Be-Operations
-  MOPR, MOPRR,
-
-  // Vector Extension
-  FIRST_VL_VECTOR_OP,
-  // VMV_V_V_VL matches the semantics of vmv.v.v but includes an extra operand
-  // for the VL value to be used for the operation. The first operand is
-  // passthru operand.
-  VMV_V_V_VL = FIRST_VL_VECTOR_OP,
-  // VMV_V_X_VL matches the semantics of vmv.v.x but includes an extra operand
-  // for the VL value to be used for the operation. The first operand is
-  // passthru operand.
-  VMV_V_X_VL,
-  // VFMV_V_F_VL matches the semantics of vfmv.v.f but includes an extra operand
-  // for the VL value to be used for the operation. The first operand is
-  // passthru operand.
-  VFMV_V_F_VL,
-  // VMV_X_S matches the semantics of vmv.x.s. The result is always XLenVT sign
-  // extended from the vector element size.
-  VMV_X_S,
-  // VMV_S_X_VL matches the semantics of vmv.s.x. It carries a VL operand.
-  VMV_S_X_VL,
-  // VFMV_S_F_VL matches the semantics of vfmv.s.f. It carries a VL operand.
-  VFMV_S_F_VL,
-  // Splats an 64-bit value that has been split into two i32 parts. This is
-  // expanded late to two scalar stores and a stride 0 vector load.
-  // The first operand is passthru operand.
-  SPLAT_VECTOR_SPLIT_I64_VL,
-  // Truncates a RVV integer vector by one power-of-two. Carries both an extra
-  // mask and VL operand.
-  TRUNCATE_VECTOR_VL,
-  // Truncates a RVV integer vector by one power-of-two. If the value doesn't
-  // fit in the destination type, the result is saturated. These correspond to
-  // vnclip and vnclipu with a shift of 0. Carries both an extra mask and VL
-  // operand.
-  TRUNCATE_VECTOR_VL_SSAT,
-  TRUNCATE_VECTOR_VL_USAT,
-  // Matches the semantics of vslideup/vslidedown. The first operand is the
-  // pass-thru operand, the second is the source vector, the third is the XLenVT
-  // index (either constant or non-constant), the fourth is the mask, the fifth
-  // is the VL and the sixth is the policy.
-  VSLIDEUP_VL,
-  VSLIDEDOWN_VL,
-  // Matches the semantics of vslide1up/slide1down. The first operand is
-  // passthru operand, the second is source vector, third is the XLenVT scalar
-  // value. The fourth and fifth operands are the mask and VL operands.
-  VSLIDE1UP_VL,
-  VSLIDE1DOWN_VL,
-  // Matches the semantics of vfslide1up/vfslide1down. The first operand is
-  // passthru operand, the second is source vector, third is a scalar value
-  // whose type matches the element type of the vectors.  The fourth and fifth
-  // operands are the mask and VL operands.
-  VFSLIDE1UP_VL,
-  VFSLIDE1DOWN_VL,
-  // Matches the semantics of the vid.v instruction, with a mask and VL
-  // operand.
-  VID_VL,
-  // Matches the semantics of the vfcnvt.rod function (Convert double-width
-  // float to single-width float, rounding towards odd). Takes a double-width
-  // float vector and produces a single-width float vector. Also has a mask and
-  // VL operand.
-  VFNCVT_ROD_VL,
-  // These nodes match the semantics of the corresponding RVV vector reduction
-  // instructions. They produce a vector result which is the reduction
-  // performed over the second vector operand plus the first element of the
-  // third vector operand. The first operand is the pass-thru operand. The
-  // second operand is an unconstrained vector type, and the result, first, and
-  // third operand's types are expected to be the corresponding full-width
-  // LMUL=1 type for the second operand:
-  //   nxv8i8 = vecreduce_add nxv8i8, nxv32i8, nxv8i8
-  //   nxv2i32 = vecreduce_add nxv2i32, nxv8i32, nxv2i32
-  // The different in types does introduce extra vsetvli instructions but
-  // similarly it reduces the number of registers consumed per reduction.
-  // Also has a mask and VL operand.
-  VECREDUCE_ADD_VL,
-  VECREDUCE_UMAX_VL,
-  VECREDUCE_SMAX_VL,
-  VECREDUCE_UMIN_VL,
-  VECREDUCE_SMIN_VL,
-  VECREDUCE_AND_VL,
-  VECREDUCE_OR_VL,
-  VECREDUCE_XOR_VL,
-  VECREDUCE_FADD_VL,
-  VECREDUCE_SEQ_FADD_VL,
-  VECREDUCE_FMIN_VL,
-  VECREDUCE_FMAX_VL,
-
-  // Vector binary ops with a passthru as a third operand, a mask as a fourth
-  // operand, and VL as a fifth operand.
-  ADD_VL,
-  AND_VL,
-  MUL_VL,
-  OR_VL,
-  SDIV_VL,
-  SHL_VL,
-  SREM_VL,
-  SRA_VL,
-  SRL_VL,
-  ROTL_VL,
-  ROTR_VL,
-  SUB_VL,
-  UDIV_VL,
-  UREM_VL,
-  XOR_VL,
-  SMIN_VL,
-  SMAX_VL,
-  UMIN_VL,
-  UMAX_VL,
-
-  BITREVERSE_VL,
-  BSWAP_VL,
-  CTLZ_VL,
-  CTTZ_VL,
-  CTPOP_VL,
-
-  SADDSAT_VL,
-  UADDSAT_VL,
-  SSUBSAT_VL,
-  USUBSAT_VL,
-
-  // Averaging adds of signed integers.
-  AVGFLOORS_VL,
-  // Averaging adds of unsigned integers.
-  AVGFLOORU_VL,
-  // Rounding averaging adds of signed integers.
-  AVGCEILS_VL,
-  // Rounding averaging adds of unsigned integers.
-  AVGCEILU_VL,
-
-  MULHS_VL,
-  MULHU_VL,
-  FADD_VL,
-  FSUB_VL,
-  FMUL_VL,
-  FDIV_VL,
-  VFMIN_VL,
-  VFMAX_VL,
-
-  // Vector unary ops with a mask as a second operand and VL as a third operand.
-  FNEG_VL,
-  FABS_VL,
-  FSQRT_VL,
-  FCLASS_VL,
-  FCOPYSIGN_VL, // Has a passthru operand
-  VFCVT_RTZ_X_F_VL,
-  VFCVT_RTZ_XU_F_VL,
-  VFROUND_NOEXCEPT_VL,
-  VFCVT_RM_X_F_VL,  // Has a rounding mode operand.
-  VFCVT_RM_XU_F_VL, // Has a rounding mode operand.
-  SINT_TO_FP_VL,
-  UINT_TO_FP_VL,
-  VFCVT_RM_F_X_VL,  // Has a rounding mode operand.
-  VFCVT_RM_F_XU_VL, // Has a rounding mode operand.
-  FP_ROUND_VL,
-  FP_EXTEND_VL,
-
-  // Vector FMA ops with a mask as a fourth operand and VL as a fifth operand.
-  VFMADD_VL,
-  VFNMADD_VL,
-  VFMSUB_VL,
-  VFNMSUB_VL,
-
-  // Vector widening FMA ops with a mask as a fourth operand and VL as a fifth
-  // operand.
-  VFWMADD_VL,
-  VFWNMADD_VL,
-  VFWMSUB_VL,
-  VFWNMSUB_VL,
-
-  // Widening instructions with a passthru value a third operand, a mask as a
-  // fourth operand, and VL as a fifth operand.
-  VWMUL_VL,
-  VWMULU_VL,
-  VWMULSU_VL,
-  VWADD_VL,
-  VWADDU_VL,
-  VWSUB_VL,
-  VWSUBU_VL,
-  VWADD_W_VL,
-  VWADDU_W_VL,
-  VWSUB_W_VL,
-  VWSUBU_W_VL,
-  VWSLL_VL,
-
-  VFWMUL_VL,
-  VFWADD_VL,
-  VFWSUB_VL,
-  VFWADD_W_VL,
-  VFWSUB_W_VL,
-
-  // Widening ternary operations with a mask as the fourth operand and VL as the
-  // fifth operand.
-  VWMACC_VL,
-  VWMACCU_VL,
-  VWMACCSU_VL,
-
-  // Vector compare producing a mask. Fourth operand is input mask. Fifth
-  // operand is VL.
-  SETCC_VL,
-
-  // General vmerge node with mask, true, false, passthru, and vl operands.
-  // Tail agnostic vselect can be implemented by setting passthru to undef.
-  VMERGE_VL,
-
-  // Mask binary operators.
-  VMAND_VL,
-  VMOR_VL,
-  VMXOR_VL,
-
-  // Set mask vector to all zeros or ones.
-  VMCLR_VL,
-  VMSET_VL,
-
-  // Matches the semantics of vrgather.vx and vrgather.vv with extra operands
-  // for passthru and VL. Operands are (src, index, mask, passthru, vl).
-  VRGATHER_VX_VL,
-  VRGATHER_VV_VL,
-  VRGATHEREI16_VV_VL,
-
-  // Vector sign/zero extend with additional mask & VL operands.
-  VSEXT_VL,
-  VZEXT_VL,
-
-  //  vcpop.m with additional mask and VL operands.
-  VCPOP_VL,
-
-  //  vfirst.m with additional mask and VL operands.
-  VFIRST_VL,
-
-  LAST_VL_VECTOR_OP = VFIRST_VL,
-
-  // Read VLENB CSR
-  READ_VLENB,
-  // Reads value of CSR.
-  // The first operand is a chain pointer. The second specifies address of the
-  // required CSR. Two results are produced, the read value and the new chain
-  // pointer.
-  READ_CSR,
-  // Write value to CSR.
-  // The first operand is a chain pointer, the second specifies address of the
-  // required CSR and the third is the value to write. The result is the new
-  // chain pointer.
-  WRITE_CSR,
-  // Read and write value of CSR.
-  // The first operand is a chain pointer, the second specifies address of the
-  // required CSR and the third is the value to write. Two results are produced,
-  // the value read before the modification and the new chain pointer.
-  SWAP_CSR,
-
-  // Branchless select operations, matching the semantics of the instructions
-  // defined in Zicond or XVentanaCondOps.
-  CZERO_EQZ, // vt.maskc for XVentanaCondOps.
-  CZERO_NEZ, // vt.maskcn for XVentanaCondOps.
-
-  // Software guarded BRIND node. Operand 0 is the chain operand and
-  // operand 1 is the target address.
-  SW_GUARDED_BRIND,
-  // Software guarded calls for large code model
-  SW_GUARDED_CALL,
-  SW_GUARDED_TAIL,
-
-  SF_VC_XV_SE,
-  SF_VC_IV_SE,
-  SF_VC_VV_SE,
-  SF_VC_FV_SE,
-  SF_VC_XVV_SE,
-  SF_VC_IVV_SE,
-  SF_VC_VVV_SE,
-  SF_VC_FVV_SE,
-  SF_VC_XVW_SE,
-  SF_VC_IVW_SE,
-  SF_VC_VVW_SE,
-  SF_VC_FVW_SE,
-  SF_VC_V_X_SE,
-  SF_VC_V_I_SE,
-  SF_VC_V_XV_SE,
-  SF_VC_V_IV_SE,
-  SF_VC_V_VV_SE,
-  SF_VC_V_FV_SE,
-  SF_VC_V_XVV_SE,
-  SF_VC_V_IVV_SE,
-  SF_VC_V_VVV_SE,
-  SF_VC_V_FVV_SE,
-  SF_VC_V_XVW_SE,
-  SF_VC_V_IVW_SE,
-  SF_VC_V_VVW_SE,
-  SF_VC_V_FVW_SE,
-
-  // RISC-V vector tuple type version of INSERT_SUBVECTOR/EXTRACT_SUBVECTOR.
-  TUPLE_INSERT,
-  TUPLE_EXTRACT,
-
-  // FP to 32 bit int conversions for RV64. These are used to keep track of the
-  // result being sign extended to 64 bit. These saturate out of range inputs.
-  FIRST_STRICTFP_OPCODE,
-  STRICT_FCVT_W_RV64 = FIRST_STRICTFP_OPCODE,
-  STRICT_FCVT_WU_RV64,
-  STRICT_FADD_VL,
-  STRICT_FSUB_VL,
-  STRICT_FMUL_VL,
-  STRICT_FDIV_VL,
-  STRICT_FSQRT_VL,
-  STRICT_VFMADD_VL,
-  STRICT_VFNMADD_VL,
-  STRICT_VFMSUB_VL,
-  STRICT_VFNMSUB_VL,
-  STRICT_FP_ROUND_VL,
-  STRICT_FP_EXTEND_VL,
-  STRICT_VFNCVT_ROD_VL,
-  STRICT_SINT_TO_FP_VL,
-  STRICT_UINT_TO_FP_VL,
-  STRICT_VFCVT_RM_X_F_VL,
-  STRICT_VFCVT_RTZ_X_F_VL,
-  STRICT_VFCVT_RTZ_XU_F_VL,
-  STRICT_FSETCC_VL,
-  STRICT_FSETCCS_VL,
-  STRICT_VFROUND_NOEXCEPT_VL,
-  LAST_STRICTFP_OPCODE = STRICT_VFROUND_NOEXCEPT_VL,
-
-  TH_LWD,
-  TH_LWUD,
-  TH_LDD,
-  TH_SWD,
-  TH_SDD,
-};
-// clang-format on
-} // namespace RISCVISD
-
 class RISCVTargetLowering : public TargetLowering {
   const RISCVSubtarget &Subtarget;
 
@@ -635,9 +160,6 @@ class RISCVTargetLowering : public TargetLowering {
 
   const Constant *getTargetConstantFromLoad(LoadSDNode *LD) const override;
 
-  // This method returns the name of a target specific DAG node.
-  const char *getTargetNodeName(unsigned Opcode) const override;
-
   MachineMemOperand::Flags
   getTargetMMOFlags(const Instruction &I) const override;
 
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td
index 6c41c53bb301fd..78d6ff5d24d68b 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td
@@ -59,12 +59,14 @@ def riscv_fcvt_xu
 def riscv_fmin : SDNode<"RISCVISD::FMIN", SDTFPBinOp>;
 def riscv_fmax : SDNode<"RISCVISD::FMAX", SDTFPBinOp>;
 
-def riscv_strict_fcvt_w_rv64
-    : SDNode<"RISCVISD::STRICT_FCVT_W_RV64", SDT_RISCVFCVT_W_RV64,
-             [SDNPHasChain]>;
-def riscv_strict_fcvt_wu_rv64
-    : SDNode<"RISCVISD::STRICT_FCVT_WU_RV64", SDT_RISCVFCVT_W_RV64,
-             [SDNPHasChain]>;
+let IsStrictFP = true in {
+  def riscv_strict_fcvt_w_rv64
+      : SDNode<"RISCVISD::STRICT_FCVT_W_RV64", SDT_RISCVFCVT_W_RV64,
+               [SDNPHasChain]>;
+  def riscv_strict_fcvt_wu_rv64
+      : SDNode<"RISCVISD::STRICT_FCVT_WU_RV64", SDT_RISCVFCVT_W_RV64,
+               [SDNPHasChain]>;
+}
 
 def riscv_any_fcvt_w_rv64 : PatFrags<(ops node:$src, node:$frm),
                                      [(riscv_strict_fcvt_w_rv64 node:$src, node:$frm),
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
index 2026ba79e623d8..dd158a5fae200f 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
@@ -21,6 +21,16 @@
 // Helpers to define the VL patterns.
 //===----------------------------------------------------------------------===//
 
+class RVSDNode<string opcode, SDTypeProfile type_profile,
+               list<SDNodeProperty> properties = []>
+    : SDNode<"RISCVISD::" # opcode, type_profile, properties> {
+  bit HasPassthruOp = false;
+  bit HasMaskOp = false;
+
+  let TSFlags{0} = HasPassthruOp;
+  let TSFlags{1} = HasMaskOp;
+}
+
 def SDT_RISCVIntUnOp_VL : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>,
                                                SDTCisSameAs<0, 2>,
                                                SDTCisVec<0>, SDTCisInt<0>,
@@ -69,85 +79,99 @@ def SDT_RISCVCopySign_VL : SDTypeProfile<1, 5, [SDTCisSameAs<0, 1>,
                                                 SDTCisSameNumEltsAs<0, 4>,
                                                 SDTCisVT<5, XLenVT>]>;
 
-def riscv_vmv_v_v_vl : SDNode<"RISCVISD::VMV_V_V_VL",
-                              SDTypeProfile<1, 3, [SDTCisVec<0>,
-                                                   SDTCisSameAs<0, 1>,
-                                                   SDTCisSameAs<0, 2>,
-                                                   SDTCisVT<3, XLenVT>]>>;
-def riscv_vmv_v_x_vl : SDNode<"RISCVISD::VMV_V_X_VL",
-                              SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisInt<0>,
-                                                   SDTCisSameAs<0, 1>,
-                                                   SDTCisVT<2, XLenVT>,
-                                                   SDTCisVT<3, XLenVT>]>>;
-def riscv_vfmv_v_f_vl : SDNode<"RISCVISD::VFMV_V_F_VL",
-                               SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisFP<0>,
-                                                    SDTCisSameAs<0, 1>,
-                                                    SDTCisEltOfVec<2, 0>,
-                                                    SDTCisVT<3, XLenVT>]>>;
-def riscv_vmv_s_x_vl : SDNode<"RISCVISD::VMV_S_X_VL",
-                              SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>,
-                                                   SDTCisInt<0>,
-                                                   SDTCisVT<2, XLenVT>,
-                                                   SDTCisVT<3, XLenVT>]>>;
-def riscv_vfmv_s_f_vl : SDNode<"RISCVISD::VFMV_S_F_VL",
-                               SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>,
-                                                    SDTCisFP<0>,
-                                                    SDTCisEltOfVec<2, 0>,
-                                                    SDTCisVT<3, XLenVT>]>>;
-
-def riscv_add_vl   : SDNode<"RISCVISD::ADD_VL",   SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
-def riscv_sub_vl   : SDNode<"RISCVISD::SUB_VL",   SDT_RISCVIntBinOp_VL>;
-def riscv_mul_vl   : SDNode<"RISCVISD::MUL_VL",   SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
-def riscv_mulhs_vl : SDNode<"RISCVISD::MULHS_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
-def riscv_mulhu_vl : SDNode<"RISCVISD::MULHU_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
-def riscv_and_vl   : SDNode<"RISCVISD::AND_VL",   SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
-def riscv_or_vl    : SDNode<"RISCVISD::OR_VL",    SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
-def riscv_xor_vl   : SDNode<"RISCVISD::XOR_VL",   SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
-def riscv_sdiv_vl  : SDNode<"RISCVISD::SDIV_VL",  SDT_RISCVIntBinOp_VL>;
-def riscv_srem_vl  : SDNode<"RISCVISD::SREM_VL",  SDT_RISCVIntBinOp_VL>;
-def riscv_udiv_vl  : SDNode<"RISCVISD::UDIV_VL",  SDT_RISCVIntBinOp_VL>;
-def riscv_urem_vl  : SDNode<"RISCVISD::UREM_VL",  SDT_RISCVIntBinOp_VL>;
-def riscv_shl_vl   : SDNode<"RISCVISD::SHL_VL",   SDT_RISCVIntBinOp_VL>;
-def riscv_sra_vl   : SDNode<"RISCVISD::SRA_VL",   SDT_RISCVIntBinOp_VL>;
-def riscv_srl_vl   : SDNode<"RISCVISD::SRL_VL",   SDT_RISCVIntBinOp_VL>;
-def riscv_rotl_vl  : SDNode<"RISCVISD::ROTL_VL",  SDT_RISCVIntBinOp_VL>;
-def riscv_rotr_vl  : SDNode<"RISCVISD::ROTR_VL",  SDT_RISCVIntBinOp_VL>;
-def riscv_smin_vl  : SDNode<"RISCVISD::SMIN_VL",  SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
-def riscv_smax_vl  : SDNode<"RISCVISD::SMAX_VL",  SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
-def riscv_umin_vl  : SDNode<"RISCVISD::UMIN_VL",  SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
-def riscv_umax_vl  : SDNode<"RISCVISD::UMAX_VL",  SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
-
-def riscv_bitreverse_vl : SDNode<"RISCVISD::BITREVERSE_VL", SDT_RISCVIntUnOp_VL>;
-def riscv_bswap_vl      : SDNode<"RISCVISD::BSWAP_VL",      SDT_RISCVIntUnOp_VL>;
-def riscv_ctlz_vl       : SDNode<"RISCVISD::CTLZ_VL",       SDT_RISCVIntUnOp_VL>;
-def riscv_cttz_vl       : SDNode<"RISCVISD::CTTZ_VL",       SDT_RISCVIntUnOp_VL>;
-def riscv_ctpop_vl      : SDNode<"RISCVISD::CTPOP_VL",      SDT_RISCVIntUnOp_VL>;
-
-def riscv_avgfloors_vl  : SDNode<"RISCVISD::AVGFLOORS_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
-def riscv_avgflooru_vl  : SDNode<"RISCVISD::AVGFLOORU_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
-def riscv_avgceils_vl   : SDNode<"RISCVISD::AVGCEILS_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
-def riscv_avgceilu_vl   : SDNode<"RISCVISD::AVGCEILU_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
-def riscv_saddsat_vl   : SDNode<"RISCVISD::SADDSAT_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
-def riscv_uaddsat_vl   : SDNode<"RISCVISD::UADDSAT_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
-def riscv_ssubsat_vl   : SDNode<"RISCVISD::SSUBSAT_VL", SDT_RISCVIntBinOp_VL>;
-def riscv_usubsat_vl   : SDNode<"RISCVISD::USUBSAT_VL", SDT_RISCVIntBinOp_VL>;
-
-def riscv_fadd_vl  : SDNode<"RISCVISD::FADD_VL",  SDT_RISCVFPBinOp_VL, [SDNPCommutative]>;
-def riscv_fsub_vl  : SDNode<"RISCVISD::FSUB_VL",  SDT_RISCVFPBinOp_VL>;
-def riscv_fmul_vl  : SDNode<"RISCVISD::FMUL_VL",  SDT_RISCVFPBinOp_VL, [SDNPCommutative]>;
-def riscv_fdiv_vl  : SDNode<"RISCVISD::FDIV_VL",  SDT_RISCVFPBinOp_VL>;
-def riscv_fneg_vl  : SDNode<"RISCVISD::FNEG_VL",  SDT_RISCVFPUnOp_VL>;
-def riscv_fabs_vl  : SDNode<"RISCVISD::FABS_VL",  SDT_RISCVFPUnOp_VL>;
-def riscv_fsqrt_vl : SDNode<"RISCVISD::FSQRT_VL", SDT_RISCVFPUnOp_VL>;
-def riscv_fcopysign_vl : SDNode<"RISCVISD::FCOPYSIGN_VL", SDT_RISCVCopySign_VL>;
-def riscv_vfmin_vl   : SDNode<"RISCVISD::VFMIN_VL",  SDT_RISCVFPBinOp_VL, [SDNPCommutative]>;
-def riscv_vfmax_vl   : SDNode<"RISCVISD::VFMAX_VL",  SDT_RISCVFPBinOp_VL, [SDNPCommutative]>;
-
-def riscv_strict_fadd_vl  : SDNode<"RISCVISD::STRICT_FADD_VL",  SDT_RISCVFPBinOp_VL, [SDNPCommutative, SDNPHasChain]>;
-def riscv_strict_fsub_vl  : SDNode<"RISCVISD::STRICT_FSUB_VL",  SDT_RISCVFPBinOp_VL, [SDNPHasChain]>;
-def riscv_strict_fmul_vl  : SDNode<"RISCVISD::STRICT_FMUL_VL",  SDT_RISCVFPBinOp_VL, [SDNPCommutative, SDNPHasChain]>;
-def riscv_strict_fdiv_vl  : SDNode<"RISCVISD::STRICT_FDIV_VL",  SDT_RISCVFPBinOp_VL, [SDNPHasChain]>;
-def riscv_strict_fsqrt_vl : SDNode<"RISCVISD::STRICT_FSQRT_VL", SDT_RISCVFPUnOp_VL, [SDNPHasChain]>;
+def riscv_vmv_v_v_vl : RVSDNode<"VMV_V_V_VL",
+                                SDTypeProfile<1, 3, [SDTCisVec<0>,
+                                                     SDTCisSameAs<0, 1>,
+                                                     SDTCisSameAs<0, 2>,
+                                                     SDTCisVT<3, XLenVT>]>>;
+def riscv_vmv_v_x_vl : RVSDNode<"VMV_V_X_VL",
+                                SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisInt<0>,
+                                                     SDTCisSameAs<0, 1>,
+                                                     SDTCisVT<2, XLenVT>,
+                                                     SDTCisVT<3, XLenVT>]>>;
+def riscv_vfmv_v_f_vl : RVSDNode<"VFMV_V_F_VL",
+                                 SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisFP<0>,
+                                                      SDTCisSameAs<0, 1>,
+                                                      SDTCisEltOfVec<2, 0>,
+                                                      SDTCisVT<3, XLenVT>]>>;
+def riscv_vmv_s_x_vl : RVSDNode<"VMV_S_X_VL",
+                                SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>,
+                                                     SDTCisInt<0>,
+                                                     SDTCisVT<2, XLenVT>,
+                                                     SDTCisVT<3, XLenVT>]>>;
+def riscv_vfmv_s_f_vl : RVSDNode<"VFMV_S_F_VL",
+                                 SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>,
+                                                      SDTCisFP<0>,
+                                                      SDTCisEltOfVec<2, 0>,
+                                                      SDTCisVT<3, XLenVT>]>>;
+
+let HasPassthruOp = true, HasMaskOp = true in {
+  def riscv_add_vl   : RVSDNode<"ADD_VL",   SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_sub_vl   : RVSDNode<"SUB_VL",   SDT_RISCVIntBinOp_VL>;
+  def riscv_mul_vl   : RVSDNode<"MUL_VL",   SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_mulhs_vl : RVSDNode<"MULHS_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_mulhu_vl : RVSDNode<"MULHU_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_and_vl   : RVSDNode<"AND_VL",   SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_or_vl    : RVSDNode<"OR_VL",    SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_xor_vl   : RVSDNode<"XOR_VL",   SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_sdiv_vl  : RVSDNode<"SDIV_VL",  SDT_RISCVIntBinOp_VL>;
+  def riscv_srem_vl  : RVSDNode<"SREM_VL",  SDT_RISCVIntBinOp_VL>;
+  def riscv_udiv_vl  : RVSDNode<"UDIV_VL",  SDT_RISCVIntBinOp_VL>;
+  def riscv_urem_vl  : RVSDNode<"UREM_VL",  SDT_RISCVIntBinOp_VL>;
+  def riscv_shl_vl   : RVSDNode<"SHL_VL",   SDT_RISCVIntBinOp_VL>;
+  def riscv_sra_vl   : RVSDNode<"SRA_VL",   SDT_RISCVIntBinOp_VL>;
+  def riscv_srl_vl   : RVSDNode<"SRL_VL",   SDT_RISCVIntBinOp_VL>;
+  def riscv_rotl_vl  : RVSDNode<"ROTL_VL",  SDT_RISCVIntBinOp_VL>;
+  def riscv_rotr_vl  : RVSDNode<"ROTR_VL",  SDT_RISCVIntBinOp_VL>;
+  def riscv_smin_vl  : RVSDNode<"SMIN_VL",  SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_smax_vl  : RVSDNode<"SMAX_VL",  SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_umin_vl  : RVSDNode<"UMIN_VL",  SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_umax_vl  : RVSDNode<"UMAX_VL",  SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
+
+  def riscv_bitreverse_vl : RVSDNode<"BITREVERSE_VL", SDT_RISCVIntUnOp_VL>;
+  def riscv_bswap_vl      : RVSDNode<"BSWAP_VL",      SDT_RISCVIntUnOp_VL>;
+  def riscv_ctlz_vl       : RVSDNode<"CTLZ_VL",       SDT_RISCVIntUnOp_VL>;
+  def riscv_cttz_vl       : RVSDNode<"CTTZ_VL",       SDT_RISCVIntUnOp_VL>;
+  def riscv_ctpop_vl      : RVSDNode<"CTPOP_VL",      SDT_RISCVIntUnOp_VL>;
+
+  def riscv_avgfloors_vl : RVSDNode<"AVGFLOORS_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_avgflooru_vl : RVSDNode<"AVGFLOORU_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_avgceils_vl  : RVSDNode<"AVGCEILS_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_avgceilu_vl  : RVSDNode<"AVGCEILU_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_saddsat_vl   : RVSDNode<"SADDSAT_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_uaddsat_vl   : RVSDNode<"UADDSAT_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_ssubsat_vl   : RVSDNode<"SSUBSAT_VL", SDT_RISCVIntBinOp_VL>;
+  def riscv_usubsat_vl   : RVSDNode<"USUBSAT_VL", SDT_RISCVIntBinOp_VL>;
+
+  def riscv_fadd_vl  : RVSDNode<"FADD_VL",  SDT_RISCVFPBinOp_VL, [SDNPCommutative]>;
+  def riscv_fsub_vl  : RVSDNode<"FSUB_VL",  SDT_RISCVFPBinOp_VL>;
+  def riscv_fmul_vl  : RVSDNode<"FMUL_VL",  SDT_RISCVFPBinOp_VL, [SDNPCommutative]>;
+  def riscv_fdiv_vl  : RVSDNode<"FDIV_VL",  SDT_RISCVFPBinOp_VL>;
+}
+
+let HasMaskOp = true in {
+  def riscv_fneg_vl  : RVSDNode<"FNEG_VL",  SDT_RISCVFPUnOp_VL>;
+  def riscv_fabs_vl  : RVSDNode<"FABS_VL",  SDT_RISCVFPUnOp_VL>;
+  def riscv_fsqrt_vl : RVSDNode<"FSQRT_VL", SDT_RISCVFPUnOp_VL>;
+}
+
+let HasPassthruOp = true, HasMaskOp = true in
+def riscv_fcopysign_vl : RVSDNode<"FCOPYSIGN_VL", SDT_RISCVCopySign_VL>;
+
+let HasPassthruOp = true, HasMaskOp = true in {
+  def riscv_vfmin_vl : RVSDNode<"VFMIN_VL", SDT_RISCVFPBinOp_VL, [SDNPCommutative]>;
+  def riscv_vfmax_vl : RVSDNode<"VFMAX_VL", SDT_RISCVFPBinOp_VL, [SDNPCommutative]>;
+}
+
+let IsStrictFP = true, HasPassthruOp = true, HasMaskOp = true in {
+  def riscv_strict_fadd_vl : RVSDNode<"STRICT_FADD_VL", SDT_RISCVFPBinOp_VL, [SDNPCommutative, SDNPHasChain]>;
+  def riscv_strict_fsub_vl : RVSDNode<"STRICT_FSUB_VL", SDT_RISCVFPBinOp_VL, [SDNPHasChain]>;
+  def riscv_strict_fmul_vl : RVSDNode<"STRICT_FMUL_VL", SDT_RISCVFPBinOp_VL, [SDNPCommutative, SDNPHasChain]>;
+  def riscv_strict_fdiv_vl : RVSDNode<"STRICT_FDIV_VL", SDT_RISCVFPBinOp_VL, [SDNPHasChain]>;
+}
+
+let IsStrictFP = true, HasMaskOp = true in
+def riscv_strict_fsqrt_vl : RVSDNode<"STRICT_FSQRT_VL", SDT_RISCVFPUnOp_VL, [SDNPHasChain]>;
 
 def any_riscv_fadd_vl : PatFrags<(ops node:$lhs, node:$rhs, node:$passthru, node:$mask, node:$vl),
                         [(riscv_fadd_vl node:$lhs, node:$rhs, node:$passthru, node:$mask, node:$vl),
@@ -165,7 +189,8 @@ def any_riscv_fsqrt_vl : PatFrags<(ops node:$src, node:$mask, node:$vl),
                         [(riscv_fsqrt_vl node:$src, node:$mask, node:$vl),
                          (riscv_strict_fsqrt_vl node:$src, node:$mask, node:$vl)]>;
 
-def riscv_fclass_vl : SDNode<"RISCVISD::FCLASS_VL",
+let HasMaskOp = true in
+def riscv_fclass_vl : RVSDNode<"FCLASS_VL",
                              SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisVec<0>,
                                                   SDTCisFP<1>, SDTCisVec<1>,
                                                   SDTCisSameSizeAs<0, 1>,
@@ -181,10 +206,12 @@ def SDT_RISCVVecFMA_VL : SDTypeProfile<1, 5, [SDTCisSameAs<0, 1>,
                                               SDTCVecEltisVT<4, i1>,
                                               SDTCisSameNumEltsAs<0, 4>,
                                               SDTCisVT<5, XLenVT>]>;
-def riscv_vfmadd_vl  : SDNode<"RISCVISD::VFMADD_VL",  SDT_RISCVVecFMA_VL, [SDNPCommutative]>;
-def riscv_vfnmadd_vl : SDNode<"RISCVISD::VFNMADD_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative]>;
-def riscv_vfmsub_vl  : SDNode<"RISCVISD::VFMSUB_VL",  SDT_RISCVVecFMA_VL, [SDNPCommutative]>;
-def riscv_vfnmsub_vl : SDNode<"RISCVISD::VFNMSUB_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative]>;
+let HasMaskOp = true in {
+  def riscv_vfmadd_vl  : RVSDNode<"VFMADD_VL",  SDT_RISCVVecFMA_VL, [SDNPCommutative]>;
+  def riscv_vfnmadd_vl : RVSDNode<"VFNMADD_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative]>;
+  def riscv_vfmsub_vl  : RVSDNode<"VFMSUB_VL",  SDT_RISCVVecFMA_VL, [SDNPCommutative]>;
+  def riscv_vfnmsub_vl : RVSDNode<"VFNMSUB_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative]>;
+}
 
 def SDT_RISCVWVecFMA_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisFP<0>,
                                                SDTCisVec<1>, SDTCisFP<1>,
@@ -195,15 +222,19 @@ def SDT_RISCVWVecFMA_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisFP<0>,
                                                SDTCVecEltisVT<4, i1>,
                                                SDTCisSameNumEltsAs<0, 4>,
                                                SDTCisVT<5, XLenVT>]>;
-def riscv_vfwmadd_vl  : SDNode<"RISCVISD::VFWMADD_VL",  SDT_RISCVWVecFMA_VL, [SDNPCommutative]>;
-def riscv_vfwnmadd_vl : SDNode<"RISCVISD::VFWNMADD_VL", SDT_RISCVWVecFMA_VL, [SDNPCommutative]>;
-def riscv_vfwmsub_vl  : SDNode<"RISCVISD::VFWMSUB_VL",  SDT_RISCVWVecFMA_VL, [SDNPCommutative]>;
-def riscv_vfwnmsub_vl : SDNode<"RISCVISD::VFWNMSUB_VL", SDT_RISCVWVecFMA_VL, [SDNPCommutative]>;
+let HasMaskOp = true in {
+  def riscv_vfwmadd_vl  : RVSDNode<"VFWMADD_VL",  SDT_RISCVWVecFMA_VL, [SDNPCommutative]>;
+  def riscv_vfwnmadd_vl : RVSDNode<"VFWNMADD_VL", SDT_RISCVWVecFMA_VL, [SDNPCommutative]>;
+  def riscv_vfwmsub_vl  : RVSDNode<"VFWMSUB_VL",  SDT_RISCVWVecFMA_VL, [SDNPCommutative]>;
+  def riscv_vfwnmsub_vl : RVSDNode<"VFWNMSUB_VL", SDT_RISCVWVecFMA_VL, [SDNPCommutative]>;
+}
 
-def riscv_strict_vfmadd_vl : SDNode<"RISCVISD::STRICT_VFMADD_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative, SDNPHasChain]>;
-def riscv_strict_vfnmadd_vl : SDNode<"RISCVISD::STRICT_VFNMADD_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative, SDNPHasChain]>;
-def riscv_strict_vfmsub_vl : SDNode<"RISCVISD::STRICT_VFMSUB_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative, SDNPHasChain]>;
-def riscv_strict_vfnmsub_vl : SDNode<"RISCVISD::STRICT_VFNMSUB_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative, SDNPHasChain]>;
+let IsStrictFP = true, HasMaskOp = true in {
+  def riscv_strict_vfmadd_vl  : RVSDNode<"STRICT_VFMADD_VL",  SDT_RISCVVecFMA_VL, [SDNPCommutative, SDNPHasChain]>;
+  def riscv_strict_vfnmadd_vl : RVSDNode<"STRICT_VFNMADD_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative, SDNPHasChain]>;
+  def riscv_strict_vfmsub_vl  : RVSDNode<"STRICT_VFMSUB_VL",  SDT_RISCVVecFMA_VL, [SDNPCommutative, SDNPHasChain]>;
+  def riscv_strict_vfnmsub_vl : RVSDNode<"STRICT_VFNMSUB_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative, SDNPHasChain]>;
+}
 
 def any_riscv_vfmadd_vl : PatFrags<(ops node:$rs1, node:$rs2, node:$rs3, node:$mask, node:$vl),
                         [(riscv_vfmadd_vl node:$rs1, node:$rs2, node:$rs3, node:$mask, node:$vl),
@@ -227,12 +258,17 @@ def SDT_RISCVFPExtendOp_VL  : SDTypeProfile<1, 3, [
   SDTCVecEltisVT<2, i1>, SDTCisSameNumEltsAs<1, 2>, SDTCisVT<3, XLenVT>
 ]>;
 
-def riscv_fpround_vl : SDNode<"RISCVISD::FP_ROUND_VL", SDT_RISCVFPRoundOp_VL>;
-def riscv_strict_fpround_vl : SDNode<"RISCVISD::STRICT_FP_ROUND_VL", SDT_RISCVFPRoundOp_VL, [SDNPHasChain]>;
-def riscv_fpextend_vl : SDNode<"RISCVISD::FP_EXTEND_VL", SDT_RISCVFPExtendOp_VL>;
-def riscv_strict_fpextend_vl : SDNode<"RISCVISD::STRICT_FP_EXTEND_VL", SDT_RISCVFPExtendOp_VL, [SDNPHasChain]>;
-def riscv_fncvt_rod_vl : SDNode<"RISCVISD::VFNCVT_ROD_VL", SDT_RISCVFPRoundOp_VL>;
-def riscv_strict_fncvt_rod_vl : SDNode<"RISCVISD::STRICT_VFNCVT_ROD_VL", SDT_RISCVFPRoundOp_VL, [SDNPHasChain]>;
+let HasMaskOp = true in {
+  def riscv_fpround_vl   : RVSDNode<"FP_ROUND_VL", SDT_RISCVFPRoundOp_VL>;
+  def riscv_fpextend_vl  : RVSDNode<"FP_EXTEND_VL", SDT_RISCVFPExtendOp_VL>;
+  def riscv_fncvt_rod_vl : RVSDNode<"VFNCVT_ROD_VL", SDT_RISCVFPRoundOp_VL>;
+}
+
+let IsStrictFP = true, HasMaskOp = true in {
+  def riscv_strict_fpround_vl   : RVSDNode<"STRICT_FP_ROUND_VL",   SDT_RISCVFPRoundOp_VL,  [SDNPHasChain]>;
+  def riscv_strict_fpextend_vl  : RVSDNode<"STRICT_FP_EXTEND_VL",  SDT_RISCVFPExtendOp_VL, [SDNPHasChain]>;
+  def riscv_strict_fncvt_rod_vl : RVSDNode<"STRICT_VFNCVT_ROD_VL", SDT_RISCVFPRoundOp_VL,  [SDNPHasChain]>;
+}
 
 def any_riscv_fpround_vl : PatFrags<(ops node:$src, node:$mask, node:$vl),
                             [(riscv_fpround_vl node:$src, node:$mask, node:$vl),
@@ -270,15 +306,19 @@ def SDT_RISCVSETCCOP_VL : SDTypeProfile<1, 6, [
   SDTCisSameAs<0, 5>, SDTCisVT<6, XLenVT>]>;
 
 // Float -> Int
-def riscv_vfcvt_rm_xu_f_vl : SDNode<"RISCVISD::VFCVT_RM_XU_F_VL", SDT_RISCVFP2IOp_RM_VL>;
-def riscv_vfcvt_rm_x_f_vl : SDNode<"RISCVISD::VFCVT_RM_X_F_VL", SDT_RISCVFP2IOp_RM_VL>;
+let HasMaskOp = true in {
+  def riscv_vfcvt_rm_xu_f_vl : RVSDNode<"VFCVT_RM_XU_F_VL", SDT_RISCVFP2IOp_RM_VL>;
+  def riscv_vfcvt_rm_x_f_vl  : RVSDNode<"VFCVT_RM_X_F_VL",  SDT_RISCVFP2IOp_RM_VL>;
 
-def riscv_vfcvt_rtz_xu_f_vl : SDNode<"RISCVISD::VFCVT_RTZ_XU_F_VL", SDT_RISCVFP2IOp_VL>;
-def riscv_vfcvt_rtz_x_f_vl  : SDNode<"RISCVISD::VFCVT_RTZ_X_F_VL",  SDT_RISCVFP2IOp_VL>;
+  def riscv_vfcvt_rtz_xu_f_vl : RVSDNode<"VFCVT_RTZ_XU_F_VL", SDT_RISCVFP2IOp_VL>;
+  def riscv_vfcvt_rtz_x_f_vl  : RVSDNode<"VFCVT_RTZ_X_F_VL",  SDT_RISCVFP2IOp_VL>;
+}
 
-def riscv_strict_vfcvt_rm_x_f_vl : SDNode<"RISCVISD::STRICT_VFCVT_RM_X_F_VL", SDT_RISCVFP2IOp_RM_VL, [SDNPHasChain]>;
-def riscv_strict_vfcvt_rtz_xu_f_vl : SDNode<"RISCVISD::STRICT_VFCVT_RTZ_XU_F_VL", SDT_RISCVFP2IOp_VL, [SDNPHasChain]>;
-def riscv_strict_vfcvt_rtz_x_f_vl  : SDNode<"RISCVISD::STRICT_VFCVT_RTZ_X_F_VL",  SDT_RISCVFP2IOp_VL, [SDNPHasChain]>;
+let IsStrictFP = true, HasMaskOp = true in {
+  def riscv_strict_vfcvt_rm_x_f_vl   : RVSDNode<"STRICT_VFCVT_RM_X_F_VL",   SDT_RISCVFP2IOp_RM_VL, [SDNPHasChain]>;
+  def riscv_strict_vfcvt_rtz_xu_f_vl : RVSDNode<"STRICT_VFCVT_RTZ_XU_F_VL", SDT_RISCVFP2IOp_VL,    [SDNPHasChain]>;
+  def riscv_strict_vfcvt_rtz_x_f_vl  : RVSDNode<"STRICT_VFCVT_RTZ_X_F_VL",  SDT_RISCVFP2IOp_VL,    [SDNPHasChain]>;
+}
 
 def any_riscv_vfcvt_rm_x_f_vl : PatFrags<(ops node:$src, node:$mask, node:$vl, node:$rm),
                             [(riscv_vfcvt_rm_x_f_vl node:$src, node:$mask, node:$vl, node:$rm),
@@ -291,13 +331,17 @@ def any_riscv_vfcvt_rtz_x_f_vl : PatFrags<(ops node:$src, node:$mask, node:$vl),
                              (riscv_strict_vfcvt_rtz_x_f_vl node:$src, node:$mask, node:$vl)]>;
 
 // Int -> Float
-def riscv_sint_to_fp_vl : SDNode<"RISCVISD::SINT_TO_FP_VL", SDT_RISCVI2FPOp_VL>;
-def riscv_uint_to_fp_vl : SDNode<"RISCVISD::UINT_TO_FP_VL", SDT_RISCVI2FPOp_VL>;
-def riscv_vfcvt_rm_f_xu_vl : SDNode<"RISCVISD::VFCVT_RM_F_XU_VL", SDT_RISCVI2FPOp_RM_VL>;
-def riscv_vfcvt_rm_f_x_vl : SDNode<"RISCVISD::VFCVT_RM_F_X_VL", SDT_RISCVI2FPOp_RM_VL>;
+let HasMaskOp = true in {
+  def riscv_sint_to_fp_vl    : RVSDNode<"SINT_TO_FP_VL",    SDT_RISCVI2FPOp_VL>;
+  def riscv_uint_to_fp_vl    : RVSDNode<"UINT_TO_FP_VL",    SDT_RISCVI2FPOp_VL>;
+  def riscv_vfcvt_rm_f_xu_vl : RVSDNode<"VFCVT_RM_F_XU_VL", SDT_RISCVI2FPOp_RM_VL>;
+  def riscv_vfcvt_rm_f_x_vl  : RVSDNode<"VFCVT_RM_F_X_VL",  SDT_RISCVI2FPOp_RM_VL>;
+}
 
-def riscv_strict_sint_to_fp_vl : SDNode<"RISCVISD::STRICT_SINT_TO_FP_VL", SDT_RISCVI2FPOp_VL, [SDNPHasChain]>;
-def riscv_strict_uint_to_fp_vl : SDNode<"RISCVISD::STRICT_UINT_TO_FP_VL", SDT_RISCVI2FPOp_VL, [SDNPHasChain]>;
+let IsStrictFP = true, HasMaskOp = true in {
+  def riscv_strict_sint_to_fp_vl : RVSDNode<"STRICT_SINT_TO_FP_VL", SDT_RISCVI2FPOp_VL, [SDNPHasChain]>;
+  def riscv_strict_uint_to_fp_vl : RVSDNode<"STRICT_UINT_TO_FP_VL", SDT_RISCVI2FPOp_VL, [SDNPHasChain]>;
+}
 
 def any_riscv_sint_to_fp_vl : PatFrags<(ops node:$src, node:$mask, node:$vl),
                             [(riscv_sint_to_fp_vl node:$src, node:$mask, node:$vl),
@@ -306,16 +350,25 @@ def any_riscv_uint_to_fp_vl : PatFrags<(ops node:$src, node:$mask, node:$vl),
                             [(riscv_uint_to_fp_vl node:$src, node:$mask, node:$vl),
                              (riscv_strict_uint_to_fp_vl node:$src, node:$mask, node:$vl)]>;
 
-def riscv_vfround_noexcept_vl: SDNode<"RISCVISD::VFROUND_NOEXCEPT_VL", SDT_RISCVFPUnOp_VL>;
-def riscv_strict_vfround_noexcept_vl: SDNode<"RISCVISD::STRICT_VFROUND_NOEXCEPT_VL", SDT_RISCVFPUnOp_VL, [SDNPHasChain]>;
+let HasMaskOp = true in {
+  def riscv_vfround_noexcept_vl : RVSDNode<"VFROUND_NOEXCEPT_VL", SDT_RISCVFPUnOp_VL>;
+
+  let IsStrictFP = true in
+  def riscv_strict_vfround_noexcept_vl : RVSDNode<"STRICT_VFROUND_NOEXCEPT_VL", SDT_RISCVFPUnOp_VL, [SDNPHasChain]>;
+}
 
 def any_riscv_vfround_noexcept_vl : PatFrags<(ops node:$src, node:$mask, node:$vl),
                         [(riscv_vfround_noexcept_vl node:$src, node:$mask, node:$vl),
                          (riscv_strict_vfround_noexcept_vl node:$src, node:$mask, node:$vl)]>;
 
-def riscv_setcc_vl : SDNode<"RISCVISD::SETCC_VL", SDT_RISCVSETCCOP_VL>;
-def riscv_strict_fsetcc_vl : SDNode<"RISCVISD::STRICT_FSETCC_VL", SDT_RISCVSETCCOP_VL, [SDNPHasChain]>;
-def riscv_strict_fsetccs_vl : SDNode<"RISCVISD::STRICT_FSETCCS_VL", SDT_RISCVSETCCOP_VL, [SDNPHasChain]>;
+let HasPassthruOp = true, HasMaskOp = true in
+def riscv_setcc_vl : RVSDNode<"SETCC_VL", SDT_RISCVSETCCOP_VL>;
+
+let IsStrictFP = true, HasMaskOp = true in {
+  def riscv_strict_fsetcc_vl  : RVSDNode<"STRICT_FSETCC_VL",  SDT_RISCVSETCCOP_VL, [SDNPHasChain]>;
+  def riscv_strict_fsetccs_vl : RVSDNode<"STRICT_FSETCCS_VL", SDT_RISCVSETCCOP_VL, [SDNPHasChain]>;
+}
+
 def any_riscv_fsetcc_vl : PatFrags<(ops node:$lhs, node:$rhs, node:$cc, node:$passthru, node:$mask, node:$vl),
                             [(riscv_setcc_vl node:$lhs, node:$rhs, node:$cc, node:$passthru, node:$mask, node:$vl),
                              (riscv_strict_fsetcc_vl node:$lhs, node:$rhs, node:$cc, node:$passthru, node:$mask, node:$vl)]>;
@@ -323,7 +376,8 @@ def any_riscv_fsetccs_vl : PatFrags<(ops node:$lhs, node:$rhs, node:$cc, node:$p
                             [(riscv_setcc_vl node:$lhs, node:$rhs, node:$cc, node:$passthru, node:$mask, node:$vl),
                              (riscv_strict_fsetccs_vl node:$lhs, node:$rhs, node:$cc, node:$passthru, node:$mask, node:$vl)]>;
 
-def riscv_vrgather_vx_vl : SDNode<"RISCVISD::VRGATHER_VX_VL",
+let HasMaskOp = true in {
+  def riscv_vrgather_vx_vl : RVSDNode<"VRGATHER_VX_VL",
                                   SDTypeProfile<1, 5, [SDTCisVec<0>,
                                                        SDTCisSameAs<0, 1>,
                                                        SDTCisVT<2, XLenVT>,
@@ -331,7 +385,7 @@ def riscv_vrgather_vx_vl : SDNode<"RISCVISD::VRGATHER_VX_VL",
                                                        SDTCVecEltisVT<4, i1>,
                                                        SDTCisSameNumEltsAs<0, 4>,
                                                        SDTCisVT<5, XLenVT>]>>;
-def riscv_vrgather_vv_vl : SDNode<"RISCVISD::VRGATHER_VV_VL",
+  def riscv_vrgather_vv_vl : RVSDNode<"VRGATHER_VV_VL",
                                   SDTypeProfile<1, 5, [SDTCisVec<0>,
                                                        SDTCisSameAs<0, 1>,
                                                        SDTCisInt<2>,
@@ -341,7 +395,7 @@ def riscv_vrgather_vv_vl : SDNode<"RISCVISD::VRGATHER_VV_VL",
                                                        SDTCVecEltisVT<4, i1>,
                                                        SDTCisSameNumEltsAs<0, 4>,
                                                        SDTCisVT<5, XLenVT>]>>;
-def riscv_vrgatherei16_vv_vl : SDNode<"RISCVISD::VRGATHEREI16_VV_VL",
+  def riscv_vrgatherei16_vv_vl : RVSDNode<"VRGATHEREI16_VV_VL",
                                       SDTypeProfile<1, 5, [SDTCisVec<0>,
                                                            SDTCisSameAs<0, 1>,
                                                            SDTCisInt<2>,
@@ -351,6 +405,7 @@ def riscv_vrgatherei16_vv_vl : SDNode<"RISCVISD::VRGATHEREI16_VV_VL",
                                                            SDTCVecEltisVT<4, i1>,
                                                            SDTCisSameNumEltsAs<0, 4>,
                                                            SDTCisVT<5, XLenVT>]>>;
+}
 
 def SDT_RISCVVMERGE_VL  : SDTypeProfile<1, 5, [
   SDTCisVec<0>, SDTCisVec<1>, SDTCisSameNumEltsAs<0, 1>, SDTCVecEltisVT<1, i1>,
@@ -358,47 +413,52 @@ def SDT_RISCVVMERGE_VL  : SDTypeProfile<1, 5, [
   SDTCisVT<5, XLenVT>
 ]>;
 
-def riscv_vmerge_vl : SDNode<"RISCVISD::VMERGE_VL", SDT_RISCVVMERGE_VL>;
+let HasPassthruOp = true in
+def riscv_vmerge_vl : RVSDNode<"VMERGE_VL", SDT_RISCVVMERGE_VL>;
 
 def SDT_RISCVVMSETCLR_VL : SDTypeProfile<1, 1, [SDTCVecEltisVT<0, i1>,
                                                 SDTCisVT<1, XLenVT>]>;
-def riscv_vmclr_vl : SDNode<"RISCVISD::VMCLR_VL", SDT_RISCVVMSETCLR_VL>;
-def riscv_vmset_vl : SDNode<"RISCVISD::VMSET_VL", SDT_RISCVVMSETCLR_VL>;
+def riscv_vmclr_vl : RVSDNode<"VMCLR_VL", SDT_RISCVVMSETCLR_VL>;
+def riscv_vmset_vl : RVSDNode<"VMSET_VL", SDT_RISCVVMSETCLR_VL>;
 
 def SDT_RISCVMaskBinOp_VL : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>,
                                                  SDTCisSameAs<0, 2>,
                                                  SDTCVecEltisVT<0, i1>,
                                                  SDTCisVT<3, XLenVT>]>;
-def riscv_vmand_vl : SDNode<"RISCVISD::VMAND_VL", SDT_RISCVMaskBinOp_VL, [SDNPCommutative]>;
-def riscv_vmor_vl  : SDNode<"RISCVISD::VMOR_VL",  SDT_RISCVMaskBinOp_VL, [SDNPCommutative]>;
-def riscv_vmxor_vl : SDNode<"RISCVISD::VMXOR_VL", SDT_RISCVMaskBinOp_VL, [SDNPCommutative]>;
+def riscv_vmand_vl : RVSDNode<"VMAND_VL", SDT_RISCVMaskBinOp_VL, [SDNPCommutative]>;
+def riscv_vmor_vl  : RVSDNode<"VMOR_VL",  SDT_RISCVMaskBinOp_VL, [SDNPCommutative]>;
+def riscv_vmxor_vl : RVSDNode<"VMXOR_VL", SDT_RISCVMaskBinOp_VL, [SDNPCommutative]>;
 
 def true_mask : PatLeaf<(riscv_vmset_vl (XLenVT srcvalue))>;
 
 def riscv_vmnot_vl : PatFrag<(ops node:$rs, node:$vl),
                              (riscv_vmxor_vl node:$rs, true_mask, node:$vl)>;
 
-def riscv_vcpop_vl : SDNode<"RISCVISD::VCPOP_VL",
+let HasMaskOp = true in {
+  def riscv_vcpop_vl : RVSDNode<"VCPOP_VL",
                             SDTypeProfile<1, 3, [SDTCisVT<0, XLenVT>,
                                                  SDTCisVec<1>, SDTCisInt<1>,
                                                  SDTCVecEltisVT<2, i1>,
                                                  SDTCisSameNumEltsAs<1, 2>,
                                                  SDTCisVT<3, XLenVT>]>>;
 
-def riscv_vfirst_vl : SDNode<"RISCVISD::VFIRST_VL",
+  def riscv_vfirst_vl : RVSDNode<"VFIRST_VL",
                             SDTypeProfile<1, 3, [SDTCisVT<0, XLenVT>,
                                                  SDTCisVec<1>, SDTCisInt<1>,
                                                  SDTCVecEltisVT<2, i1>,
                                                  SDTCisSameNumEltsAs<1, 2>,
                                                  SDTCisVT<3, XLenVT>]>>;
+}
 
 def SDT_RISCVVEXTEND_VL : SDTypeProfile<1, 3, [SDTCisVec<0>,
                                                SDTCisSameNumEltsAs<0, 1>,
                                                SDTCisSameNumEltsAs<1, 2>,
                                                SDTCVecEltisVT<2, i1>,
                                                SDTCisVT<3, XLenVT>]>;
-def riscv_sext_vl : SDNode<"RISCVISD::VSEXT_VL", SDT_RISCVVEXTEND_VL>;
-def riscv_zext_vl : SDNode<"RISCVISD::VZEXT_VL", SDT_RISCVVEXTEND_VL>;
+let HasMaskOp = true in {
+  def riscv_sext_vl : RVSDNode<"VSEXT_VL", SDT_RISCVVEXTEND_VL>;
+  def riscv_zext_vl : RVSDNode<"VZEXT_VL", SDT_RISCVVEXTEND_VL>;
+}
 def riscv_ext_vl : PatFrags<(ops node:$A, node:$B, node:$C),
                             [(riscv_sext_vl node:$A, node:$B, node:$C),
                              (riscv_zext_vl node:$A, node:$B, node:$C)]>;
@@ -408,12 +468,14 @@ def SDT_RISCVVTRUNCATE_VL : SDTypeProfile<1, 3, [SDTCisVec<0>,
                                                  SDTCisSameNumEltsAs<0, 2>,
                                                  SDTCVecEltisVT<2, i1>,
                                                  SDTCisVT<3, XLenVT>]>;
-def riscv_trunc_vector_vl : SDNode<"RISCVISD::TRUNCATE_VECTOR_VL",
-                                   SDT_RISCVVTRUNCATE_VL>;
-def riscv_trunc_vector_vl_ssat : SDNode<"RISCVISD::TRUNCATE_VECTOR_VL_SSAT",
-                                        SDT_RISCVVTRUNCATE_VL>;
-def riscv_trunc_vector_vl_usat : SDNode<"RISCVISD::TRUNCATE_VECTOR_VL_USAT",
-                                        SDT_RISCVVTRUNCATE_VL>;
+let HasMaskOp = true in {
+  def riscv_trunc_vector_vl : RVSDNode<"TRUNCATE_VECTOR_VL",
+                                     SDT_RISCVVTRUNCATE_VL>;
+  def riscv_trunc_vector_vl_ssat : RVSDNode<"TRUNCATE_VECTOR_VL_SSAT",
+                                          SDT_RISCVVTRUNCATE_VL>;
+  def riscv_trunc_vector_vl_usat : RVSDNode<"TRUNCATE_VECTOR_VL_USAT",
+                                          SDT_RISCVVTRUNCATE_VL>;
+}
 
 def SDT_RISCVVWIntBinOp_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisInt<0>,
                                                   SDTCisInt<1>,
@@ -424,14 +486,16 @@ def SDT_RISCVVWIntBinOp_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisInt<0>,
                                                   SDTCisSameNumEltsAs<1, 4>,
                                                   SDTCVecEltisVT<4, i1>,
                                                   SDTCisVT<5, XLenVT>]>;
-def riscv_vwmul_vl   : SDNode<"RISCVISD::VWMUL_VL",   SDT_RISCVVWIntBinOp_VL, [SDNPCommutative]>;
-def riscv_vwmulu_vl  : SDNode<"RISCVISD::VWMULU_VL",  SDT_RISCVVWIntBinOp_VL, [SDNPCommutative]>;
-def riscv_vwmulsu_vl : SDNode<"RISCVISD::VWMULSU_VL", SDT_RISCVVWIntBinOp_VL>;
-def riscv_vwadd_vl   : SDNode<"RISCVISD::VWADD_VL",   SDT_RISCVVWIntBinOp_VL, [SDNPCommutative]>;
-def riscv_vwaddu_vl  : SDNode<"RISCVISD::VWADDU_VL",  SDT_RISCVVWIntBinOp_VL, [SDNPCommutative]>;
-def riscv_vwsub_vl   : SDNode<"RISCVISD::VWSUB_VL",   SDT_RISCVVWIntBinOp_VL, []>;
-def riscv_vwsubu_vl  : SDNode<"RISCVISD::VWSUBU_VL",  SDT_RISCVVWIntBinOp_VL, []>;
-def riscv_vwsll_vl   : SDNode<"RISCVISD::VWSLL_VL",   SDT_RISCVVWIntBinOp_VL, []>;
+let HasPassthruOp = true, HasMaskOp = true in {
+  def riscv_vwmul_vl   : RVSDNode<"VWMUL_VL",   SDT_RISCVVWIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_vwmulu_vl  : RVSDNode<"VWMULU_VL",  SDT_RISCVVWIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_vwmulsu_vl : RVSDNode<"VWMULSU_VL", SDT_RISCVVWIntBinOp_VL>;
+  def riscv_vwadd_vl   : RVSDNode<"VWADD_VL",   SDT_RISCVVWIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_vwaddu_vl  : RVSDNode<"VWADDU_VL",  SDT_RISCVVWIntBinOp_VL, [SDNPCommutative]>;
+  def riscv_vwsub_vl   : RVSDNode<"VWSUB_VL",   SDT_RISCVVWIntBinOp_VL, []>;
+  def riscv_vwsubu_vl  : RVSDNode<"VWSUBU_VL",  SDT_RISCVVWIntBinOp_VL, []>;
+  def riscv_vwsll_vl   : RVSDNode<"VWSLL_VL",   SDT_RISCVVWIntBinOp_VL, []>;
+}
 
 def SDT_RISCVVWIntTernOp_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisInt<0>,
                                                    SDTCisInt<1>,
@@ -442,9 +506,12 @@ def SDT_RISCVVWIntTernOp_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisInt<0>,
                                                    SDTCisSameNumEltsAs<1, 4>,
                                                    SDTCVecEltisVT<4, i1>,
                                                    SDTCisVT<5, XLenVT>]>;
-def riscv_vwmacc_vl : SDNode<"RISCVISD::VWMACC_VL", SDT_RISCVVWIntTernOp_VL, [SDNPCommutative]>;
-def riscv_vwmaccu_vl : SDNode<"RISCVISD::VWMACCU_VL", SDT_RISCVVWIntTernOp_VL, [SDNPCommutative]>;
-def riscv_vwmaccsu_vl : SDNode<"RISCVISD::VWMACCSU_VL", SDT_RISCVVWIntTernOp_VL, []>;
+
+let HasMaskOp = true in {
+  def riscv_vwmacc_vl : RVSDNode<"VWMACC_VL", SDT_RISCVVWIntTernOp_VL, [SDNPCommutative]>;
+  def riscv_vwmaccu_vl : RVSDNode<"VWMACCU_VL", SDT_RISCVVWIntTernOp_VL, [SDNPCommutative]>;
+  def riscv_vwmaccsu_vl : RVSDNode<"VWMACCSU_VL", SDT_RISCVVWIntTernOp_VL, []>;
+}
 
 def SDT_RISCVVWFPBinOp_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisFP<0>,
                                                  SDTCisFP<1>,
@@ -455,9 +522,12 @@ def SDT_RISCVVWFPBinOp_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisFP<0>,
                                                  SDTCisSameNumEltsAs<1, 4>,
                                                  SDTCVecEltisVT<4, i1>,
                                                  SDTCisVT<5, XLenVT>]>;
-def riscv_vfwmul_vl : SDNode<"RISCVISD::VFWMUL_VL", SDT_RISCVVWFPBinOp_VL, [SDNPCommutative]>;
-def riscv_vfwadd_vl : SDNode<"RISCVISD::VFWADD_VL", SDT_RISCVVWFPBinOp_VL, [SDNPCommutative]>;
-def riscv_vfwsub_vl : SDNode<"RISCVISD::VFWSUB_VL", SDT_RISCVVWFPBinOp_VL, []>;
+
+let HasPassthruOp = true, HasMaskOp = true in {
+  def riscv_vfwmul_vl : RVSDNode<"VFWMUL_VL", SDT_RISCVVWFPBinOp_VL, [SDNPCommutative]>;
+  def riscv_vfwadd_vl : RVSDNode<"VFWADD_VL", SDT_RISCVVWFPBinOp_VL, [SDNPCommutative]>;
+  def riscv_vfwsub_vl : RVSDNode<"VFWSUB_VL", SDT_RISCVVWFPBinOp_VL, []>;
+}
 
 def SDT_RISCVVWIntBinOpW_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisInt<0>,
                                                    SDTCisSameAs<0, 1>,
@@ -468,10 +538,13 @@ def SDT_RISCVVWIntBinOpW_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisInt<0>,
                                                    SDTCisSameNumEltsAs<1, 4>,
                                                    SDTCVecEltisVT<4, i1>,
                                                    SDTCisVT<5, XLenVT>]>;
-def riscv_vwadd_w_vl :  SDNode<"RISCVISD::VWADD_W_VL",  SDT_RISCVVWIntBinOpW_VL>;
-def riscv_vwaddu_w_vl : SDNode<"RISCVISD::VWADDU_W_VL", SDT_RISCVVWIntBinOpW_VL>;
-def riscv_vwsub_w_vl :  SDNode<"RISCVISD::VWSUB_W_VL",  SDT_RISCVVWIntBinOpW_VL>;
-def riscv_vwsubu_w_vl : SDNode<"RISCVISD::VWSUBU_W_VL", SDT_RISCVVWIntBinOpW_VL>;
+
+let HasPassthruOp = true, HasMaskOp = true in {
+  def riscv_vwadd_w_vl  : RVSDNode<"VWADD_W_VL",  SDT_RISCVVWIntBinOpW_VL>;
+  def riscv_vwaddu_w_vl : RVSDNode<"VWADDU_W_VL", SDT_RISCVVWIntBinOpW_VL>;
+  def riscv_vwsub_w_vl  : RVSDNode<"VWSUB_W_VL",  SDT_RISCVVWIntBinOpW_VL>;
+  def riscv_vwsubu_w_vl : RVSDNode<"VWSUBU_W_VL", SDT_RISCVVWIntBinOpW_VL>;
+}
 
 def SDT_RISCVVWFPBinOpW_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisFP<0>,
                                                   SDTCisSameAs<0, 1>,
@@ -483,8 +556,10 @@ def SDT_RISCVVWFPBinOpW_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisFP<0>,
                                                   SDTCVecEltisVT<4, i1>,
                                                   SDTCisVT<5, XLenVT>]>;
 
-def riscv_vfwadd_w_vl :  SDNode<"RISCVISD::VFWADD_W_VL", SDT_RISCVVWFPBinOpW_VL>;
-def riscv_vfwsub_w_vl :  SDNode<"RISCVISD::VFWSUB_W_VL", SDT_RISCVVWFPBinOpW_VL>;
+let HasPassthruOp = true, HasMaskOp = true in {
+  def riscv_vfwadd_w_vl : RVSDNode<"VFWADD_W_VL", SDT_RISCVVWFPBinOpW_VL>;
+  def riscv_vfwsub_w_vl : RVSDNode<"VFWSUB_W_VL", SDT_RISCVVWFPBinOpW_VL>;
+}
 
 def SDTRVVVecReduce : SDTypeProfile<1, 6, [
   SDTCisVec<0>, SDTCisVec<1>, SDTCisVec<2>, SDTCisSameAs<0, 3>,
@@ -582,9 +657,10 @@ def riscv_vfnmsub_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D,
   return N->hasOneUse();
 }]>;
 
+let HasMaskOp = true in
 foreach kind = ["ADD", "UMAX", "SMAX", "UMIN", "SMIN", "AND", "OR", "XOR",
                 "FADD", "SEQ_FADD", "FMIN", "FMAX"] in
-  def rvv_vecreduce_#kind#_vl : SDNode<"RISCVISD::VECREDUCE_"#kind#"_VL", SDTRVVVecReduce>;
+  def rvv_vecreduce_#kind#_vl : RVSDNode<"VECREDUCE_"#kind#"_VL", SDTRVVVecReduce>;
 
 // Give explicit Complexity to prefer simm5/uimm5.
 def SplatPat       : ComplexPattern<vAny, 1, "selectVSplat",      [], [], 1>;
@@ -2905,7 +2981,8 @@ foreach vti = !listconcat(AllFloatVectors, AllBFloatVectors) in {
 // Miscellaneous RISCVISD SDNodes
 //===----------------------------------------------------------------------===//
 
-def riscv_vid_vl : SDNode<"RISCVISD::VID_VL", SDTypeProfile<1, 2,
+let HasMaskOp = true in
+def riscv_vid_vl : RVSDNode<"VID_VL", SDTypeProfile<1, 2,
                           [SDTCisVec<0>, SDTCVecEltisVT<1, i1>,
                            SDTCisSameNumEltsAs<0, 1>, SDTCisVT<2, XLenVT>]>, []>;
 
@@ -2925,12 +3002,14 @@ def SDTRVVFSlide1 : SDTypeProfile<1, 5, [
   SDTCisVT<5, XLenVT>
 ]>;
 
-def riscv_slideup_vl   : SDNode<"RISCVISD::VSLIDEUP_VL", SDTRVVSlide, []>;
-def riscv_slide1up_vl  : SDNode<"RISCVISD::VSLIDE1UP_VL", SDTRVVSlide1, []>;
-def riscv_slidedown_vl : SDNode<"RISCVISD::VSLIDEDOWN_VL", SDTRVVSlide, []>;
-def riscv_slide1down_vl  : SDNode<"RISCVISD::VSLIDE1DOWN_VL", SDTRVVSlide1, []>;
-def riscv_fslide1up_vl  : SDNode<"RISCVISD::VFSLIDE1UP_VL", SDTRVVFSlide1, []>;
-def riscv_fslide1down_vl  : SDNode<"RISCVISD::VFSLIDE1DOWN_VL", SDTRVVFSlide1, []>;
+let HasMaskOp = true in {
+  def riscv_slideup_vl     : RVSDNode<"VSLIDEUP_VL", SDTRVVSlide, []>;
+  def riscv_slide1up_vl    : RVSDNode<"VSLIDE1UP_VL", SDTRVVSlide1, []>;
+  def riscv_slidedown_vl   : RVSDNode<"VSLIDEDOWN_VL", SDTRVVSlide, []>;
+  def riscv_slide1down_vl  : RVSDNode<"VSLIDE1DOWN_VL", SDTRVVSlide1, []>;
+  def riscv_fslide1up_vl   : RVSDNode<"VFSLIDE1UP_VL", SDTRVVFSlide1, []>;
+  def riscv_fslide1down_vl : RVSDNode<"VFSLIDE1DOWN_VL", SDTRVVFSlide1, []>;
+}
 
 foreach vti = AllIntegerVectors in {
   let Predicates = GetVTypePredicates<vti>.Predicates in {
diff --git a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp
index 8f2c7a013ec228..6d9589202311b4 100644
--- a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp
@@ -7,29 +7,31 @@
 //===----------------------------------------------------------------------===//
 
 #include "RISCVSelectionDAGInfo.h"
-#include "RISCVISelLowering.h"
+
+#define GET_SDNODE_DESC
+#include "RISCVGenSDNodeInfo.inc"
 
 using namespace llvm;
 
+RISCVSelectionDAGInfo::RISCVSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(RISCVGenSDNodeInfo) {}
+
 RISCVSelectionDAGInfo::~RISCVSelectionDAGInfo() = default;
 
-bool RISCVSelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
+const char *RISCVSelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
+#define NODE_NAME_CASE(NODE)                                                   \
+  case RISCVISD::NODE:                                                         \
+    return "RISCVISD::" #NODE;
+
+  // These nodes don't have corresponding entries in *.td files yet.
   switch (static_cast<RISCVISD::NodeType>(Opcode)) {
-  default:
-    break;
-  case RISCVISD::TH_LWD:
-  case RISCVISD::TH_LWUD:
-  case RISCVISD::TH_LDD:
-  case RISCVISD::TH_SWD:
-  case RISCVISD::TH_SDD:
-    return true;
+    NODE_NAME_CASE(BuildGPRPair)
+    NODE_NAME_CASE(SplitGPRPair)
+    NODE_NAME_CASE(SPLAT_VECTOR_SPLIT_I64_VL)
+    NODE_NAME_CASE(TUPLE_INSERT)
+    NODE_NAME_CASE(TUPLE_EXTRACT)
   }
-  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
-}
+#undef NODE_NAME_CASE
 
-bool RISCVSelectionDAGInfo::isTargetStrictFPOpcode(unsigned Opcode) const {
-  if (Opcode >= RISCVISD::FIRST_STRICTFP_OPCODE &&
-      Opcode <= RISCVISD::LAST_STRICTFP_OPCODE)
-    return true;
-  return SelectionDAGTargetInfo::isTargetStrictFPOpcode(Opcode);
+  return SelectionDAGGenTargetInfo::getTargetNodeName(Opcode);
 }
diff --git a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h
index a64f1b27eda3da..dddba483d3d537 100644
--- a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h
@@ -11,15 +11,70 @@
 
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 
+#define GET_SDNODE_ENUM
+#include "RISCVGenSDNodeInfo.inc"
+
 namespace llvm {
+namespace RISCVISD {
+
+enum NodeType : unsigned {
+  /// Turn a pair of `i<xlen>`s into an even-odd register pair (`untyped`).
+  /// - Output: `untyped` even-odd register pair
+  /// - Input 0: `i<xlen>` low-order bits, for even register.
+  /// - Input 1: `i<xlen>` high-order bits, for odd register.
+  BuildGPRPair = GENERATED_OPCODE_END,
+
+  /// Turn an even-odd register pair (`untyped`) into a pair of `i<xlen>`s.
+  /// - Output 0: `i<xlen>` low-order bits, from even register.
+  /// - Output 1: `i<xlen>` high-order bits, from odd register.
+  /// - Input: `untyped` even-odd register pair
+  SplitGPRPair,
+
+  // Splats an 64-bit value that has been split into two i32 parts. This is
+  // expanded late to two scalar stores and a stride 0 vector load.
+  // The first operand is passthru operand.
+  SPLAT_VECTOR_SPLIT_I64_VL,
+
+  // RISC-V vector tuple type version of INSERT_SUBVECTOR/EXTRACT_SUBVECTOR.
+  TUPLE_INSERT,
+  TUPLE_EXTRACT,
+};
 
-class RISCVSelectionDAGInfo : public SelectionDAGTargetInfo {
+enum : unsigned {
+  HasPassthruOpMask = 1 << 0,
+  HasMaskOpMask = 1 << 1,
+};
+
+} // namespace RISCVISD
+
+class RISCVSelectionDAGInfo : public SelectionDAGGenTargetInfo {
 public:
+  RISCVSelectionDAGInfo();
+
   ~RISCVSelectionDAGInfo() override;
 
-  bool isTargetMemoryOpcode(unsigned Opcode) const override;
+  const char *getTargetNodeName(unsigned Opcode) const override;
+
+  bool hasPassthruOp(unsigned Opcode) const {
+    return GenNodeInfo.getDesc(Opcode).TSFlags & RISCVISD::HasPassthruOpMask;
+  }
+
+  bool hasMaskOp(unsigned Opcode) const {
+    return GenNodeInfo.getDesc(Opcode).TSFlags & RISCVISD::HasMaskOpMask;
+  }
 
-  bool isTargetStrictFPOpcode(unsigned Opcode) const override;
+  unsigned getMAccOpcode(unsigned MulOpcode) const {
+    switch (static_cast<RISCVISD::GenNodeType>(MulOpcode)) {
+    default:
+      llvm_unreachable("Unexpected opcode");
+    case RISCVISD::VWMUL_VL:
+      return RISCVISD::VWMACC_VL;
+    case RISCVISD::VWMULU_VL:
+      return RISCVISD::VWMACCU_VL;
+    case RISCVISD::VWMULSU_VL:
+      return RISCVISD::VWMACCSU_VL;
+    }
+  }
 };
 
 } // namespace llvm

>From 18f441178fb846169b9ccc9f0efe4f32ebf3bb00 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 03:11:32 +0300
Subject: [PATCH 20/27] Sparc

---
 llvm/lib/Target/Sparc/CMakeLists.txt          |  2 +
 llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp   |  1 +
 llvm/lib/Target/Sparc/SparcISelLowering.cpp   | 42 +-----------------
 llvm/lib/Target/Sparc/SparcISelLowering.h     | 43 -------------------
 .../Target/Sparc/SparcSelectionDAGInfo.cpp    | 28 ++++++++++++
 llvm/lib/Target/Sparc/SparcSelectionDAGInfo.h | 38 ++++++++++++++++
 llvm/lib/Target/Sparc/SparcSubtarget.cpp      | 11 ++++-
 llvm/lib/Target/Sparc/SparcSubtarget.h        | 10 ++---
 8 files changed, 85 insertions(+), 90 deletions(-)
 create mode 100644 llvm/lib/Target/Sparc/SparcSelectionDAGInfo.cpp
 create mode 100644 llvm/lib/Target/Sparc/SparcSelectionDAGInfo.h

diff --git a/llvm/lib/Target/Sparc/CMakeLists.txt b/llvm/lib/Target/Sparc/CMakeLists.txt
index bf76ed9d671b97..e9d78c50fc11e5 100644
--- a/llvm/lib/Target/Sparc/CMakeLists.txt
+++ b/llvm/lib/Target/Sparc/CMakeLists.txt
@@ -10,6 +10,7 @@ tablegen(LLVM SparcGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM SparcGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM SparcGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM SparcGenSDNodeInfo.inc -gen-sd-node-info -sdnode-namespace=SPISD)
 tablegen(LLVM SparcGenSearchableTables.inc -gen-searchable-tables)
 tablegen(LLVM SparcGenSubtargetInfo.inc -gen-subtarget)
 
@@ -25,6 +26,7 @@ add_llvm_target(SparcCodeGen
   SparcFrameLowering.cpp
   SparcMachineFunctionInfo.cpp
   SparcRegisterInfo.cpp
+  SparcSelectionDAGInfo.cpp
   SparcSubtarget.cpp
   SparcTargetMachine.cpp
   SparcMCInstLower.cpp
diff --git a/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp
index 461f859957041f..55bf40e185ff46 100644
--- a/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp
@@ -10,6 +10,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "SparcSelectionDAGInfo.h"
 #include "SparcTargetMachine.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
index 03a74b62543006..27bb3d2ced41ad 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -16,6 +16,7 @@
 #include "MCTargetDesc/SparcMCTargetDesc.h"
 #include "SparcMachineFunctionInfo.h"
 #include "SparcRegisterInfo.h"
+#include "SparcSelectionDAGInfo.h"
 #include "SparcTargetMachine.h"
 #include "SparcTargetObjectFile.h"
 #include "llvm/ADT/StringExtras.h"
@@ -1991,47 +1992,6 @@ bool SparcTargetLowering::useSoftFloat() const {
   return Subtarget->useSoftFloat();
 }
 
-const char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const {
-  switch ((SPISD::NodeType)Opcode) {
-  case SPISD::FIRST_NUMBER:    break;
-  case SPISD::CMPICC:          return "SPISD::CMPICC";
-  case SPISD::CMPFCC:          return "SPISD::CMPFCC";
-  case SPISD::CMPFCC_V9:
-    return "SPISD::CMPFCC_V9";
-  case SPISD::BRICC:           return "SPISD::BRICC";
-  case SPISD::BPICC:
-    return "SPISD::BPICC";
-  case SPISD::BPXCC:
-    return "SPISD::BPXCC";
-  case SPISD::BRFCC:           return "SPISD::BRFCC";
-  case SPISD::BRFCC_V9:
-    return "SPISD::BRFCC_V9";
-  case SPISD::BR_REG:
-    return "SPISD::BR_REG";
-  case SPISD::SELECT_ICC:      return "SPISD::SELECT_ICC";
-  case SPISD::SELECT_XCC:      return "SPISD::SELECT_XCC";
-  case SPISD::SELECT_FCC:      return "SPISD::SELECT_FCC";
-  case SPISD::SELECT_REG:
-    return "SPISD::SELECT_REG";
-  case SPISD::Hi:              return "SPISD::Hi";
-  case SPISD::Lo:              return "SPISD::Lo";
-  case SPISD::FTOI:            return "SPISD::FTOI";
-  case SPISD::ITOF:            return "SPISD::ITOF";
-  case SPISD::FTOX:            return "SPISD::FTOX";
-  case SPISD::XTOF:            return "SPISD::XTOF";
-  case SPISD::CALL:            return "SPISD::CALL";
-  case SPISD::RET_GLUE:        return "SPISD::RET_GLUE";
-  case SPISD::GLOBAL_BASE_REG: return "SPISD::GLOBAL_BASE_REG";
-  case SPISD::FLUSHW:          return "SPISD::FLUSHW";
-  case SPISD::TLS_ADD:         return "SPISD::TLS_ADD";
-  case SPISD::TLS_LD:          return "SPISD::TLS_LD";
-  case SPISD::TLS_CALL:        return "SPISD::TLS_CALL";
-  case SPISD::TAIL_CALL:       return "SPISD::TAIL_CALL";
-  case SPISD::LOAD_GDOP:       return "SPISD::LOAD_GDOP";
-  }
-  return nullptr;
-}
-
 EVT SparcTargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &,
                                             EVT VT) const {
   if (!VT.isVector())
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.h b/llvm/lib/Target/Sparc/SparcISelLowering.h
index cc672074a4be80..2445c5e0e6f34a 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.h
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.h
@@ -20,47 +20,6 @@
 namespace llvm {
   class SparcSubtarget;
 
-  namespace SPISD {
-  enum NodeType : unsigned {
-    FIRST_NUMBER = ISD::BUILTIN_OP_END,
-    CMPICC,    // Compare two GPR operands, set icc+xcc.
-    CMPFCC,    // Compare two FP operands, set fcc.
-    CMPFCC_V9, // Compare two FP operands, set fcc (v9 variant).
-    BRICC,     // Branch to dest on icc condition
-    BPICC,    // Branch to dest on icc condition, with prediction (64-bit only).
-    BPXCC,    // Branch to dest on xcc condition, with prediction (64-bit only).
-    BRFCC,    // Branch to dest on fcc condition
-    BRFCC_V9, // Branch to dest on fcc condition (v9 variant).
-    BR_REG,   // Branch to dest using the comparison of a register with zero.
-    SELECT_ICC, // Select between two values using the current ICC flags.
-    SELECT_XCC, // Select between two values using the current XCC flags.
-    SELECT_FCC, // Select between two values using the current FCC flags.
-    SELECT_REG, // Select between two values using the comparison of a register
-                // with zero.
-
-    Hi,
-    Lo, // Hi/Lo operations, typically on a global address.
-
-    FTOI, // FP to Int within a FP register.
-    ITOF, // Int to FP within a FP register.
-    FTOX, // FP to Int64 within a FP register.
-    XTOF, // Int64 to FP within a FP register.
-
-    CALL,            // A call instruction.
-    RET_GLUE,        // Return with a glue operand.
-    GLOBAL_BASE_REG, // Global base reg for PIC.
-    FLUSHW,          // FLUSH register windows to stack.
-
-    TAIL_CALL, // Tail call
-
-    TLS_ADD, // For Thread Local Storage (TLS).
-    TLS_LD,
-    TLS_CALL,
-
-    LOAD_GDOP, // Load operation w/ gdop relocation.
-  };
-  }
-
   class SparcTargetLowering : public TargetLowering {
     const SparcSubtarget *Subtarget;
   public:
@@ -82,8 +41,6 @@ namespace llvm {
     EmitInstrWithCustomInserter(MachineInstr &MI,
                                 MachineBasicBlock *MBB) const override;
 
-    const char *getTargetNodeName(unsigned Opcode) const override;
-
     ConstraintType getConstraintType(StringRef Constraint) const override;
     ConstraintWeight
     getSingleConstraintMatchWeight(AsmOperandInfo &info,
diff --git a/llvm/lib/Target/Sparc/SparcSelectionDAGInfo.cpp b/llvm/lib/Target/Sparc/SparcSelectionDAGInfo.cpp
new file mode 100644
index 00000000000000..b52c5f0cc7f91a
--- /dev/null
+++ b/llvm/lib/Target/Sparc/SparcSelectionDAGInfo.cpp
@@ -0,0 +1,28 @@
+//===- SparcSelectionDAGInfo.cpp ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "SparcSelectionDAGInfo.h"
+
+#define GET_SDNODE_DESC
+#include "SparcGenSDNodeInfo.inc"
+
+using namespace llvm;
+
+SparcSelectionDAGInfo::SparcSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(SparcGenSDNodeInfo) {}
+
+SparcSelectionDAGInfo::~SparcSelectionDAGInfo() = default;
+
+const char *SparcSelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
+  switch (static_cast<SPISD::NodeType>(Opcode)) {
+  case SPISD::GLOBAL_BASE_REG:
+    return "SPISD::GLOBAL_BASE_REG";
+  }
+
+  return SelectionDAGGenTargetInfo::getTargetNodeName(Opcode);
+}
diff --git a/llvm/lib/Target/Sparc/SparcSelectionDAGInfo.h b/llvm/lib/Target/Sparc/SparcSelectionDAGInfo.h
new file mode 100644
index 00000000000000..3a8021f8544a6e
--- /dev/null
+++ b/llvm/lib/Target/Sparc/SparcSelectionDAGInfo.h
@@ -0,0 +1,38 @@
+//===- SparcSelectionDAGInfo.h ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_SPARC_SPARCSELECTIONDAGINFO_H
+#define LLVM_LIB_TARGET_SPARC_SPARCSELECTIONDAGINFO_H
+
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+
+#define GET_SDNODE_ENUM
+#include "SparcGenSDNodeInfo.inc"
+
+namespace llvm {
+namespace SPISD {
+
+enum NodeType : unsigned {
+  // Global base reg for PIC.
+  GLOBAL_BASE_REG = GENERATED_OPCODE_END,
+};
+
+} // namespace SPISD
+
+class SparcSelectionDAGInfo : public SelectionDAGGenTargetInfo {
+public:
+  SparcSelectionDAGInfo();
+
+  ~SparcSelectionDAGInfo() override;
+
+  const char *getTargetNodeName(unsigned Opcode) const override;
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_SPARC_SPARCSELECTIONDAGINFO_H
diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.cpp b/llvm/lib/Target/Sparc/SparcSubtarget.cpp
index 3ccb742981ea5f..e42df1d68613b7 100644
--- a/llvm/lib/Target/Sparc/SparcSubtarget.cpp
+++ b/llvm/lib/Target/Sparc/SparcSubtarget.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "SparcSubtarget.h"
+#include "SparcSelectionDAGInfo.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/MC/TargetRegistry.h"
 #include "llvm/Support/MathExtras.h"
@@ -52,7 +53,15 @@ SparcSubtarget::SparcSubtarget(const StringRef &CPU, const StringRef &TuneCPU,
       ReserveRegister(TM.getMCRegisterInfo()->getNumRegs()),
       TargetTriple(TM.getTargetTriple()), Is64Bit(is64Bit),
       InstrInfo(initializeSubtargetDependencies(CPU, TuneCPU, FS)),
-      TLInfo(TM, *this), FrameLowering(*this) {}
+      TLInfo(TM, *this), FrameLowering(*this) {
+  TSInfo = std::make_unique<SparcSelectionDAGInfo>();
+}
+
+SparcSubtarget::~SparcSubtarget() = default;
+
+const SelectionDAGTargetInfo *SparcSubtarget::getSelectionDAGInfo() const {
+  return TSInfo.get();
+}
 
 int SparcSubtarget::getAdjustedFrameSize(int frameSize) const {
 
diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.h b/llvm/lib/Target/Sparc/SparcSubtarget.h
index fe4aca5195306a..5785c199f44b5d 100644
--- a/llvm/lib/Target/Sparc/SparcSubtarget.h
+++ b/llvm/lib/Target/Sparc/SparcSubtarget.h
@@ -17,7 +17,6 @@
 #include "SparcFrameLowering.h"
 #include "SparcISelLowering.h"
 #include "SparcInstrInfo.h"
-#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -46,13 +45,15 @@ class SparcSubtarget : public SparcGenSubtargetInfo {
 
   SparcInstrInfo InstrInfo;
   SparcTargetLowering TLInfo;
-  SelectionDAGTargetInfo TSInfo;
+  std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
   SparcFrameLowering FrameLowering;
 
 public:
   SparcSubtarget(const StringRef &CPU, const StringRef &TuneCPU,
                  const StringRef &FS, const TargetMachine &TM, bool is64bit);
 
+  ~SparcSubtarget() override;
+
   const SparcInstrInfo *getInstrInfo() const override { return &InstrInfo; }
   const TargetFrameLowering *getFrameLowering() const override {
     return &FrameLowering;
@@ -63,9 +64,8 @@ class SparcSubtarget : public SparcGenSubtargetInfo {
   const SparcTargetLowering *getTargetLowering() const override {
     return &TLInfo;
   }
-  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
-    return &TSInfo;
-  }
+
+  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
 
   bool enableMachineScheduler() const override;
 

>From d0e9e1a079b974c47564ee284527c0db63036051 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 01:02:30 +0300
Subject: [PATCH 21/27] SystemZ

---
 llvm/lib/Target/SystemZ/CMakeLists.txt        |   1 +
 .../Target/SystemZ/SystemZISelLowering.cpp    | 139 -------
 llvm/lib/Target/SystemZ/SystemZISelLowering.h | 373 ------------------
 llvm/lib/Target/SystemZ/SystemZOperators.td   |  47 ++-
 .../SystemZ/SystemZSelectionDAGInfo.cpp       |  32 +-
 .../Target/SystemZ/SystemZSelectionDAGInfo.h  |  29 +-
 6 files changed, 64 insertions(+), 557 deletions(-)

diff --git a/llvm/lib/Target/SystemZ/CMakeLists.txt b/llvm/lib/Target/SystemZ/CMakeLists.txt
index 0d8f3eac6ee4f4..6d94a755322df5 100644
--- a/llvm/lib/Target/SystemZ/CMakeLists.txt
+++ b/llvm/lib/Target/SystemZ/CMakeLists.txt
@@ -11,6 +11,7 @@ tablegen(LLVM SystemZGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM SystemZGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM SystemZGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM SystemZGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM SystemZGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM SystemZGenSubtargetInfo.inc -gen-subtarget)
 
 add_public_tablegen_target(SystemZCommonTableGen)
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index becc3936eef894..5147789a1ac7ae 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -6670,145 +6670,6 @@ SystemZTargetLowering::ReplaceNodeResults(SDNode *N,
   return LowerOperationWrapper(N, Results, DAG);
 }
 
-const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const {
-#define OPCODE(NAME) case SystemZISD::NAME: return "SystemZISD::" #NAME
-  switch ((SystemZISD::NodeType)Opcode) {
-    case SystemZISD::FIRST_NUMBER: break;
-    OPCODE(RET_GLUE);
-    OPCODE(CALL);
-    OPCODE(SIBCALL);
-    OPCODE(TLS_GDCALL);
-    OPCODE(TLS_LDCALL);
-    OPCODE(PCREL_WRAPPER);
-    OPCODE(PCREL_OFFSET);
-    OPCODE(ICMP);
-    OPCODE(FCMP);
-    OPCODE(STRICT_FCMP);
-    OPCODE(STRICT_FCMPS);
-    OPCODE(TM);
-    OPCODE(BR_CCMASK);
-    OPCODE(SELECT_CCMASK);
-    OPCODE(ADJDYNALLOC);
-    OPCODE(PROBED_ALLOCA);
-    OPCODE(POPCNT);
-    OPCODE(SMUL_LOHI);
-    OPCODE(UMUL_LOHI);
-    OPCODE(SDIVREM);
-    OPCODE(UDIVREM);
-    OPCODE(SADDO);
-    OPCODE(SSUBO);
-    OPCODE(UADDO);
-    OPCODE(USUBO);
-    OPCODE(ADDCARRY);
-    OPCODE(SUBCARRY);
-    OPCODE(GET_CCMASK);
-    OPCODE(MVC);
-    OPCODE(NC);
-    OPCODE(OC);
-    OPCODE(XC);
-    OPCODE(CLC);
-    OPCODE(MEMSET_MVC);
-    OPCODE(STPCPY);
-    OPCODE(STRCMP);
-    OPCODE(SEARCH_STRING);
-    OPCODE(IPM);
-    OPCODE(TBEGIN);
-    OPCODE(TBEGIN_NOFLOAT);
-    OPCODE(TEND);
-    OPCODE(BYTE_MASK);
-    OPCODE(ROTATE_MASK);
-    OPCODE(REPLICATE);
-    OPCODE(JOIN_DWORDS);
-    OPCODE(SPLAT);
-    OPCODE(MERGE_HIGH);
-    OPCODE(MERGE_LOW);
-    OPCODE(SHL_DOUBLE);
-    OPCODE(PERMUTE_DWORDS);
-    OPCODE(PERMUTE);
-    OPCODE(PACK);
-    OPCODE(PACKS_CC);
-    OPCODE(PACKLS_CC);
-    OPCODE(UNPACK_HIGH);
-    OPCODE(UNPACKL_HIGH);
-    OPCODE(UNPACK_LOW);
-    OPCODE(UNPACKL_LOW);
-    OPCODE(VSHL_BY_SCALAR);
-    OPCODE(VSRL_BY_SCALAR);
-    OPCODE(VSRA_BY_SCALAR);
-    OPCODE(VROTL_BY_SCALAR);
-    OPCODE(VSUM);
-    OPCODE(VACC);
-    OPCODE(VSCBI);
-    OPCODE(VAC);
-    OPCODE(VSBI);
-    OPCODE(VACCC);
-    OPCODE(VSBCBI);
-    OPCODE(VICMPE);
-    OPCODE(VICMPH);
-    OPCODE(VICMPHL);
-    OPCODE(VICMPES);
-    OPCODE(VICMPHS);
-    OPCODE(VICMPHLS);
-    OPCODE(VFCMPE);
-    OPCODE(STRICT_VFCMPE);
-    OPCODE(STRICT_VFCMPES);
-    OPCODE(VFCMPH);
-    OPCODE(STRICT_VFCMPH);
-    OPCODE(STRICT_VFCMPHS);
-    OPCODE(VFCMPHE);
-    OPCODE(STRICT_VFCMPHE);
-    OPCODE(STRICT_VFCMPHES);
-    OPCODE(VFCMPES);
-    OPCODE(VFCMPHS);
-    OPCODE(VFCMPHES);
-    OPCODE(VFTCI);
-    OPCODE(VEXTEND);
-    OPCODE(STRICT_VEXTEND);
-    OPCODE(VROUND);
-    OPCODE(STRICT_VROUND);
-    OPCODE(VTM);
-    OPCODE(SCMP128HI);
-    OPCODE(UCMP128HI);
-    OPCODE(VFAE_CC);
-    OPCODE(VFAEZ_CC);
-    OPCODE(VFEE_CC);
-    OPCODE(VFEEZ_CC);
-    OPCODE(VFENE_CC);
-    OPCODE(VFENEZ_CC);
-    OPCODE(VISTR_CC);
-    OPCODE(VSTRC_CC);
-    OPCODE(VSTRCZ_CC);
-    OPCODE(VSTRS_CC);
-    OPCODE(VSTRSZ_CC);
-    OPCODE(TDC);
-    OPCODE(ATOMIC_SWAPW);
-    OPCODE(ATOMIC_LOADW_ADD);
-    OPCODE(ATOMIC_LOADW_SUB);
-    OPCODE(ATOMIC_LOADW_AND);
-    OPCODE(ATOMIC_LOADW_OR);
-    OPCODE(ATOMIC_LOADW_XOR);
-    OPCODE(ATOMIC_LOADW_NAND);
-    OPCODE(ATOMIC_LOADW_MIN);
-    OPCODE(ATOMIC_LOADW_MAX);
-    OPCODE(ATOMIC_LOADW_UMIN);
-    OPCODE(ATOMIC_LOADW_UMAX);
-    OPCODE(ATOMIC_CMP_SWAPW);
-    OPCODE(ATOMIC_CMP_SWAP);
-    OPCODE(ATOMIC_LOAD_128);
-    OPCODE(ATOMIC_STORE_128);
-    OPCODE(ATOMIC_CMP_SWAP_128);
-    OPCODE(LRV);
-    OPCODE(STRV);
-    OPCODE(VLER);
-    OPCODE(VSTER);
-    OPCODE(STCKF);
-    OPCODE(PREFETCH);
-    OPCODE(ADA_ENTRY);
-  }
-  return nullptr;
-#undef OPCODE
-}
-
 // Return true if VT is a vector whose elements are a whole number of bytes
 // in width. Also check for presence of vector support.
 bool SystemZTargetLowering::canTreatAsByteVector(EVT VT) const {
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
index 4f418eceef8bbe..d72a0319f068e6 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
@@ -22,378 +22,6 @@
 #include <optional>
 
 namespace llvm {
-namespace SystemZISD {
-enum NodeType : unsigned {
-  FIRST_NUMBER = ISD::BUILTIN_OP_END,
-
-  // Return with a glue operand.  Operand 0 is the chain operand.
-  RET_GLUE,
-
-  // Calls a function.  Operand 0 is the chain operand and operand 1
-  // is the target address.  The arguments start at operand 2.
-  // There is an optional glue operand at the end.
-  CALL,
-  SIBCALL,
-
-  // TLS calls.  Like regular calls, except operand 1 is the TLS symbol.
-  // (The call target is implicitly __tls_get_offset.)
-  TLS_GDCALL,
-  TLS_LDCALL,
-
-  // Wraps a TargetGlobalAddress that should be loaded using PC-relative
-  // accesses (LARL).  Operand 0 is the address.
-  PCREL_WRAPPER,
-
-  // Used in cases where an offset is applied to a TargetGlobalAddress.
-  // Operand 0 is the full TargetGlobalAddress and operand 1 is a
-  // PCREL_WRAPPER for an anchor point.  This is used so that we can
-  // cheaply refer to either the full address or the anchor point
-  // as a register base.
-  PCREL_OFFSET,
-
-  // Integer comparisons.  There are three operands: the two values
-  // to compare, and an integer of type SystemZICMP.
-  ICMP,
-
-  // Floating-point comparisons.  The two operands are the values to compare.
-  FCMP,
-
-  // Test under mask.  The first operand is ANDed with the second operand
-  // and the condition codes are set on the result.  The third operand is
-  // a boolean that is true if the condition codes need to distinguish
-  // between CCMASK_TM_MIXED_MSB_0 and CCMASK_TM_MIXED_MSB_1 (which the
-  // register forms do but the memory forms don't).
-  TM,
-
-  // Branches if a condition is true.  Operand 0 is the chain operand;
-  // operand 1 is the 4-bit condition-code mask, with bit N in
-  // big-endian order meaning "branch if CC=N"; operand 2 is the
-  // target block and operand 3 is the flag operand.
-  BR_CCMASK,
-
-  // Selects between operand 0 and operand 1.  Operand 2 is the
-  // mask of condition-code values for which operand 0 should be
-  // chosen over operand 1; it has the same form as BR_CCMASK.
-  // Operand 3 is the flag operand.
-  SELECT_CCMASK,
-
-  // Evaluates to the gap between the stack pointer and the
-  // base of the dynamically-allocatable area.
-  ADJDYNALLOC,
-
-  // For allocating stack space when using stack clash protector.
-  // Allocation is performed by block, and each block is probed.
-  PROBED_ALLOCA,
-
-  // Count number of bits set in operand 0 per byte.
-  POPCNT,
-
-  // Wrappers around the ISD opcodes of the same name.  The output is GR128.
-  // Input operands may be GR64 or GR32, depending on the instruction.
-  SMUL_LOHI,
-  UMUL_LOHI,
-  SDIVREM,
-  UDIVREM,
-
-  // Add/subtract with overflow/carry.  These have the same operands as
-  // the corresponding standard operations, except with the carry flag
-  // replaced by a condition code value.
-  SADDO, SSUBO, UADDO, USUBO, ADDCARRY, SUBCARRY,
-
-  // Set the condition code from a boolean value in operand 0.
-  // Operand 1 is a mask of all condition-code values that may result of this
-  // operation, operand 2 is a mask of condition-code values that may result
-  // if the boolean is true.
-  // Note that this operation is always optimized away, we will never
-  // generate any code for it.
-  GET_CCMASK,
-
-  // Use a series of MVCs to copy bytes from one memory location to another.
-  // The operands are:
-  // - the target address
-  // - the source address
-  // - the constant length
-  //
-  // This isn't a memory opcode because we'd need to attach two
-  // MachineMemOperands rather than one.
-  MVC,
-
-  // Similar to MVC, but for logic operations (AND, OR, XOR).
-  NC,
-  OC,
-  XC,
-
-  // Use CLC to compare two blocks of memory, with the same comments
-  // as for MVC.
-  CLC,
-
-  // Use MVC to set a block of memory after storing the first byte.
-  MEMSET_MVC,
-
-  // Use an MVST-based sequence to implement stpcpy().
-  STPCPY,
-
-  // Use a CLST-based sequence to implement strcmp().  The two input operands
-  // are the addresses of the strings to compare.
-  STRCMP,
-
-  // Use an SRST-based sequence to search a block of memory.  The first
-  // operand is the end address, the second is the start, and the third
-  // is the character to search for.  CC is set to 1 on success and 2
-  // on failure.
-  SEARCH_STRING,
-
-  // Store the CC value in bits 29 and 28 of an integer.
-  IPM,
-
-  // Transaction begin.  The first operand is the chain, the second
-  // the TDB pointer, and the third the immediate control field.
-  // Returns CC value and chain.
-  TBEGIN,
-  TBEGIN_NOFLOAT,
-
-  // Transaction end.  Just the chain operand.  Returns CC value and chain.
-  TEND,
-
-  // Create a vector constant by filling byte N of the result with bit
-  // 15-N of the single operand.
-  BYTE_MASK,
-
-  // Create a vector constant by replicating an element-sized RISBG-style mask.
-  // The first operand specifies the starting set bit and the second operand
-  // specifies the ending set bit.  Both operands count from the MSB of the
-  // element.
-  ROTATE_MASK,
-
-  // Replicate a GPR scalar value into all elements of a vector.
-  REPLICATE,
-
-  // Create a vector from two i64 GPRs.
-  JOIN_DWORDS,
-
-  // Replicate one element of a vector into all elements.  The first operand
-  // is the vector and the second is the index of the element to replicate.
-  SPLAT,
-
-  // Interleave elements from the high half of operand 0 and the high half
-  // of operand 1.
-  MERGE_HIGH,
-
-  // Likewise for the low halves.
-  MERGE_LOW,
-
-  // Concatenate the vectors in the first two operands, shift them left
-  // by the third operand, and take the first half of the result.
-  SHL_DOUBLE,
-
-  // Take one element of the first v2i64 operand and the one element of
-  // the second v2i64 operand and concatenate them to form a v2i64 result.
-  // The third operand is a 4-bit value of the form 0A0B, where A and B
-  // are the element selectors for the first operand and second operands
-  // respectively.
-  PERMUTE_DWORDS,
-
-  // Perform a general vector permute on vector operands 0 and 1.
-  // Each byte of operand 2 controls the corresponding byte of the result,
-  // in the same way as a byte-level VECTOR_SHUFFLE mask.
-  PERMUTE,
-
-  // Pack vector operands 0 and 1 into a single vector with half-sized elements.
-  PACK,
-
-  // Likewise, but saturate the result and set CC.  PACKS_CC does signed
-  // saturation and PACKLS_CC does unsigned saturation.
-  PACKS_CC,
-  PACKLS_CC,
-
-  // Unpack the first half of vector operand 0 into double-sized elements.
-  // UNPACK_HIGH sign-extends and UNPACKL_HIGH zero-extends.
-  UNPACK_HIGH,
-  UNPACKL_HIGH,
-
-  // Likewise for the second half.
-  UNPACK_LOW,
-  UNPACKL_LOW,
-
-  // Shift/rotate each element of vector operand 0 by the number of bits
-  // specified by scalar operand 1.
-  VSHL_BY_SCALAR,
-  VSRL_BY_SCALAR,
-  VSRA_BY_SCALAR,
-  VROTL_BY_SCALAR,
-
-  // For each element of the output type, sum across all sub-elements of
-  // operand 0 belonging to the corresponding element, and add in the
-  // rightmost sub-element of the corresponding element of operand 1.
-  VSUM,
-
-  // Compute carry/borrow indication for add/subtract.
-  VACC, VSCBI,
-  // Add/subtract with carry/borrow.
-  VAC, VSBI,
-  // Compute carry/borrow indication for add/subtract with carry/borrow.
-  VACCC, VSBCBI,
-
-  // Compare integer vector operands 0 and 1 to produce the usual 0/-1
-  // vector result.  VICMPE is for equality, VICMPH for "signed greater than"
-  // and VICMPHL for "unsigned greater than".
-  VICMPE,
-  VICMPH,
-  VICMPHL,
-
-  // Likewise, but also set the condition codes on the result.
-  VICMPES,
-  VICMPHS,
-  VICMPHLS,
-
-  // Compare floating-point vector operands 0 and 1 to produce the usual 0/-1
-  // vector result.  VFCMPE is for "ordered and equal", VFCMPH for "ordered and
-  // greater than" and VFCMPHE for "ordered and greater than or equal to".
-  VFCMPE,
-  VFCMPH,
-  VFCMPHE,
-
-  // Likewise, but also set the condition codes on the result.
-  VFCMPES,
-  VFCMPHS,
-  VFCMPHES,
-
-  // Test floating-point data class for vectors.
-  VFTCI,
-
-  // Extend the even f32 elements of vector operand 0 to produce a vector
-  // of f64 elements.
-  VEXTEND,
-
-  // Round the f64 elements of vector operand 0 to f32s and store them in the
-  // even elements of the result.
-  VROUND,
-
-  // AND the two vector operands together and set CC based on the result.
-  VTM,
-
-  // i128 high integer comparisons.
-  SCMP128HI,
-  UCMP128HI,
-
-  // String operations that set CC as a side-effect.
-  VFAE_CC,
-  VFAEZ_CC,
-  VFEE_CC,
-  VFEEZ_CC,
-  VFENE_CC,
-  VFENEZ_CC,
-  VISTR_CC,
-  VSTRC_CC,
-  VSTRCZ_CC,
-  VSTRS_CC,
-  VSTRSZ_CC,
-
-  // Test Data Class.
-  //
-  // Operand 0: the value to test
-  // Operand 1: the bit mask
-  TDC,
-
-  // z/OS XPLINK ADA Entry
-  // Wraps a TargetGlobalAddress that should be loaded from a function's
-  // AssociatedData Area (ADA). Tha ADA is passed to the function by the
-  // caller in the XPLink ABI defined register R5.
-  // Operand 0: the GlobalValue/External Symbol
-  // Operand 1: the ADA register
-  // Operand 2: the offset (0 for the first and 8 for the second element in the
-  // function descriptor)
-  ADA_ENTRY,
-
-  // Strict variants of scalar floating-point comparisons.
-  // Quiet and signaling versions.
-  STRICT_FCMP,
-  STRICT_FCMPS,
-
-  // Strict variants of vector floating-point comparisons.
-  // Quiet and signaling versions.
-  STRICT_VFCMPE,
-  STRICT_VFCMPH,
-  STRICT_VFCMPHE,
-  STRICT_VFCMPES,
-  STRICT_VFCMPHS,
-  STRICT_VFCMPHES,
-
-  // Strict variants of VEXTEND and VROUND.
-  STRICT_VEXTEND,
-  STRICT_VROUND,
-
-  // Wrappers around the inner loop of an 8- or 16-bit ATOMIC_SWAP or
-  // ATOMIC_LOAD_<op>.
-  //
-  // Operand 0: the address of the containing 32-bit-aligned field
-  // Operand 1: the second operand of <op>, in the high bits of an i32
-  //            for everything except ATOMIC_SWAPW
-  // Operand 2: how many bits to rotate the i32 left to bring the first
-  //            operand into the high bits
-  // Operand 3: the negative of operand 2, for rotating the other way
-  // Operand 4: the width of the field in bits (8 or 16)
-  FIRST_MEMORY_OPCODE,
-  ATOMIC_SWAPW = FIRST_MEMORY_OPCODE,
-  ATOMIC_LOADW_ADD,
-  ATOMIC_LOADW_SUB,
-  ATOMIC_LOADW_AND,
-  ATOMIC_LOADW_OR,
-  ATOMIC_LOADW_XOR,
-  ATOMIC_LOADW_NAND,
-  ATOMIC_LOADW_MIN,
-  ATOMIC_LOADW_MAX,
-  ATOMIC_LOADW_UMIN,
-  ATOMIC_LOADW_UMAX,
-
-  // A wrapper around the inner loop of an ATOMIC_CMP_SWAP.
-  //
-  // Operand 0: the address of the containing 32-bit-aligned field
-  // Operand 1: the compare value, in the low bits of an i32
-  // Operand 2: the swap value, in the low bits of an i32
-  // Operand 3: how many bits to rotate the i32 left to bring the first
-  //            operand into the high bits
-  // Operand 4: the negative of operand 2, for rotating the other way
-  // Operand 5: the width of the field in bits (8 or 16)
-  ATOMIC_CMP_SWAPW,
-
-  // Atomic compare-and-swap returning CC value.
-  // Val, CC, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap)
-  ATOMIC_CMP_SWAP,
-
-  // 128-bit atomic load.
-  // Val, OUTCHAIN = ATOMIC_LOAD_128(INCHAIN, ptr)
-  ATOMIC_LOAD_128,
-
-  // 128-bit atomic store.
-  // OUTCHAIN = ATOMIC_STORE_128(INCHAIN, val, ptr)
-  ATOMIC_STORE_128,
-
-  // 128-bit atomic compare-and-swap.
-  // Val, CC, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap)
-  ATOMIC_CMP_SWAP_128,
-
-  // Byte swapping load/store.  Same operands as regular load/store.
-  LRV, STRV,
-
-  // Element swapping load/store.  Same operands as regular load/store.
-  VLER, VSTER,
-
-  // Use STORE CLOCK FAST to store current TOD clock value.
-  STCKF,
-
-  // Prefetch from the second operand using the 4-bit control code in
-  // the first operand.  The code is 1 for a load prefetch and 2 for
-  // a store prefetch.
-  PREFETCH,
-  LAST_MEMORY_OPCODE = PREFETCH,
-};
-
-// Return true if OPCODE is some kind of PC-relative address.
-inline bool isPCREL(unsigned Opcode) {
-  return Opcode == PCREL_WRAPPER || Opcode == PCREL_OFFSET;
-}
-} // end namespace SystemZISD
 
 namespace SystemZICMP {
 // Describes whether an integer comparison needs to be signed or unsigned,
@@ -517,7 +145,6 @@ class SystemZTargetLowering : public TargetLowering {
 
   bool shouldExpandCmpUsingSelects(EVT VT) const override { return true; }
 
-  const char *getTargetNodeName(unsigned Opcode) const override;
   std::pair<unsigned, const TargetRegisterClass *>
   getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
                                StringRef Constraint, MVT VT) const override;
diff --git a/llvm/lib/Target/SystemZ/SystemZOperators.td b/llvm/lib/Target/SystemZ/SystemZOperators.td
index 6439c82d26ff5c..00025043d82340 100644
--- a/llvm/lib/Target/SystemZ/SystemZOperators.td
+++ b/llvm/lib/Target/SystemZ/SystemZOperators.td
@@ -276,10 +276,14 @@ def z_pcrel_offset      : SDNode<"SystemZISD::PCREL_OFFSET",
                                  SDT_ZWrapOffset, []>;
 def z_icmp              : SDNode<"SystemZISD::ICMP", SDT_ZICmp>;
 def z_fcmp              : SDNode<"SystemZISD::FCMP", SDT_ZCmp>;
-def z_strict_fcmp       : SDNode<"SystemZISD::STRICT_FCMP", SDT_ZCmp,
-                                 [SDNPHasChain]>;
-def z_strict_fcmps      : SDNode<"SystemZISD::STRICT_FCMPS", SDT_ZCmp,
-                                 [SDNPHasChain]>;
+
+let IsStrictFP = true in {
+  def z_strict_fcmp : SDNode<"SystemZISD::STRICT_FCMP", SDT_ZCmp,
+                             [SDNPHasChain]>;
+  def z_strict_fcmps : SDNode<"SystemZISD::STRICT_FCMPS", SDT_ZCmp,
+                              [SDNPHasChain]>;
+}
+
 def z_tm                : SDNode<"SystemZISD::TM", SDT_ZICmp>;
 def z_br_ccmask_1       : SDNode<"SystemZISD::BR_CCMASK", SDT_ZBRCCMask,
                                  [SDNPHasChain]>;
@@ -364,30 +368,35 @@ def z_vicmphl           : SDNode<"SystemZISD::VICMPHL", SDT_ZVecBinary>;
 def z_vicmpes           : SDNode<"SystemZISD::VICMPES", SDT_ZVecBinaryCC>;
 def z_vicmphs           : SDNode<"SystemZISD::VICMPHS", SDT_ZVecBinaryCC>;
 def z_vicmphls          : SDNode<"SystemZISD::VICMPHLS", SDT_ZVecBinaryCC>;
+
 def z_vfcmpe            : SDNode<"SystemZISD::VFCMPE", SDT_ZVecBinaryConv>;
-def z_strict_vfcmpe     : SDNode<"SystemZISD::STRICT_VFCMPE",
-                                 SDT_ZVecBinaryConv, [SDNPHasChain]>;
-def z_strict_vfcmpes    : SDNode<"SystemZISD::STRICT_VFCMPES",
-                                 SDT_ZVecBinaryConv, [SDNPHasChain]>;
 def z_vfcmph            : SDNode<"SystemZISD::VFCMPH", SDT_ZVecBinaryConv>;
-def z_strict_vfcmph     : SDNode<"SystemZISD::STRICT_VFCMPH",
-                                 SDT_ZVecBinaryConv, [SDNPHasChain]>;
-def z_strict_vfcmphs    : SDNode<"SystemZISD::STRICT_VFCMPHS",
-                                 SDT_ZVecBinaryConv, [SDNPHasChain]>;
 def z_vfcmphe           : SDNode<"SystemZISD::VFCMPHE", SDT_ZVecBinaryConv>;
-def z_strict_vfcmphe    : SDNode<"SystemZISD::STRICT_VFCMPHE",
-                                 SDT_ZVecBinaryConv, [SDNPHasChain]>;
-def z_strict_vfcmphes   : SDNode<"SystemZISD::STRICT_VFCMPHES",
-                                 SDT_ZVecBinaryConv, [SDNPHasChain]>;
 def z_vfcmpes           : SDNode<"SystemZISD::VFCMPES", SDT_ZVecBinaryConvCC>;
 def z_vfcmphs           : SDNode<"SystemZISD::VFCMPHS", SDT_ZVecBinaryConvCC>;
 def z_vfcmphes          : SDNode<"SystemZISD::VFCMPHES", SDT_ZVecBinaryConvCC>;
 def z_vextend           : SDNode<"SystemZISD::VEXTEND", SDT_ZVecUnaryConv>;
-def z_strict_vextend    : SDNode<"SystemZISD::STRICT_VEXTEND",
-                                 SDT_ZVecUnaryConv, [SDNPHasChain]>;
 def z_vround            : SDNode<"SystemZISD::VROUND", SDT_ZVecUnaryConv>;
-def z_strict_vround     : SDNode<"SystemZISD::STRICT_VROUND",
+
+let IsStrictFP = true in {
+  def z_strict_vfcmpe   : SDNode<"SystemZISD::STRICT_VFCMPE",
+                                 SDT_ZVecBinaryConv, [SDNPHasChain]>;
+  def z_strict_vfcmph   : SDNode<"SystemZISD::STRICT_VFCMPH",
+                                 SDT_ZVecBinaryConv, [SDNPHasChain]>;
+  def z_strict_vfcmphe  : SDNode<"SystemZISD::STRICT_VFCMPHE",
+                                 SDT_ZVecBinaryConv, [SDNPHasChain]>;
+  def z_strict_vfcmpes  : SDNode<"SystemZISD::STRICT_VFCMPES",
+                                 SDT_ZVecBinaryConv, [SDNPHasChain]>;
+  def z_strict_vfcmphs  : SDNode<"SystemZISD::STRICT_VFCMPHS",
+                                 SDT_ZVecBinaryConv, [SDNPHasChain]>;
+  def z_strict_vfcmphes : SDNode<"SystemZISD::STRICT_VFCMPHES",
+                                 SDT_ZVecBinaryConv, [SDNPHasChain]>;
+  def z_strict_vextend  : SDNode<"SystemZISD::STRICT_VEXTEND",
+                                 SDT_ZVecUnaryConv, [SDNPHasChain]>;
+  def z_strict_vround   : SDNode<"SystemZISD::STRICT_VROUND",
                                  SDT_ZVecUnaryConv, [SDNPHasChain]>;
+}
+
 def z_vtm               : SDNode<"SystemZISD::VTM", SDT_ZCmp>;
 def z_scmp128hi         : SDNode<"SystemZISD::SCMP128HI", SDT_ZCmp>;
 def z_ucmp128hi         : SDNode<"SystemZISD::UCMP128HI", SDT_ZCmp>;
diff --git a/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp b/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp
index 552bf1a24a74c6..9dc34e5c237ca2 100644
--- a/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp
@@ -10,37 +10,27 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "SystemZSelectionDAGInfo.h"
 #include "SystemZTargetMachine.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 
+#define GET_SDNODE_DESC
+#include "SystemZGenSDNodeInfo.inc"
+
 using namespace llvm;
 
 #define DEBUG_TYPE "systemz-selectiondag-info"
 
-bool SystemZSelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
-  if (Opcode >= SystemZISD::FIRST_MEMORY_OPCODE &&
-      Opcode <= SystemZISD::LAST_MEMORY_OPCODE)
-    return true;
-  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
-}
+SystemZSelectionDAGInfo::SystemZSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(SystemZGenSDNodeInfo) {}
 
-bool SystemZSelectionDAGInfo::isTargetStrictFPOpcode(unsigned Opcode) const {
+const char *SystemZSelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
   switch (static_cast<SystemZISD::NodeType>(Opcode)) {
-  default:
-    break;
-  case SystemZISD::STRICT_FCMP:
-  case SystemZISD::STRICT_FCMPS:
-  case SystemZISD::STRICT_VFCMPE:
-  case SystemZISD::STRICT_VFCMPH:
-  case SystemZISD::STRICT_VFCMPHE:
-  case SystemZISD::STRICT_VFCMPES:
-  case SystemZISD::STRICT_VFCMPHS:
-  case SystemZISD::STRICT_VFCMPHES:
-  case SystemZISD::STRICT_VEXTEND:
-  case SystemZISD::STRICT_VROUND:
-    return true;
+  case SystemZISD::GET_CCMASK:
+    return "SystemZISD::GET_CCMASK";
   }
-  return SelectionDAGTargetInfo::isTargetStrictFPOpcode(Opcode);
+
+  return SelectionDAGGenTargetInfo::getTargetNodeName(Opcode);
 }
 
 static unsigned getMemMemLenAdj(unsigned Op) {
diff --git a/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.h b/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.h
index c928f343e57103..7a7547bc0a8e6a 100644
--- a/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.h
+++ b/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.h
@@ -15,15 +15,34 @@
 
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 
+#define GET_SDNODE_ENUM
+#include "SystemZGenSDNodeInfo.inc"
+
 namespace llvm {
+namespace SystemZISD {
+
+enum NodeType : unsigned {
+  // Set the condition code from a boolean value in operand 0.
+  // Operand 1 is a mask of all condition-code values that may result of this
+  // operation, operand 2 is a mask of condition-code values that may result
+  // if the boolean is true.
+  // Note that this operation is always optimized away, we will never
+  // generate any code for it.
+  GET_CCMASK = GENERATED_OPCODE_END,
+};
 
-class SystemZSelectionDAGInfo : public SelectionDAGTargetInfo {
-public:
-  explicit SystemZSelectionDAGInfo() = default;
+// Return true if OPCODE is some kind of PC-relative address.
+inline bool isPCREL(unsigned Opcode) {
+  return Opcode == PCREL_WRAPPER || Opcode == PCREL_OFFSET;
+}
 
-  bool isTargetMemoryOpcode(unsigned Opcode) const override;
+} // namespace SystemZISD
+
+class SystemZSelectionDAGInfo : public SelectionDAGGenTargetInfo {
+public:
+  SystemZSelectionDAGInfo();
 
-  bool isTargetStrictFPOpcode(unsigned Opcode) const override;
+  const char *getTargetNodeName(unsigned Opcode) const override;
 
   SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &DL,
                                   SDValue Chain, SDValue Dst, SDValue Src,

>From 2e081f8cc1970ff0b035f7a61a9e6b132c603381 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 03:11:35 +0300
Subject: [PATCH 22/27] VE

---
 llvm/lib/Target/VE/CMakeLists.txt         |  2 +
 llvm/lib/Target/VE/VECustomDAG.cpp        |  1 +
 llvm/lib/Target/VE/VEISelDAGToDAG.cpp     |  1 +
 llvm/lib/Target/VE/VEISelLowering.cpp     | 42 +--------------------
 llvm/lib/Target/VE/VEISelLowering.h       | 46 -----------------------
 llvm/lib/Target/VE/VESelectionDAGInfo.cpp | 44 ++++++++++++++++++++++
 llvm/lib/Target/VE/VESelectionDAGInfo.h   | 45 ++++++++++++++++++++++
 llvm/lib/Target/VE/VESubtarget.cpp        | 11 +++++-
 llvm/lib/Target/VE/VESubtarget.h          | 10 ++---
 llvm/lib/Target/VE/VVPISelLowering.cpp    |  1 +
 10 files changed, 110 insertions(+), 93 deletions(-)
 create mode 100644 llvm/lib/Target/VE/VESelectionDAGInfo.cpp
 create mode 100644 llvm/lib/Target/VE/VESelectionDAGInfo.h

diff --git a/llvm/lib/Target/VE/CMakeLists.txt b/llvm/lib/Target/VE/CMakeLists.txt
index 76684d39450d8b..e63d8921badcf1 100644
--- a/llvm/lib/Target/VE/CMakeLists.txt
+++ b/llvm/lib/Target/VE/CMakeLists.txt
@@ -9,6 +9,7 @@ tablegen(LLVM VEGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM VEGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM VEGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM VEGenDAGISel.inc -gen-dag-isel)
+tablegen(LLVM VEGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM VEGenSubtargetInfo.inc -gen-subtarget)
 tablegen(LLVM VEGenCallingConv.inc -gen-callingconv)
 add_public_tablegen_target(VECommonTableGen)
@@ -24,6 +25,7 @@ add_llvm_target(VECodeGen
   VEMachineFunctionInfo.cpp
   VEMCInstLower.cpp
   VERegisterInfo.cpp
+  VESelectionDAGInfo.cpp
   VESubtarget.cpp
   VETargetMachine.cpp
   VVPISelLowering.cpp
diff --git a/llvm/lib/Target/VE/VECustomDAG.cpp b/llvm/lib/Target/VE/VECustomDAG.cpp
index 2855a65f654c96..74c21edb3d5143 100644
--- a/llvm/lib/Target/VE/VECustomDAG.cpp
+++ b/llvm/lib/Target/VE/VECustomDAG.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "VECustomDAG.h"
+#include "VESelectionDAGInfo.h"
 
 #ifndef DEBUG_TYPE
 #define DEBUG_TYPE "vecustomdag"
diff --git a/llvm/lib/Target/VE/VEISelDAGToDAG.cpp b/llvm/lib/Target/VE/VEISelDAGToDAG.cpp
index 85bb69cf33fda8..58bff511c0c152 100644
--- a/llvm/lib/Target/VE/VEISelDAGToDAG.cpp
+++ b/llvm/lib/Target/VE/VEISelDAGToDAG.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "VE.h"
+#include "VESelectionDAGInfo.h"
 #include "VETargetMachine.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
 #include "llvm/Support/ErrorHandling.h"
diff --git a/llvm/lib/Target/VE/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp
index a56b5a2ac9a3ea..e89d8eb27a7229 100644
--- a/llvm/lib/Target/VE/VEISelLowering.cpp
+++ b/llvm/lib/Target/VE/VEISelLowering.cpp
@@ -17,6 +17,7 @@
 #include "VEInstrBuilder.h"
 #include "VEMachineFunctionInfo.h"
 #include "VERegisterInfo.h"
+#include "VESelectionDAGInfo.h"
 #include "VETargetMachine.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/CodeGen/CallingConvLower.h"
@@ -923,47 +924,6 @@ VETargetLowering::VETargetLowering(const TargetMachine &TM,
   computeRegisterProperties(Subtarget->getRegisterInfo());
 }
 
-const char *VETargetLowering::getTargetNodeName(unsigned Opcode) const {
-#define TARGET_NODE_CASE(NAME)                                                 \
-  case VEISD::NAME:                                                            \
-    return "VEISD::" #NAME;
-  switch ((VEISD::NodeType)Opcode) {
-  case VEISD::FIRST_NUMBER:
-    break;
-    TARGET_NODE_CASE(CMPI)
-    TARGET_NODE_CASE(CMPU)
-    TARGET_NODE_CASE(CMPF)
-    TARGET_NODE_CASE(CMPQ)
-    TARGET_NODE_CASE(CMOV)
-    TARGET_NODE_CASE(CALL)
-    TARGET_NODE_CASE(EH_SJLJ_LONGJMP)
-    TARGET_NODE_CASE(EH_SJLJ_SETJMP)
-    TARGET_NODE_CASE(EH_SJLJ_SETUP_DISPATCH)
-    TARGET_NODE_CASE(GETFUNPLT)
-    TARGET_NODE_CASE(GETSTACKTOP)
-    TARGET_NODE_CASE(GETTLSADDR)
-    TARGET_NODE_CASE(GLOBAL_BASE_REG)
-    TARGET_NODE_CASE(Hi)
-    TARGET_NODE_CASE(Lo)
-    TARGET_NODE_CASE(RET_GLUE)
-    TARGET_NODE_CASE(TS1AM)
-    TARGET_NODE_CASE(VEC_UNPACK_LO)
-    TARGET_NODE_CASE(VEC_UNPACK_HI)
-    TARGET_NODE_CASE(VEC_PACK)
-    TARGET_NODE_CASE(VEC_BROADCAST)
-    TARGET_NODE_CASE(REPL_I32)
-    TARGET_NODE_CASE(REPL_F32)
-
-    TARGET_NODE_CASE(LEGALAVL)
-
-    // Register the VVP_* SDNodes.
-#define ADD_VVP_OP(VVP_NAME, ...) TARGET_NODE_CASE(VVP_NAME)
-#include "VVPNodes.def"
-  }
-#undef TARGET_NODE_CASE
-  return nullptr;
-}
-
 EVT VETargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &,
                                          EVT VT) const {
   return MVT::i32;
diff --git a/llvm/lib/Target/VE/VEISelLowering.h b/llvm/lib/Target/VE/VEISelLowering.h
index 8b9412d786625d..84b5519a098084 100644
--- a/llvm/lib/Target/VE/VEISelLowering.h
+++ b/llvm/lib/Target/VE/VEISelLowering.h
@@ -20,51 +20,6 @@
 namespace llvm {
 class VESubtarget;
 
-namespace VEISD {
-enum NodeType : unsigned {
-  FIRST_NUMBER = ISD::BUILTIN_OP_END,
-
-  CMPI, // Compare between two signed integer values.
-  CMPU, // Compare between two unsigned integer values.
-  CMPF, // Compare between two floating-point values.
-  CMPQ, // Compare between two quad floating-point values.
-  CMOV, // Select between two values using the result of comparison.
-
-  CALL,                   // A call instruction.
-  EH_SJLJ_LONGJMP,        // SjLj exception handling longjmp.
-  EH_SJLJ_SETJMP,         // SjLj exception handling setjmp.
-  EH_SJLJ_SETUP_DISPATCH, // SjLj exception handling setup_dispatch.
-  GETFUNPLT,              // Load function address through %plt insturction.
-  GETTLSADDR,             // Load address for TLS access.
-  GETSTACKTOP,            // Retrieve address of stack top (first address of
-                          // locals and temporaries).
-  GLOBAL_BASE_REG,        // Global base reg for PIC.
-  Hi,                     // Hi/Lo operations, typically on a global address.
-  Lo,                     // Hi/Lo operations, typically on a global address.
-  RET_GLUE,               // Return with a flag operand.
-  TS1AM,                  // A TS1AM instruction used for 1/2 bytes swap.
-  VEC_UNPACK_LO,          // unpack the lo v256 slice of a packed v512 vector.
-  VEC_UNPACK_HI,          // unpack the hi v256 slice of a packed v512 vector.
-                          //    0: v512 vector, 1: AVL
-  VEC_PACK,               // pack a lo and a hi vector into one v512 vector
-                          //    0: v256 lo vector, 1: v256 hi vector, 2: AVL
-
-  VEC_BROADCAST, // A vector broadcast instruction.
-                 //   0: scalar value, 1: VL
-  REPL_I32,
-  REPL_F32, // Replicate subregister to other half.
-
-  // Annotation as a wrapper. LEGALAVL(VL) means that VL refers to 64bit of
-  // data, whereas the raw EVL coming in from VP nodes always refers to number
-  // of elements, regardless of their size.
-  LEGALAVL,
-
-// VVP_* nodes.
-#define ADD_VVP_OP(VVP_NAME, ...) VVP_NAME,
-#include "VVPNodes.def"
-};
-}
-
 /// Convert a DAG integer condition code to a VE ICC condition.
 inline static VECC::CondCode intCondCode2Icc(ISD::CondCode CC) {
   switch (CC) {
@@ -167,7 +122,6 @@ class VETargetLowering : public TargetLowering {
 public:
   VETargetLowering(const TargetMachine &TM, const VESubtarget &STI);
 
-  const char *getTargetNodeName(unsigned Opcode) const override;
   MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override {
     return MVT::i32;
   }
diff --git a/llvm/lib/Target/VE/VESelectionDAGInfo.cpp b/llvm/lib/Target/VE/VESelectionDAGInfo.cpp
new file mode 100644
index 00000000000000..fba13eb32830b3
--- /dev/null
+++ b/llvm/lib/Target/VE/VESelectionDAGInfo.cpp
@@ -0,0 +1,44 @@
+//===- VESelectionDAGInfo.cpp ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "VESelectionDAGInfo.h"
+
+#define GET_SDNODE_DESC
+#include "VEGenSDNodeInfo.inc"
+
+using namespace llvm;
+
+VESelectionDAGInfo::VESelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(VEGenSDNodeInfo) {}
+
+VESelectionDAGInfo::~VESelectionDAGInfo() = default;
+
+const char *VESelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
+#define TARGET_NODE_CASE(NAME)                                                 \
+  case VEISD::NAME:                                                            \
+    return "VEISD::" #NAME;
+
+  switch (static_cast<VEISD::NodeType>(Opcode)) {
+    TARGET_NODE_CASE(GLOBAL_BASE_REG)
+    TARGET_NODE_CASE(LEGALAVL)
+  }
+#undef TARGET_NODE_CASE
+
+  return SelectionDAGGenTargetInfo::getTargetNodeName(Opcode);
+}
+
+void VESelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
+                                          const SDNode *N) const {
+  switch (N->getOpcode()) {
+  case VEISD::GETSTACKTOP:
+    // result #0 has invalid type; expected ch, got i64
+    return;
+  }
+
+  SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
+}
diff --git a/llvm/lib/Target/VE/VESelectionDAGInfo.h b/llvm/lib/Target/VE/VESelectionDAGInfo.h
new file mode 100644
index 00000000000000..c9dded16113982
--- /dev/null
+++ b/llvm/lib/Target/VE/VESelectionDAGInfo.h
@@ -0,0 +1,45 @@
+//===- VESelectionDAGInfo.h -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_VE_VESELECTIONDAGINFO_H
+#define LLVM_LIB_TARGET_VE_VESELECTIONDAGINFO_H
+
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+
+#define GET_SDNODE_ENUM
+#include "VEGenSDNodeInfo.inc"
+
+namespace llvm {
+namespace VEISD {
+
+enum NodeType : unsigned {
+  GLOBAL_BASE_REG = GENERATED_OPCODE_END, // Global base reg for PIC.
+
+  // Annotation as a wrapper. LEGALAVL(VL) means that VL refers to 64bit of
+  // data, whereas the raw EVL coming in from VP nodes always refers to number
+  // of elements, regardless of their size.
+  LEGALAVL,
+};
+
+} // namespace VEISD
+
+class VESelectionDAGInfo : public SelectionDAGGenTargetInfo {
+public:
+  VESelectionDAGInfo();
+
+  ~VESelectionDAGInfo() override;
+
+  const char *getTargetNodeName(unsigned Opcode) const override;
+
+  void verifyTargetNode(const SelectionDAG &DAG,
+                        const SDNode *N) const override;
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_VE_VESELECTIONDAGINFO_H
diff --git a/llvm/lib/Target/VE/VESubtarget.cpp b/llvm/lib/Target/VE/VESubtarget.cpp
index 197bffe2b55b7a..9c9b1b43d1a04b 100644
--- a/llvm/lib/Target/VE/VESubtarget.cpp
+++ b/llvm/lib/Target/VE/VESubtarget.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "VESubtarget.h"
+#include "VESelectionDAGInfo.h"
 #include "llvm/MC/TargetRegistry.h"
 
 using namespace llvm;
@@ -43,7 +44,15 @@ VESubtarget::VESubtarget(const Triple &TT, const std::string &CPU,
                          const std::string &FS, const TargetMachine &TM)
     : VEGenSubtargetInfo(TT, CPU, /*TuneCPU=*/CPU, FS), TargetTriple(TT),
       InstrInfo(initializeSubtargetDependencies(CPU, FS)), TLInfo(TM, *this),
-      FrameLowering(*this) {}
+      FrameLowering(*this) {
+  TSInfo = std::make_unique<VESelectionDAGInfo>();
+}
+
+VESubtarget::~VESubtarget() = default;
+
+const SelectionDAGTargetInfo *VESubtarget::getSelectionDAGInfo() const {
+  return TSInfo.get();
+}
 
 uint64_t VESubtarget::getAdjustedFrameSize(uint64_t FrameSize) const {
   // Calculate adjusted frame size by adding the size of RSA frame,
diff --git a/llvm/lib/Target/VE/VESubtarget.h b/llvm/lib/Target/VE/VESubtarget.h
index 0c3dc0a0807231..bc1c9faca5b5f0 100644
--- a/llvm/lib/Target/VE/VESubtarget.h
+++ b/llvm/lib/Target/VE/VESubtarget.h
@@ -16,7 +16,6 @@
 #include "VEFrameLowering.h"
 #include "VEISelLowering.h"
 #include "VEInstrInfo.h"
-#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/CodeGen/TargetFrameLowering.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/IR/DataLayout.h"
@@ -41,13 +40,15 @@ class VESubtarget : public VEGenSubtargetInfo {
 
   VEInstrInfo InstrInfo;
   VETargetLowering TLInfo;
-  SelectionDAGTargetInfo TSInfo;
+  std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
   VEFrameLowering FrameLowering;
 
 public:
   VESubtarget(const Triple &TT, const std::string &CPU, const std::string &FS,
               const TargetMachine &TM);
 
+  ~VESubtarget() override;
+
   const VEInstrInfo *getInstrInfo() const override { return &InstrInfo; }
   const VEFrameLowering *getFrameLowering() const override {
     return &FrameLowering;
@@ -56,9 +57,8 @@ class VESubtarget : public VEGenSubtargetInfo {
     return &InstrInfo.getRegisterInfo();
   }
   const VETargetLowering *getTargetLowering() const override { return &TLInfo; }
-  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
-    return &TSInfo;
-  }
+
+  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
 
   bool enableMachineScheduler() const override;
 
diff --git a/llvm/lib/Target/VE/VVPISelLowering.cpp b/llvm/lib/Target/VE/VVPISelLowering.cpp
index f1e2d7f717016b..2b84529cf3dd16 100644
--- a/llvm/lib/Target/VE/VVPISelLowering.cpp
+++ b/llvm/lib/Target/VE/VVPISelLowering.cpp
@@ -13,6 +13,7 @@
 
 #include "VECustomDAG.h"
 #include "VEISelLowering.h"
+#include "VESelectionDAGInfo.h"
 
 using namespace llvm;
 

>From 49f6fd3a82a8956c39115aedb6c2c59689b287aa Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 01:02:43 +0300
Subject: [PATCH 23/27] WebAssembly (BR_IF removed)

---
 llvm/lib/Target/WebAssembly/CMakeLists.txt    |  1 +
 .../lib/Target/WebAssembly/WebAssemblyISD.def | 61 -------------------
 .../WebAssembly/WebAssemblyISelLowering.cpp   | 16 +----
 .../WebAssembly/WebAssemblyISelLowering.h     | 12 ----
 .../WebAssemblySelectionDAGInfo.cpp           | 34 ++++++++---
 .../WebAssembly/WebAssemblySelectionDAGInfo.h | 20 +++++-
 6 files changed, 47 insertions(+), 97 deletions(-)
 delete mode 100644 llvm/lib/Target/WebAssembly/WebAssemblyISD.def

diff --git a/llvm/lib/Target/WebAssembly/CMakeLists.txt b/llvm/lib/Target/WebAssembly/CMakeLists.txt
index 1e83cbeac50d6d..17df119d62709b 100644
--- a/llvm/lib/Target/WebAssembly/CMakeLists.txt
+++ b/llvm/lib/Target/WebAssembly/CMakeLists.txt
@@ -10,6 +10,7 @@ tablegen(LLVM WebAssemblyGenFastISel.inc -gen-fast-isel)
 tablegen(LLVM WebAssemblyGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM WebAssemblyGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM WebAssemblyGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM WebAssemblyGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM WebAssemblyGenSubtargetInfo.inc -gen-subtarget)
 
 add_public_tablegen_target(WebAssemblyCommonTableGen)
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISD.def b/llvm/lib/Target/WebAssembly/WebAssemblyISD.def
deleted file mode 100644
index 1cf0d13df1ff6b..00000000000000
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISD.def
+++ /dev/null
@@ -1,61 +0,0 @@
-//- WebAssemblyISD.def - WebAssembly ISD ---------------------------*- C++ -*-//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This file describes the various WebAssembly ISD node types.
-///
-//===----------------------------------------------------------------------===//
-
-// NOTE: NO INCLUDE GUARD DESIRED!
-
-HANDLE_NODETYPE(CALL)
-HANDLE_NODETYPE(RET_CALL)
-HANDLE_NODETYPE(RETURN)
-HANDLE_NODETYPE(ARGUMENT)
-HANDLE_NODETYPE(LOCAL_GET)
-HANDLE_NODETYPE(LOCAL_SET)
-// A wrapper node for TargetExternalSymbol, TargetGlobalAddress, and MCSymbol
-HANDLE_NODETYPE(Wrapper)
-// A special node for TargetGlobalAddress used in PIC code for
-// __memory_base/__table_base relative access.
-HANDLE_NODETYPE(WrapperREL)
-HANDLE_NODETYPE(BR_IF)
-HANDLE_NODETYPE(BR_TABLE)
-HANDLE_NODETYPE(SHUFFLE)
-HANDLE_NODETYPE(SWIZZLE)
-HANDLE_NODETYPE(VEC_SHL)
-HANDLE_NODETYPE(VEC_SHR_S)
-HANDLE_NODETYPE(VEC_SHR_U)
-HANDLE_NODETYPE(NARROW_U)
-HANDLE_NODETYPE(EXTEND_LOW_S)
-HANDLE_NODETYPE(EXTEND_LOW_U)
-HANDLE_NODETYPE(EXTEND_HIGH_S)
-HANDLE_NODETYPE(EXTEND_HIGH_U)
-HANDLE_NODETYPE(CONVERT_LOW_S)
-HANDLE_NODETYPE(CONVERT_LOW_U)
-HANDLE_NODETYPE(PROMOTE_LOW)
-HANDLE_NODETYPE(TRUNC_SAT_ZERO_S)
-HANDLE_NODETYPE(TRUNC_SAT_ZERO_U)
-HANDLE_NODETYPE(DEMOTE_ZERO)
-HANDLE_NODETYPE(I64_ADD128)
-HANDLE_NODETYPE(I64_SUB128)
-HANDLE_NODETYPE(I64_MUL_WIDE_S)
-HANDLE_NODETYPE(I64_MUL_WIDE_U)
-
-// Memory intrinsics
-HANDLE_NODETYPE(GLOBAL_GET)
-HANDLE_NODETYPE(GLOBAL_SET)
-HANDLE_NODETYPE(TABLE_GET)
-HANDLE_NODETYPE(TABLE_SET)
-
-// Bulk memory instructions. These follow LLVM's expected semantics of
-// supporting out-of-bounds pointers if the length is zero, by inserting
-// a branch around Wasm's `memory.copy` and `memory.fill`, which would
-// otherwise trap.
-HANDLE_NODETYPE(MEMCPY)
-HANDLE_NODETYPE(MEMSET)
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index 084aed6eed46d3..9f1a106f80ebc1 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -867,20 +867,6 @@ MachineBasicBlock *WebAssemblyTargetLowering::EmitInstrWithCustomInserter(
   }
 }
 
-const char *
-WebAssemblyTargetLowering::getTargetNodeName(unsigned Opcode) const {
-  switch (static_cast<WebAssemblyISD::NodeType>(Opcode)) {
-  case WebAssemblyISD::FIRST_NUMBER:
-    break;
-#define HANDLE_NODETYPE(NODE)                                                  \
-  case WebAssemblyISD::NODE:                                                   \
-    return "WebAssemblyISD::" #NODE;
-#include "WebAssemblyISD.def"
-#undef HANDLE_NODETYPE
-  }
-  return nullptr;
-}
-
 std::pair<unsigned, const TargetRegisterClass *>
 WebAssemblyTargetLowering::getRegForInlineAsmConstraint(
     const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
@@ -1726,7 +1712,7 @@ SDValue WebAssemblyTargetLowering::LowerLoad(SDValue Op,
     SDValue Idx = DAG.getTargetConstant(*Local, Base, MVT::i32);
     EVT LocalVT = LN->getValueType(0);
     SDValue LocalGet = DAG.getNode(WebAssemblyISD::LOCAL_GET, DL, LocalVT,
-                                   {LN->getChain(), Idx});
+                       {LN->getChain(), Idx});
     SDValue Result = DAG.getMergeValues({LocalGet, LN->getChain()}, DL);
     assert(Result->getNumValues() == 2 && "Loads must carry a chain!");
     return Result;
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
index 454432728ca871..952d508d464801 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
@@ -19,17 +19,6 @@
 
 namespace llvm {
 
-namespace WebAssemblyISD {
-
-enum NodeType : unsigned {
-  FIRST_NUMBER = ISD::BUILTIN_OP_END,
-#define HANDLE_NODETYPE(NODE) NODE,
-#include "WebAssemblyISD.def"
-#undef HANDLE_NODETYPE
-};
-
-} // end namespace WebAssemblyISD
-
 class WebAssemblySubtarget;
 
 class WebAssemblyTargetLowering final : public TargetLowering {
@@ -53,7 +42,6 @@ class WebAssemblyTargetLowering final : public TargetLowering {
   MachineBasicBlock *
   EmitInstrWithCustomInserter(MachineInstr &MI,
                               MachineBasicBlock *MBB) const override;
-  const char *getTargetNodeName(unsigned Opcode) const override;
   std::pair<unsigned, const TargetRegisterClass *>
   getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
                                StringRef Constraint, MVT VT) const override;
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.cpp
index b94cd46c9c141e..c02f8434ee5828 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.cpp
@@ -11,24 +11,44 @@
 ///
 //===----------------------------------------------------------------------===//
 
+#include "WebAssemblySelectionDAGInfo.h"
 #include "WebAssemblyTargetMachine.h"
+
+#define GET_SDNODE_DESC
+#include "WebAssemblyGenSDNodeInfo.inc"
+
 using namespace llvm;
 
 #define DEBUG_TYPE "wasm-selectiondag-info"
 
+WebAssemblySelectionDAGInfo::WebAssemblySelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(WebAssemblyGenSDNodeInfo) {}
+
 WebAssemblySelectionDAGInfo::~WebAssemblySelectionDAGInfo() = default; // anchor
 
-bool WebAssemblySelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
+const char *
+WebAssemblySelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
   switch (static_cast<WebAssemblyISD::NodeType>(Opcode)) {
+  case WebAssemblyISD::CALL:
+    return "WebAssemblyISD::CALL";
+  case WebAssemblyISD::RET_CALL:
+    return "WebAssemblyISD::RET_CALL";
+  }
+
+  return SelectionDAGGenTargetInfo::getTargetNodeName(Opcode);
+}
+
+void WebAssemblySelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
+                                                   const SDNode *N) const {
+  switch (N->getOpcode()) {
   default:
     break;
-  case WebAssemblyISD::GLOBAL_GET:
-  case WebAssemblyISD::GLOBAL_SET:
-  case WebAssemblyISD::TABLE_GET:
-  case WebAssemblyISD::TABLE_SET:
-    return true;
+  case WebAssemblyISD::LOCAL_GET:
+    // invalid number of results; expected 2, got 1
+    return;
   }
-  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+
+  SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
 }
 
 SDValue WebAssemblySelectionDAGInfo::EmitTargetCodeForMemcpy(
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.h b/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.h
index 69c9af09663081..6fcc09a3681795 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.h
@@ -17,13 +17,29 @@
 
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 
+#define GET_SDNODE_ENUM
+#include "WebAssemblyGenSDNodeInfo.inc"
+
 namespace llvm {
+namespace WebAssemblyISD {
+
+enum NodeType : unsigned {
+  CALL = GENERATED_OPCODE_END,
+  RET_CALL,
+};
 
-class WebAssemblySelectionDAGInfo final : public SelectionDAGTargetInfo {
+} // namespace WebAssemblyISD
+
+class WebAssemblySelectionDAGInfo final : public SelectionDAGGenTargetInfo {
 public:
+  WebAssemblySelectionDAGInfo();
+
   ~WebAssemblySelectionDAGInfo() override;
 
-  bool isTargetMemoryOpcode(unsigned Opcode) const override;
+  const char *getTargetNodeName(unsigned Opcode) const override;
+
+  void verifyTargetNode(const SelectionDAG &DAG,
+                        const SDNode *N) const override;
 
   SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &dl,
                                   SDValue Chain, SDValue Op1, SDValue Op2,

>From 9f4d0c6f77c4014baf39c52d1e8dfeb15b2e2770 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 01:02:48 +0300
Subject: [PATCH 24/27] X86

---
 llvm/lib/Target/X86/CMakeLists.txt           |   1 +
 llvm/lib/Target/X86/X86ISelLowering.cpp      | 486 +---------
 llvm/lib/Target/X86/X86ISelLowering.h        | 966 +------------------
 llvm/lib/Target/X86/X86ISelLoweringCall.cpp  |   6 +-
 llvm/lib/Target/X86/X86InstrFragments.td     |  11 +-
 llvm/lib/Target/X86/X86InstrFragmentsSIMD.td |  52 +-
 llvm/lib/Target/X86/X86SelectionDAGInfo.cpp  |  74 +-
 llvm/lib/Target/X86/X86SelectionDAGInfo.h    |  45 +-
 8 files changed, 173 insertions(+), 1468 deletions(-)

diff --git a/llvm/lib/Target/X86/CMakeLists.txt b/llvm/lib/Target/X86/CMakeLists.txt
index 9553a8619feb51..f9ad00525bf15f 100644
--- a/llvm/lib/Target/X86/CMakeLists.txt
+++ b/llvm/lib/Target/X86/CMakeLists.txt
@@ -17,6 +17,7 @@ tablegen(LLVM X86GenInstrInfo.inc -gen-instr-info
 tablegen(LLVM X86GenMnemonicTables.inc -gen-x86-mnemonic-tables -asmwriternum=1)
 tablegen(LLVM X86GenRegisterBank.inc -gen-register-bank)
 tablegen(LLVM X86GenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM X86GenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM X86GenSubtargetInfo.inc -gen-subtarget)
 tablegen(LLVM X86GenFoldTables.inc -gen-x86-fold-tables -asmwriternum=1)
 
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 2956800ee3a147..84543675268fed 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -18988,9 +18988,9 @@ static SDValue GetTLSADDR(SelectionDAG &DAG, GlobalAddressSDNode *GA,
   }
 
   if (!Ret) {
-    X86ISD::NodeType CallType = UseTLSDESC     ? X86ISD::TLSDESC
-                                : LocalDynamic ? X86ISD::TLSBASEADDR
-                                               : X86ISD::TLSADDR;
+    unsigned CallType = UseTLSDESC     ? X86ISD::TLSDESC
+                        : LocalDynamic ? X86ISD::TLSBASEADDR
+                                       : X86ISD::TLSADDR;
 
     Chain = DAG.getCALLSEQ_START(Chain, 0, 0, dl);
     if (LoadGlobalBaseReg) {
@@ -26860,7 +26860,7 @@ SDValue X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
 
     SDValue Operation =
         DAG.getNode(X86ISD::VP2INTERSECT, DL, VTs,
-                    Op->getOperand(1), Op->getOperand(2));
+                                    Op->getOperand(1), Op->getOperand(2));
 
     SDValue Result0 = DAG.getTargetExtractSubreg(X86::sub_mask_0, DL,
                                                  MaskVT, Operation);
@@ -28836,7 +28836,7 @@ static SDValue LowerFMINIMUM_FMAXIMUM(SDValue Op, const X86Subtarget &Subtarget,
   APInt PreferredZero = APInt::getZero(SizeInBits);
   APInt OppositeZero = PreferredZero;
   EVT IVT = VT.changeTypeToInteger();
-  X86ISD::NodeType MinMaxOp;
+  unsigned MinMaxOp;
   if (Op.getOpcode() == ISD::FMAXIMUM) {
     MinMaxOp = X86ISD::FMAX;
     OppositeZero.setSignBit();
@@ -34415,474 +34415,6 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N,
   }
 }
 
-const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
-  switch ((X86ISD::NodeType)Opcode) {
-  case X86ISD::FIRST_NUMBER:       break;
-#define NODE_NAME_CASE(NODE) case X86ISD::NODE: return "X86ISD::" #NODE;
-  NODE_NAME_CASE(BSF)
-  NODE_NAME_CASE(BSR)
-  NODE_NAME_CASE(FSHL)
-  NODE_NAME_CASE(FSHR)
-  NODE_NAME_CASE(FAND)
-  NODE_NAME_CASE(FANDN)
-  NODE_NAME_CASE(FOR)
-  NODE_NAME_CASE(FXOR)
-  NODE_NAME_CASE(FILD)
-  NODE_NAME_CASE(FIST)
-  NODE_NAME_CASE(FP_TO_INT_IN_MEM)
-  NODE_NAME_CASE(FLD)
-  NODE_NAME_CASE(FST)
-  NODE_NAME_CASE(CALL)
-  NODE_NAME_CASE(CALL_RVMARKER)
-  NODE_NAME_CASE(BT)
-  NODE_NAME_CASE(CMP)
-  NODE_NAME_CASE(FCMP)
-  NODE_NAME_CASE(STRICT_FCMP)
-  NODE_NAME_CASE(STRICT_FCMPS)
-  NODE_NAME_CASE(COMI)
-  NODE_NAME_CASE(UCOMI)
-  NODE_NAME_CASE(COMX)
-  NODE_NAME_CASE(UCOMX)
-  NODE_NAME_CASE(CMPM)
-  NODE_NAME_CASE(CMPMM)
-  NODE_NAME_CASE(STRICT_CMPM)
-  NODE_NAME_CASE(CMPMM_SAE)
-  NODE_NAME_CASE(SETCC)
-  NODE_NAME_CASE(SETCC_CARRY)
-  NODE_NAME_CASE(FSETCC)
-  NODE_NAME_CASE(FSETCCM)
-  NODE_NAME_CASE(FSETCCM_SAE)
-  NODE_NAME_CASE(CMOV)
-  NODE_NAME_CASE(BRCOND)
-  NODE_NAME_CASE(RET_GLUE)
-  NODE_NAME_CASE(IRET)
-  NODE_NAME_CASE(REP_STOS)
-  NODE_NAME_CASE(REP_MOVS)
-  NODE_NAME_CASE(GlobalBaseReg)
-  NODE_NAME_CASE(Wrapper)
-  NODE_NAME_CASE(WrapperRIP)
-  NODE_NAME_CASE(MOVQ2DQ)
-  NODE_NAME_CASE(MOVDQ2Q)
-  NODE_NAME_CASE(MMX_MOVD2W)
-  NODE_NAME_CASE(MMX_MOVW2D)
-  NODE_NAME_CASE(PEXTRB)
-  NODE_NAME_CASE(PEXTRW)
-  NODE_NAME_CASE(INSERTPS)
-  NODE_NAME_CASE(PINSRB)
-  NODE_NAME_CASE(PINSRW)
-  NODE_NAME_CASE(PSHUFB)
-  NODE_NAME_CASE(ANDNP)
-  NODE_NAME_CASE(BLENDI)
-  NODE_NAME_CASE(BLENDV)
-  NODE_NAME_CASE(HADD)
-  NODE_NAME_CASE(HSUB)
-  NODE_NAME_CASE(FHADD)
-  NODE_NAME_CASE(FHSUB)
-  NODE_NAME_CASE(CONFLICT)
-  NODE_NAME_CASE(FMAX)
-  NODE_NAME_CASE(FMAXS)
-  NODE_NAME_CASE(FMAX_SAE)
-  NODE_NAME_CASE(FMAXS_SAE)
-  NODE_NAME_CASE(STRICT_FMAX)
-  NODE_NAME_CASE(FMIN)
-  NODE_NAME_CASE(FMINS)
-  NODE_NAME_CASE(FMIN_SAE)
-  NODE_NAME_CASE(FMINS_SAE)
-  NODE_NAME_CASE(STRICT_FMIN)
-  NODE_NAME_CASE(FMAXC)
-  NODE_NAME_CASE(FMINC)
-  NODE_NAME_CASE(FRSQRT)
-  NODE_NAME_CASE(FRCP)
-  NODE_NAME_CASE(EXTRQI)
-  NODE_NAME_CASE(INSERTQI)
-  NODE_NAME_CASE(TLSADDR)
-  NODE_NAME_CASE(TLSBASEADDR)
-  NODE_NAME_CASE(TLSCALL)
-  NODE_NAME_CASE(TLSDESC)
-  NODE_NAME_CASE(EH_SJLJ_SETJMP)
-  NODE_NAME_CASE(EH_SJLJ_LONGJMP)
-  NODE_NAME_CASE(EH_SJLJ_SETUP_DISPATCH)
-  NODE_NAME_CASE(EH_RETURN)
-  NODE_NAME_CASE(TC_RETURN)
-  NODE_NAME_CASE(FNSTCW16m)
-  NODE_NAME_CASE(FLDCW16m)
-  NODE_NAME_CASE(FNSTENVm)
-  NODE_NAME_CASE(FLDENVm)
-  NODE_NAME_CASE(LCMPXCHG_DAG)
-  NODE_NAME_CASE(LCMPXCHG8_DAG)
-  NODE_NAME_CASE(LCMPXCHG16_DAG)
-  NODE_NAME_CASE(LCMPXCHG16_SAVE_RBX_DAG)
-  NODE_NAME_CASE(LADD)
-  NODE_NAME_CASE(LSUB)
-  NODE_NAME_CASE(LOR)
-  NODE_NAME_CASE(LXOR)
-  NODE_NAME_CASE(LAND)
-  NODE_NAME_CASE(LBTS)
-  NODE_NAME_CASE(LBTC)
-  NODE_NAME_CASE(LBTR)
-  NODE_NAME_CASE(LBTS_RM)
-  NODE_NAME_CASE(LBTC_RM)
-  NODE_NAME_CASE(LBTR_RM)
-  NODE_NAME_CASE(AADD)
-  NODE_NAME_CASE(AOR)
-  NODE_NAME_CASE(AXOR)
-  NODE_NAME_CASE(AAND)
-  NODE_NAME_CASE(VZEXT_MOVL)
-  NODE_NAME_CASE(VZEXT_LOAD)
-  NODE_NAME_CASE(VEXTRACT_STORE)
-  NODE_NAME_CASE(VTRUNC)
-  NODE_NAME_CASE(VTRUNCS)
-  NODE_NAME_CASE(VTRUNCUS)
-  NODE_NAME_CASE(VMTRUNC)
-  NODE_NAME_CASE(VMTRUNCS)
-  NODE_NAME_CASE(VMTRUNCUS)
-  NODE_NAME_CASE(VTRUNCSTORES)
-  NODE_NAME_CASE(VTRUNCSTOREUS)
-  NODE_NAME_CASE(VMTRUNCSTORES)
-  NODE_NAME_CASE(VMTRUNCSTOREUS)
-  NODE_NAME_CASE(VFPEXT)
-  NODE_NAME_CASE(STRICT_VFPEXT)
-  NODE_NAME_CASE(VFPEXT_SAE)
-  NODE_NAME_CASE(VFPEXTS)
-  NODE_NAME_CASE(VFPEXTS_SAE)
-  NODE_NAME_CASE(VFPROUND)
-  NODE_NAME_CASE(VFPROUND2)
-  NODE_NAME_CASE(VFPROUND2_RND)
-  NODE_NAME_CASE(STRICT_VFPROUND)
-  NODE_NAME_CASE(VMFPROUND)
-  NODE_NAME_CASE(VFPROUND_RND)
-  NODE_NAME_CASE(VFPROUNDS)
-  NODE_NAME_CASE(VFPROUNDS_RND)
-  NODE_NAME_CASE(VSHLDQ)
-  NODE_NAME_CASE(VSRLDQ)
-  NODE_NAME_CASE(VSHL)
-  NODE_NAME_CASE(VSRL)
-  NODE_NAME_CASE(VSRA)
-  NODE_NAME_CASE(VSHLI)
-  NODE_NAME_CASE(VSRLI)
-  NODE_NAME_CASE(VSRAI)
-  NODE_NAME_CASE(VSHLV)
-  NODE_NAME_CASE(VSRLV)
-  NODE_NAME_CASE(VSRAV)
-  NODE_NAME_CASE(VROTLI)
-  NODE_NAME_CASE(VROTRI)
-  NODE_NAME_CASE(VPPERM)
-  NODE_NAME_CASE(CMPP)
-  NODE_NAME_CASE(STRICT_CMPP)
-  NODE_NAME_CASE(PCMPEQ)
-  NODE_NAME_CASE(PCMPGT)
-  NODE_NAME_CASE(PHMINPOS)
-  NODE_NAME_CASE(ADD)
-  NODE_NAME_CASE(SUB)
-  NODE_NAME_CASE(ADC)
-  NODE_NAME_CASE(SBB)
-  NODE_NAME_CASE(SMUL)
-  NODE_NAME_CASE(UMUL)
-  NODE_NAME_CASE(OR)
-  NODE_NAME_CASE(XOR)
-  NODE_NAME_CASE(AND)
-  NODE_NAME_CASE(BEXTR)
-  NODE_NAME_CASE(BEXTRI)
-  NODE_NAME_CASE(BZHI)
-  NODE_NAME_CASE(PDEP)
-  NODE_NAME_CASE(PEXT)
-  NODE_NAME_CASE(MUL_IMM)
-  NODE_NAME_CASE(MOVMSK)
-  NODE_NAME_CASE(PTEST)
-  NODE_NAME_CASE(TESTP)
-  NODE_NAME_CASE(KORTEST)
-  NODE_NAME_CASE(KTEST)
-  NODE_NAME_CASE(KADD)
-  NODE_NAME_CASE(KSHIFTL)
-  NODE_NAME_CASE(KSHIFTR)
-  NODE_NAME_CASE(PACKSS)
-  NODE_NAME_CASE(PACKUS)
-  NODE_NAME_CASE(PALIGNR)
-  NODE_NAME_CASE(VALIGN)
-  NODE_NAME_CASE(VSHLD)
-  NODE_NAME_CASE(VSHRD)
-  NODE_NAME_CASE(VSHLDV)
-  NODE_NAME_CASE(VSHRDV)
-  NODE_NAME_CASE(PSHUFD)
-  NODE_NAME_CASE(PSHUFHW)
-  NODE_NAME_CASE(PSHUFLW)
-  NODE_NAME_CASE(SHUFP)
-  NODE_NAME_CASE(SHUF128)
-  NODE_NAME_CASE(MOVLHPS)
-  NODE_NAME_CASE(MOVHLPS)
-  NODE_NAME_CASE(MOVDDUP)
-  NODE_NAME_CASE(MOVSHDUP)
-  NODE_NAME_CASE(MOVSLDUP)
-  NODE_NAME_CASE(MOVSD)
-  NODE_NAME_CASE(MOVSS)
-  NODE_NAME_CASE(MOVSH)
-  NODE_NAME_CASE(UNPCKL)
-  NODE_NAME_CASE(UNPCKH)
-  NODE_NAME_CASE(VBROADCAST)
-  NODE_NAME_CASE(VBROADCAST_LOAD)
-  NODE_NAME_CASE(VBROADCASTM)
-  NODE_NAME_CASE(SUBV_BROADCAST_LOAD)
-  NODE_NAME_CASE(VPERMILPV)
-  NODE_NAME_CASE(VPERMILPI)
-  NODE_NAME_CASE(VPERM2X128)
-  NODE_NAME_CASE(VPERMV)
-  NODE_NAME_CASE(VPERMV3)
-  NODE_NAME_CASE(VPERMI)
-  NODE_NAME_CASE(VPTERNLOG)
-  NODE_NAME_CASE(VFIXUPIMM)
-  NODE_NAME_CASE(VFIXUPIMM_SAE)
-  NODE_NAME_CASE(VFIXUPIMMS)
-  NODE_NAME_CASE(VFIXUPIMMS_SAE)
-  NODE_NAME_CASE(VRANGE)
-  NODE_NAME_CASE(VRANGE_SAE)
-  NODE_NAME_CASE(VRANGES)
-  NODE_NAME_CASE(VRANGES_SAE)
-  NODE_NAME_CASE(PMULUDQ)
-  NODE_NAME_CASE(PMULDQ)
-  NODE_NAME_CASE(PSADBW)
-  NODE_NAME_CASE(DBPSADBW)
-  NODE_NAME_CASE(VASTART_SAVE_XMM_REGS)
-  NODE_NAME_CASE(VAARG_64)
-  NODE_NAME_CASE(VAARG_X32)
-  NODE_NAME_CASE(DYN_ALLOCA)
-  NODE_NAME_CASE(MFENCE)
-  NODE_NAME_CASE(SEG_ALLOCA)
-  NODE_NAME_CASE(PROBED_ALLOCA)
-  NODE_NAME_CASE(RDRAND)
-  NODE_NAME_CASE(RDSEED)
-  NODE_NAME_CASE(RDPKRU)
-  NODE_NAME_CASE(WRPKRU)
-  NODE_NAME_CASE(VPMADDUBSW)
-  NODE_NAME_CASE(VPMADDWD)
-  NODE_NAME_CASE(VPSHA)
-  NODE_NAME_CASE(VPSHL)
-  NODE_NAME_CASE(VPCOM)
-  NODE_NAME_CASE(VPCOMU)
-  NODE_NAME_CASE(VPERMIL2)
-  NODE_NAME_CASE(FMSUB)
-  NODE_NAME_CASE(STRICT_FMSUB)
-  NODE_NAME_CASE(FNMADD)
-  NODE_NAME_CASE(STRICT_FNMADD)
-  NODE_NAME_CASE(FNMSUB)
-  NODE_NAME_CASE(STRICT_FNMSUB)
-  NODE_NAME_CASE(FMADDSUB)
-  NODE_NAME_CASE(FMSUBADD)
-  NODE_NAME_CASE(FMADD_RND)
-  NODE_NAME_CASE(FNMADD_RND)
-  NODE_NAME_CASE(FMSUB_RND)
-  NODE_NAME_CASE(FNMSUB_RND)
-  NODE_NAME_CASE(FMADDSUB_RND)
-  NODE_NAME_CASE(FMSUBADD_RND)
-  NODE_NAME_CASE(VFMADDC)
-  NODE_NAME_CASE(VFMADDC_RND)
-  NODE_NAME_CASE(VFCMADDC)
-  NODE_NAME_CASE(VFCMADDC_RND)
-  NODE_NAME_CASE(VFMULC)
-  NODE_NAME_CASE(VFMULC_RND)
-  NODE_NAME_CASE(VFCMULC)
-  NODE_NAME_CASE(VFCMULC_RND)
-  NODE_NAME_CASE(VFMULCSH)
-  NODE_NAME_CASE(VFMULCSH_RND)
-  NODE_NAME_CASE(VFCMULCSH)
-  NODE_NAME_CASE(VFCMULCSH_RND)
-  NODE_NAME_CASE(VFMADDCSH)
-  NODE_NAME_CASE(VFMADDCSH_RND)
-  NODE_NAME_CASE(VFCMADDCSH)
-  NODE_NAME_CASE(VFCMADDCSH_RND)
-  NODE_NAME_CASE(VPMADD52H)
-  NODE_NAME_CASE(VPMADD52L)
-  NODE_NAME_CASE(VRNDSCALE)
-  NODE_NAME_CASE(STRICT_VRNDSCALE)
-  NODE_NAME_CASE(VRNDSCALE_SAE)
-  NODE_NAME_CASE(VRNDSCALES)
-  NODE_NAME_CASE(VRNDSCALES_SAE)
-  NODE_NAME_CASE(VREDUCE)
-  NODE_NAME_CASE(VREDUCE_SAE)
-  NODE_NAME_CASE(VREDUCES)
-  NODE_NAME_CASE(VREDUCES_SAE)
-  NODE_NAME_CASE(VGETMANT)
-  NODE_NAME_CASE(VGETMANT_SAE)
-  NODE_NAME_CASE(VGETMANTS)
-  NODE_NAME_CASE(VGETMANTS_SAE)
-  NODE_NAME_CASE(PCMPESTR)
-  NODE_NAME_CASE(PCMPISTR)
-  NODE_NAME_CASE(XTEST)
-  NODE_NAME_CASE(COMPRESS)
-  NODE_NAME_CASE(EXPAND)
-  NODE_NAME_CASE(SELECTS)
-  NODE_NAME_CASE(ADDSUB)
-  NODE_NAME_CASE(RCP14)
-  NODE_NAME_CASE(RCP14S)
-  NODE_NAME_CASE(RSQRT14)
-  NODE_NAME_CASE(RSQRT14S)
-  NODE_NAME_CASE(FADD_RND)
-  NODE_NAME_CASE(FADDS)
-  NODE_NAME_CASE(FADDS_RND)
-  NODE_NAME_CASE(FSUB_RND)
-  NODE_NAME_CASE(FSUBS)
-  NODE_NAME_CASE(FSUBS_RND)
-  NODE_NAME_CASE(FMUL_RND)
-  NODE_NAME_CASE(FMULS)
-  NODE_NAME_CASE(FMULS_RND)
-  NODE_NAME_CASE(FDIV_RND)
-  NODE_NAME_CASE(FDIVS)
-  NODE_NAME_CASE(FDIVS_RND)
-  NODE_NAME_CASE(FSQRT_RND)
-  NODE_NAME_CASE(FSQRTS)
-  NODE_NAME_CASE(FSQRTS_RND)
-  NODE_NAME_CASE(FGETEXP)
-  NODE_NAME_CASE(FGETEXP_SAE)
-  NODE_NAME_CASE(FGETEXPS)
-  NODE_NAME_CASE(FGETEXPS_SAE)
-  NODE_NAME_CASE(SCALEF)
-  NODE_NAME_CASE(SCALEF_RND)
-  NODE_NAME_CASE(SCALEFS)
-  NODE_NAME_CASE(SCALEFS_RND)
-  NODE_NAME_CASE(MULHRS)
-  NODE_NAME_CASE(SINT_TO_FP_RND)
-  NODE_NAME_CASE(UINT_TO_FP_RND)
-  NODE_NAME_CASE(CVTTP2SI)
-  NODE_NAME_CASE(CVTTP2UI)
-  NODE_NAME_CASE(STRICT_CVTTP2SI)
-  NODE_NAME_CASE(STRICT_CVTTP2UI)
-  NODE_NAME_CASE(MCVTTP2SI)
-  NODE_NAME_CASE(MCVTTP2UI)
-  NODE_NAME_CASE(CVTTP2SI_SAE)
-  NODE_NAME_CASE(CVTTP2UI_SAE)
-  NODE_NAME_CASE(CVTTS2SI)
-  NODE_NAME_CASE(CVTTS2UI)
-  NODE_NAME_CASE(CVTTS2SI_SAE)
-  NODE_NAME_CASE(CVTTS2UI_SAE)
-  NODE_NAME_CASE(CVTSI2P)
-  NODE_NAME_CASE(CVTUI2P)
-  NODE_NAME_CASE(STRICT_CVTSI2P)
-  NODE_NAME_CASE(STRICT_CVTUI2P)
-  NODE_NAME_CASE(MCVTSI2P)
-  NODE_NAME_CASE(MCVTUI2P)
-  NODE_NAME_CASE(VFPCLASS)
-  NODE_NAME_CASE(VFPCLASSS)
-  NODE_NAME_CASE(MULTISHIFT)
-  NODE_NAME_CASE(SCALAR_SINT_TO_FP)
-  NODE_NAME_CASE(SCALAR_SINT_TO_FP_RND)
-  NODE_NAME_CASE(SCALAR_UINT_TO_FP)
-  NODE_NAME_CASE(SCALAR_UINT_TO_FP_RND)
-  NODE_NAME_CASE(CVTPS2PH)
-  NODE_NAME_CASE(STRICT_CVTPS2PH)
-  NODE_NAME_CASE(CVTPS2PH_SAE)
-  NODE_NAME_CASE(MCVTPS2PH)
-  NODE_NAME_CASE(MCVTPS2PH_SAE)
-  NODE_NAME_CASE(CVTPH2PS)
-  NODE_NAME_CASE(STRICT_CVTPH2PS)
-  NODE_NAME_CASE(CVTPH2PS_SAE)
-  NODE_NAME_CASE(CVTP2SI)
-  NODE_NAME_CASE(CVTP2UI)
-  NODE_NAME_CASE(MCVTP2SI)
-  NODE_NAME_CASE(MCVTP2UI)
-  NODE_NAME_CASE(CVTP2SI_RND)
-  NODE_NAME_CASE(CVTP2UI_RND)
-  NODE_NAME_CASE(CVTS2SI)
-  NODE_NAME_CASE(CVTS2UI)
-  NODE_NAME_CASE(CVTS2SI_RND)
-  NODE_NAME_CASE(CVTS2UI_RND)
-  NODE_NAME_CASE(CVTNEPS2BF16)
-  NODE_NAME_CASE(MCVTNEPS2BF16)
-  NODE_NAME_CASE(DPBF16PS)
-  NODE_NAME_CASE(DPFP16PS)
-  NODE_NAME_CASE(MPSADBW)
-  NODE_NAME_CASE(LWPINS)
-  NODE_NAME_CASE(MGATHER)
-  NODE_NAME_CASE(MSCATTER)
-  NODE_NAME_CASE(VPDPBUSD)
-  NODE_NAME_CASE(VPDPBUSDS)
-  NODE_NAME_CASE(VPDPWSSD)
-  NODE_NAME_CASE(VPDPWSSDS)
-  NODE_NAME_CASE(VPSHUFBITQMB)
-  NODE_NAME_CASE(GF2P8MULB)
-  NODE_NAME_CASE(GF2P8AFFINEQB)
-  NODE_NAME_CASE(GF2P8AFFINEINVQB)
-  NODE_NAME_CASE(NT_CALL)
-  NODE_NAME_CASE(NT_BRIND)
-  NODE_NAME_CASE(UMWAIT)
-  NODE_NAME_CASE(TPAUSE)
-  NODE_NAME_CASE(ENQCMD)
-  NODE_NAME_CASE(ENQCMDS)
-  NODE_NAME_CASE(VP2INTERSECT)
-  NODE_NAME_CASE(VPDPBSUD)
-  NODE_NAME_CASE(VPDPBSUDS)
-  NODE_NAME_CASE(VPDPBUUD)
-  NODE_NAME_CASE(VPDPBUUDS)
-  NODE_NAME_CASE(VPDPBSSD)
-  NODE_NAME_CASE(VPDPBSSDS)
-  NODE_NAME_CASE(VPDPWSUD)
-  NODE_NAME_CASE(VPDPWSUDS)
-  NODE_NAME_CASE(VPDPWUSD)
-  NODE_NAME_CASE(VPDPWUSDS)
-  NODE_NAME_CASE(VPDPWUUD)
-  NODE_NAME_CASE(VPDPWUUDS)
-  NODE_NAME_CASE(VMINMAX)
-  NODE_NAME_CASE(VMINMAX_SAE)
-  NODE_NAME_CASE(VMINMAXS)
-  NODE_NAME_CASE(VMINMAXS_SAE)
-  NODE_NAME_CASE(CVTP2IBS)
-  NODE_NAME_CASE(CVTP2IUBS)
-  NODE_NAME_CASE(CVTP2IBS_RND)
-  NODE_NAME_CASE(CVTP2IUBS_RND)
-  NODE_NAME_CASE(CVTTP2IBS)
-  NODE_NAME_CASE(CVTTP2IUBS)
-  NODE_NAME_CASE(CVTTP2IBS_SAE)
-  NODE_NAME_CASE(CVTTP2IUBS_SAE)
-  NODE_NAME_CASE(VCVTNE2PH2BF8)
-  NODE_NAME_CASE(VCVTNE2PH2BF8S)
-  NODE_NAME_CASE(VCVTNE2PH2HF8)
-  NODE_NAME_CASE(VCVTNE2PH2HF8S)
-  NODE_NAME_CASE(VCVTBIASPH2BF8)
-  NODE_NAME_CASE(VCVTBIASPH2BF8S)
-  NODE_NAME_CASE(VCVTBIASPH2HF8)
-  NODE_NAME_CASE(VCVTBIASPH2HF8S)
-  NODE_NAME_CASE(VCVTNEPH2BF8)
-  NODE_NAME_CASE(VCVTNEPH2BF8S)
-  NODE_NAME_CASE(VCVTNEPH2HF8)
-  NODE_NAME_CASE(VCVTNEPH2HF8S)
-  NODE_NAME_CASE(VMCVTBIASPH2BF8)
-  NODE_NAME_CASE(VMCVTBIASPH2BF8S)
-  NODE_NAME_CASE(VMCVTBIASPH2HF8)
-  NODE_NAME_CASE(VMCVTBIASPH2HF8S)
-  NODE_NAME_CASE(VMCVTNEPH2BF8)
-  NODE_NAME_CASE(VMCVTNEPH2BF8S)
-  NODE_NAME_CASE(VMCVTNEPH2HF8)
-  NODE_NAME_CASE(VMCVTNEPH2HF8S)
-  NODE_NAME_CASE(VCVTHF82PH)
-  NODE_NAME_CASE(AESENC128KL)
-  NODE_NAME_CASE(AESDEC128KL)
-  NODE_NAME_CASE(AESENC256KL)
-  NODE_NAME_CASE(AESDEC256KL)
-  NODE_NAME_CASE(AESENCWIDE128KL)
-  NODE_NAME_CASE(AESDECWIDE128KL)
-  NODE_NAME_CASE(AESENCWIDE256KL)
-  NODE_NAME_CASE(AESDECWIDE256KL)
-  NODE_NAME_CASE(CMPCCXADD)
-  NODE_NAME_CASE(TESTUI)
-  NODE_NAME_CASE(FP80_ADD)
-  NODE_NAME_CASE(STRICT_FP80_ADD)
-  NODE_NAME_CASE(CCMP)
-  NODE_NAME_CASE(CTEST)
-  NODE_NAME_CASE(CLOAD)
-  NODE_NAME_CASE(CSTORE)
-  NODE_NAME_CASE(CVTTS2SIS)
-  NODE_NAME_CASE(CVTTS2UIS)
-  NODE_NAME_CASE(CVTTS2SIS_SAE)
-  NODE_NAME_CASE(CVTTS2UIS_SAE)
-  NODE_NAME_CASE(CVTTP2SIS)
-  NODE_NAME_CASE(MCVTTP2SIS)
-  NODE_NAME_CASE(CVTTP2UIS_SAE)
-  NODE_NAME_CASE(CVTTP2SIS_SAE)
-  NODE_NAME_CASE(CVTTP2UIS)
-  NODE_NAME_CASE(MCVTTP2UIS)
-  }
-  return nullptr;
-#undef NODE_NAME_CASE
-}
-
 /// Return true if the addressing mode represented by AM is legal for this
 /// target, for a load/store of the specified type.
 bool X86TargetLowering::isLegalAddressingMode(const DataLayout &DL,
@@ -54494,8 +54026,8 @@ static SDValue combineX86INT_TO_FP(SDNode *N, SelectionDAG &DAG,
 
 static SDValue combineCVTP2I_CVTTP2I(SDNode *N, SelectionDAG &DAG,
                                      TargetLowering::DAGCombinerInfo &DCI) {
-  const SelectionDAGTargetInfo &TSI = DAG.getSelectionDAGInfo();
-  bool IsStrict = TSI.isTargetStrictFPOpcode(N->getOpcode());
+  const SelectionDAGTargetInfo &TSInfo = DAG.getSelectionDAGInfo();
+  bool IsStrict = TSInfo.isTargetStrictFPOpcode(N->getOpcode());
   EVT VT = N->getValueType(0);
 
   // Convert a full vector load into vzload when not all bits are needed.
@@ -55115,9 +54647,9 @@ static SDValue combineFMA(SDNode *N, SelectionDAG &DAG,
                           const X86Subtarget &Subtarget) {
   SDLoc dl(N);
   EVT VT = N->getValueType(0);
-  const SelectionDAGTargetInfo &TSI = DAG.getSelectionDAGInfo();
+  const SelectionDAGTargetInfo &TSInfo = DAG.getSelectionDAGInfo();
   bool IsStrict = N->isTargetOpcode()
-                      ? TSI.isTargetStrictFPOpcode(N->getOpcode())
+                      ? TSInfo.isTargetStrictFPOpcode(N->getOpcode())
                       : N->isStrictFPOpcode();
 
   // Let legalize expand this if it isn't a legal type yet.
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index 2b7a8eaf249d83..0219532665f256 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_LIB_TARGET_X86_X86ISELLOWERING_H
 #define LLVM_LIB_TARGET_X86_X86ISELLOWERING_H
 
+#include "X86SelectionDAGInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/TargetLowering.h"
 
@@ -21,968 +22,6 @@ namespace llvm {
   class X86Subtarget;
   class X86TargetMachine;
 
-  namespace X86ISD {
-    // X86 Specific DAG Nodes
-  enum NodeType : unsigned {
-    // Start the numbering where the builtin ops leave off.
-    FIRST_NUMBER = ISD::BUILTIN_OP_END,
-
-    /// Bit scan forward.
-    BSF,
-    /// Bit scan reverse.
-    BSR,
-
-    /// X86 funnel/double shift i16 instructions. These correspond to
-    /// X86::SHLDW and X86::SHRDW instructions which have different amt
-    /// modulo rules to generic funnel shifts.
-    /// NOTE: The operand order matches ISD::FSHL/FSHR not SHLD/SHRD.
-    FSHL,
-    FSHR,
-
-    /// Bitwise logical AND of floating point values. This corresponds
-    /// to X86::ANDPS or X86::ANDPD.
-    FAND,
-
-    /// Bitwise logical OR of floating point values. This corresponds
-    /// to X86::ORPS or X86::ORPD.
-    FOR,
-
-    /// Bitwise logical XOR of floating point values. This corresponds
-    /// to X86::XORPS or X86::XORPD.
-    FXOR,
-
-    ///  Bitwise logical ANDNOT of floating point values. This
-    /// corresponds to X86::ANDNPS or X86::ANDNPD.
-    FANDN,
-
-    /// These operations represent an abstract X86 call
-    /// instruction, which includes a bunch of information.  In particular the
-    /// operands of these node are:
-    ///
-    ///     #0 - The incoming token chain
-    ///     #1 - The callee
-    ///     #2 - The number of arg bytes the caller pushes on the stack.
-    ///     #3 - The number of arg bytes the callee pops off the stack.
-    ///     #4 - The value to pass in AL/AX/EAX (optional)
-    ///     #5 - The value to pass in DL/DX/EDX (optional)
-    ///
-    /// The result values of these nodes are:
-    ///
-    ///     #0 - The outgoing token chain
-    ///     #1 - The first register result value (optional)
-    ///     #2 - The second register result value (optional)
-    ///
-    CALL,
-
-    /// Same as call except it adds the NoTrack prefix.
-    NT_CALL,
-
-    // Pseudo for a OBJC call that gets emitted together with a special
-    // marker instruction.
-    CALL_RVMARKER,
-
-    /// X86 compare and logical compare instructions.
-    CMP,
-    FCMP,
-    COMI,
-    UCOMI,
-
-    // X86 compare with Intrinsics similar to COMI.
-    COMX,
-    UCOMX,
-
-    /// X86 bit-test instructions.
-    BT,
-
-    /// X86 SetCC. Operand 0 is condition code, and operand 1 is the EFLAGS
-    /// operand, usually produced by a CMP instruction.
-    SETCC,
-
-    /// X86 Select
-    SELECTS,
-
-    // Same as SETCC except it's materialized with a sbb and the value is all
-    // one's or all zero's.
-    SETCC_CARRY, // R = carry_bit ? ~0 : 0
-
-    /// X86 FP SETCC, implemented with CMP{cc}SS/CMP{cc}SD.
-    /// Operands are two FP values to compare; result is a mask of
-    /// 0s or 1s.  Generally DTRT for C/C++ with NaNs.
-    FSETCC,
-
-    /// X86 FP SETCC, similar to above, but with output as an i1 mask and
-    /// and a version with SAE.
-    FSETCCM,
-    FSETCCM_SAE,
-
-    /// X86 conditional moves. Operand 0 and operand 1 are the two values
-    /// to select from. Operand 2 is the condition code, and operand 3 is the
-    /// flag operand produced by a CMP or TEST instruction.
-    CMOV,
-
-    /// X86 conditional branches. Operand 0 is the chain operand, operand 1
-    /// is the block to branch if condition is true, operand 2 is the
-    /// condition code, and operand 3 is the flag operand produced by a CMP
-    /// or TEST instruction.
-    BRCOND,
-
-    /// BRIND node with NoTrack prefix. Operand 0 is the chain operand and
-    /// operand 1 is the target address.
-    NT_BRIND,
-
-    /// Return with a glue operand. Operand 0 is the chain operand, operand
-    /// 1 is the number of bytes of stack to pop.
-    RET_GLUE,
-
-    /// Return from interrupt. Operand 0 is the number of bytes to pop.
-    IRET,
-
-    /// Repeat fill, corresponds to X86::REP_STOSx.
-    REP_STOS,
-
-    /// Repeat move, corresponds to X86::REP_MOVSx.
-    REP_MOVS,
-
-    /// On Darwin, this node represents the result of the popl
-    /// at function entry, used for PIC code.
-    GlobalBaseReg,
-
-    /// A wrapper node for TargetConstantPool, TargetJumpTable,
-    /// TargetExternalSymbol, TargetGlobalAddress, TargetGlobalTLSAddress,
-    /// MCSymbol and TargetBlockAddress.
-    Wrapper,
-
-    /// Special wrapper used under X86-64 PIC mode for RIP
-    /// relative displacements.
-    WrapperRIP,
-
-    /// Copies a 64-bit value from an MMX vector to the low word
-    /// of an XMM vector, with the high word zero filled.
-    MOVQ2DQ,
-
-    /// Copies a 64-bit value from the low word of an XMM vector
-    /// to an MMX vector.
-    MOVDQ2Q,
-
-    /// Copies a 32-bit value from the low word of a MMX
-    /// vector to a GPR.
-    MMX_MOVD2W,
-
-    /// Copies a GPR into the low 32-bit word of a MMX vector
-    /// and zero out the high word.
-    MMX_MOVW2D,
-
-    /// Extract an 8-bit value from a vector and zero extend it to
-    /// i32, corresponds to X86::PEXTRB.
-    PEXTRB,
-
-    /// Extract a 16-bit value from a vector and zero extend it to
-    /// i32, corresponds to X86::PEXTRW.
-    PEXTRW,
-
-    /// Insert any element of a 4 x float vector into any element
-    /// of a destination 4 x floatvector.
-    INSERTPS,
-
-    /// Insert the lower 8-bits of a 32-bit value to a vector,
-    /// corresponds to X86::PINSRB.
-    PINSRB,
-
-    /// Insert the lower 16-bits of a 32-bit value to a vector,
-    /// corresponds to X86::PINSRW.
-    PINSRW,
-
-    /// Shuffle 16 8-bit values within a vector.
-    PSHUFB,
-
-    /// Compute Sum of Absolute Differences.
-    PSADBW,
-    /// Compute Double Block Packed Sum-Absolute-Differences
-    DBPSADBW,
-
-    /// Bitwise Logical AND NOT of Packed FP values.
-    ANDNP,
-
-    /// Blend where the selector is an immediate.
-    BLENDI,
-
-    /// Dynamic (non-constant condition) vector blend where only the sign bits
-    /// of the condition elements are used. This is used to enforce that the
-    /// condition mask is not valid for generic VSELECT optimizations. This
-    /// is also used to implement the intrinsics.
-    /// Operands are in VSELECT order: MASK, TRUE, FALSE
-    BLENDV,
-
-    /// Combined add and sub on an FP vector.
-    ADDSUB,
-
-    //  FP vector ops with rounding mode.
-    FADD_RND,
-    FADDS,
-    FADDS_RND,
-    FSUB_RND,
-    FSUBS,
-    FSUBS_RND,
-    FMUL_RND,
-    FMULS,
-    FMULS_RND,
-    FDIV_RND,
-    FDIVS,
-    FDIVS_RND,
-    FMAX_SAE,
-    FMAXS_SAE,
-    FMIN_SAE,
-    FMINS_SAE,
-    FSQRT_RND,
-    FSQRTS,
-    FSQRTS_RND,
-
-    // FP vector get exponent.
-    FGETEXP,
-    FGETEXP_SAE,
-    FGETEXPS,
-    FGETEXPS_SAE,
-    // Extract Normalized Mantissas.
-    VGETMANT,
-    VGETMANT_SAE,
-    VGETMANTS,
-    VGETMANTS_SAE,
-    // FP Scale.
-    SCALEF,
-    SCALEF_RND,
-    SCALEFS,
-    SCALEFS_RND,
-
-    /// Integer horizontal add/sub.
-    HADD,
-    HSUB,
-
-    /// Floating point horizontal add/sub.
-    FHADD,
-    FHSUB,
-
-    // Detect Conflicts Within a Vector
-    CONFLICT,
-
-    /// Floating point max and min.
-    FMAX,
-    FMIN,
-
-    /// Commutative FMIN and FMAX.
-    FMAXC,
-    FMINC,
-
-    /// Scalar intrinsic floating point max and min.
-    FMAXS,
-    FMINS,
-
-    /// Floating point reciprocal-sqrt and reciprocal approximation.
-    /// Note that these typically require refinement
-    /// in order to obtain suitable precision.
-    FRSQRT,
-    FRCP,
-
-    // AVX-512 reciprocal approximations with a little more precision.
-    RSQRT14,
-    RSQRT14S,
-    RCP14,
-    RCP14S,
-
-    // Thread Local Storage.
-    TLSADDR,
-
-    // Thread Local Storage. A call to get the start address
-    // of the TLS block for the current module.
-    TLSBASEADDR,
-
-    // Thread Local Storage.  When calling to an OS provided
-    // thunk at the address from an earlier relocation.
-    TLSCALL,
-
-    // Thread Local Storage. A descriptor containing pointer to
-    // code and to argument to get the TLS offset for the symbol.
-    TLSDESC,
-
-    // Exception Handling helpers.
-    EH_RETURN,
-
-    // SjLj exception handling setjmp.
-    EH_SJLJ_SETJMP,
-
-    // SjLj exception handling longjmp.
-    EH_SJLJ_LONGJMP,
-
-    // SjLj exception handling dispatch.
-    EH_SJLJ_SETUP_DISPATCH,
-
-    /// Tail call return. See X86TargetLowering::LowerCall for
-    /// the list of operands.
-    TC_RETURN,
-
-    // Vector move to low scalar and zero higher vector elements.
-    VZEXT_MOVL,
-
-    // Vector integer truncate.
-    VTRUNC,
-    // Vector integer truncate with unsigned/signed saturation.
-    VTRUNCUS,
-    VTRUNCS,
-
-    // Masked version of the above. Used when less than a 128-bit result is
-    // produced since the mask only applies to the lower elements and can't
-    // be represented by a select.
-    // SRC, PASSTHRU, MASK
-    VMTRUNC,
-    VMTRUNCUS,
-    VMTRUNCS,
-
-    // Vector FP extend.
-    VFPEXT,
-    VFPEXT_SAE,
-    VFPEXTS,
-    VFPEXTS_SAE,
-
-    // Vector FP round.
-    VFPROUND,
-    // Convert TWO packed single data to one packed data
-    VFPROUND2,
-    VFPROUND2_RND,
-    VFPROUND_RND,
-    VFPROUNDS,
-    VFPROUNDS_RND,
-
-    // Masked version of above. Used for v2f64->v4f32.
-    // SRC, PASSTHRU, MASK
-    VMFPROUND,
-
-    // 128-bit vector logical left / right shift
-    VSHLDQ,
-    VSRLDQ,
-
-    // Vector shift elements
-    VSHL,
-    VSRL,
-    VSRA,
-
-    // Vector variable shift
-    VSHLV,
-    VSRLV,
-    VSRAV,
-
-    // Vector shift elements by immediate
-    VSHLI,
-    VSRLI,
-    VSRAI,
-
-    // Shifts of mask registers.
-    KSHIFTL,
-    KSHIFTR,
-
-    // Bit rotate by immediate
-    VROTLI,
-    VROTRI,
-
-    // Vector packed double/float comparison.
-    CMPP,
-
-    // Vector integer comparisons.
-    PCMPEQ,
-    PCMPGT,
-
-    // v8i16 Horizontal minimum and position.
-    PHMINPOS,
-
-    MULTISHIFT,
-
-    /// Vector comparison generating mask bits for fp and
-    /// integer signed and unsigned data types.
-    CMPM,
-    // Vector mask comparison generating mask bits for FP values.
-    CMPMM,
-    // Vector mask comparison with SAE for FP values.
-    CMPMM_SAE,
-
-    // Arithmetic operations with FLAGS results.
-    ADD,
-    SUB,
-    ADC,
-    SBB,
-    SMUL,
-    UMUL,
-    OR,
-    XOR,
-    AND,
-
-    // Bit field extract.
-    BEXTR,
-    BEXTRI,
-
-    // Zero High Bits Starting with Specified Bit Position.
-    BZHI,
-
-    // Parallel extract and deposit.
-    PDEP,
-    PEXT,
-
-    // X86-specific multiply by immediate.
-    MUL_IMM,
-
-    // Vector sign bit extraction.
-    MOVMSK,
-
-    // Vector bitwise comparisons.
-    PTEST,
-
-    // Vector packed fp sign bitwise comparisons.
-    TESTP,
-
-    // OR/AND test for masks.
-    KORTEST,
-    KTEST,
-
-    // ADD for masks.
-    KADD,
-
-    // Several flavors of instructions with vector shuffle behaviors.
-    // Saturated signed/unnsigned packing.
-    PACKSS,
-    PACKUS,
-    // Intra-lane alignr.
-    PALIGNR,
-    // AVX512 inter-lane alignr.
-    VALIGN,
-    PSHUFD,
-    PSHUFHW,
-    PSHUFLW,
-    SHUFP,
-    // VBMI2 Concat & Shift.
-    VSHLD,
-    VSHRD,
-    VSHLDV,
-    VSHRDV,
-    // Shuffle Packed Values at 128-bit granularity.
-    SHUF128,
-    MOVDDUP,
-    MOVSHDUP,
-    MOVSLDUP,
-    MOVLHPS,
-    MOVHLPS,
-    MOVSD,
-    MOVSS,
-    MOVSH,
-    UNPCKL,
-    UNPCKH,
-    VPERMILPV,
-    VPERMILPI,
-    VPERMI,
-    VPERM2X128,
-
-    // Variable Permute (VPERM).
-    // Res = VPERMV MaskV, V0
-    VPERMV,
-
-    // 3-op Variable Permute (VPERMT2).
-    // Res = VPERMV3 V0, MaskV, V1
-    VPERMV3,
-
-    // Bitwise ternary logic.
-    VPTERNLOG,
-    // Fix Up Special Packed Float32/64 values.
-    VFIXUPIMM,
-    VFIXUPIMM_SAE,
-    VFIXUPIMMS,
-    VFIXUPIMMS_SAE,
-    // Range Restriction Calculation For Packed Pairs of Float32/64 values.
-    VRANGE,
-    VRANGE_SAE,
-    VRANGES,
-    VRANGES_SAE,
-    // Reduce - Perform Reduction Transformation on scalar\packed FP.
-    VREDUCE,
-    VREDUCE_SAE,
-    VREDUCES,
-    VREDUCES_SAE,
-    // RndScale - Round FP Values To Include A Given Number Of Fraction Bits.
-    // Also used by the legacy (V)ROUND intrinsics where we mask out the
-    // scaling part of the immediate.
-    VRNDSCALE,
-    VRNDSCALE_SAE,
-    VRNDSCALES,
-    VRNDSCALES_SAE,
-    // Tests Types Of a FP Values for packed types.
-    VFPCLASS,
-    // Tests Types Of a FP Values for scalar types.
-    VFPCLASSS,
-
-    // Broadcast (splat) scalar or element 0 of a vector. If the operand is
-    // a vector, this node may change the vector length as part of the splat.
-    VBROADCAST,
-    // Broadcast mask to vector.
-    VBROADCASTM,
-
-    /// SSE4A Extraction and Insertion.
-    EXTRQI,
-    INSERTQI,
-
-    // XOP arithmetic/logical shifts.
-    VPSHA,
-    VPSHL,
-    // XOP signed/unsigned integer comparisons.
-    VPCOM,
-    VPCOMU,
-    // XOP packed permute bytes.
-    VPPERM,
-    // XOP two source permutation.
-    VPERMIL2,
-
-    // Vector multiply packed unsigned doubleword integers.
-    PMULUDQ,
-    // Vector multiply packed signed doubleword integers.
-    PMULDQ,
-    // Vector Multiply Packed UnsignedIntegers with Round and Scale.
-    MULHRS,
-
-    // Multiply and Add Packed Integers.
-    VPMADDUBSW,
-    VPMADDWD,
-
-    // AVX512IFMA multiply and add.
-    // NOTE: These are different than the instruction and perform
-    // op0 x op1 + op2.
-    VPMADD52L,
-    VPMADD52H,
-
-    // VNNI
-    VPDPBUSD,
-    VPDPBUSDS,
-    VPDPWSSD,
-    VPDPWSSDS,
-
-    // FMA nodes.
-    // We use the target independent ISD::FMA for the non-inverted case.
-    FNMADD,
-    FMSUB,
-    FNMSUB,
-    FMADDSUB,
-    FMSUBADD,
-
-    // FMA with rounding mode.
-    FMADD_RND,
-    FNMADD_RND,
-    FMSUB_RND,
-    FNMSUB_RND,
-    FMADDSUB_RND,
-    FMSUBADD_RND,
-
-    // AVX512-FP16 complex addition and multiplication.
-    VFMADDC,
-    VFMADDC_RND,
-    VFCMADDC,
-    VFCMADDC_RND,
-
-    VFMULC,
-    VFMULC_RND,
-    VFCMULC,
-    VFCMULC_RND,
-
-    VFMADDCSH,
-    VFMADDCSH_RND,
-    VFCMADDCSH,
-    VFCMADDCSH_RND,
-
-    VFMULCSH,
-    VFMULCSH_RND,
-    VFCMULCSH,
-    VFCMULCSH_RND,
-
-    VPDPBSUD,
-    VPDPBSUDS,
-    VPDPBUUD,
-    VPDPBUUDS,
-    VPDPBSSD,
-    VPDPBSSDS,
-
-    VPDPWSUD,
-    VPDPWSUDS,
-    VPDPWUSD,
-    VPDPWUSDS,
-    VPDPWUUD,
-    VPDPWUUDS,
-
-    VMINMAX,
-    VMINMAX_SAE,
-    VMINMAXS,
-    VMINMAXS_SAE,
-
-    CVTP2IBS,
-    CVTP2IUBS,
-    CVTP2IBS_RND,
-    CVTP2IUBS_RND,
-    CVTTP2IBS,
-    CVTTP2IUBS,
-    CVTTP2IBS_SAE,
-    CVTTP2IUBS_SAE,
-
-    MPSADBW,
-
-    VCVTNE2PH2BF8,
-    VCVTNE2PH2BF8S,
-    VCVTNE2PH2HF8,
-    VCVTNE2PH2HF8S,
-    VCVTBIASPH2BF8,
-    VCVTBIASPH2BF8S,
-    VCVTBIASPH2HF8,
-    VCVTBIASPH2HF8S,
-    VCVTNEPH2BF8,
-    VCVTNEPH2BF8S,
-    VCVTNEPH2HF8,
-    VCVTNEPH2HF8S,
-    VMCVTBIASPH2BF8,
-    VMCVTBIASPH2BF8S,
-    VMCVTBIASPH2HF8,
-    VMCVTBIASPH2HF8S,
-    VMCVTNEPH2BF8,
-    VMCVTNEPH2BF8S,
-    VMCVTNEPH2HF8,
-    VMCVTNEPH2HF8S,
-    VCVTHF82PH,
-
-    // Compress and expand.
-    COMPRESS,
-    EXPAND,
-
-    // Bits shuffle
-    VPSHUFBITQMB,
-
-    // Convert Unsigned/Integer to Floating-Point Value with rounding mode.
-    SINT_TO_FP_RND,
-    UINT_TO_FP_RND,
-    SCALAR_SINT_TO_FP,
-    SCALAR_UINT_TO_FP,
-    SCALAR_SINT_TO_FP_RND,
-    SCALAR_UINT_TO_FP_RND,
-
-    // Vector float/double to signed/unsigned integer.
-    CVTP2SI,
-    CVTP2UI,
-    CVTP2SI_RND,
-    CVTP2UI_RND,
-    // Scalar float/double to signed/unsigned integer.
-    CVTS2SI,
-    CVTS2UI,
-    CVTS2SI_RND,
-    CVTS2UI_RND,
-
-    // Vector float/double to signed/unsigned integer with truncation.
-    CVTTP2SI,
-    CVTTP2UI,
-    CVTTP2SI_SAE,
-    CVTTP2UI_SAE,
-
-    // Saturation enabled Vector float/double to signed/unsigned
-    // integer with truncation.
-    CVTTP2SIS,
-    CVTTP2UIS,
-    CVTTP2SIS_SAE,
-    CVTTP2UIS_SAE,
-    // Masked versions of above. Used for v2f64 to v4i32.
-    // SRC, PASSTHRU, MASK
-    MCVTTP2SIS,
-    MCVTTP2UIS,
-
-    // Scalar float/double to signed/unsigned integer with truncation.
-    CVTTS2SI,
-    CVTTS2UI,
-    CVTTS2SI_SAE,
-    CVTTS2UI_SAE,
-
-    // Vector signed/unsigned integer to float/double.
-    CVTSI2P,
-    CVTUI2P,
-
-    // Scalar float/double to signed/unsigned integer with saturation.
-    CVTTS2SIS,
-    CVTTS2UIS,
-    CVTTS2SIS_SAE,
-    CVTTS2UIS_SAE,
-
-    // Masked versions of above. Used for v2f64->v4f32.
-    // SRC, PASSTHRU, MASK
-    MCVTP2SI,
-    MCVTP2UI,
-    MCVTTP2SI,
-    MCVTTP2UI,
-    MCVTSI2P,
-    MCVTUI2P,
-
-    // Vector float to bfloat16.
-    // Convert packed single data to packed BF16 data
-    CVTNEPS2BF16,
-    // Masked version of above.
-    // SRC, PASSTHRU, MASK
-    MCVTNEPS2BF16,
-
-    // Dot product of BF16/FP16 pairs to accumulated into
-    // packed single precision.
-    DPBF16PS,
-    DPFP16PS,
-
-    // A stack checking function call. On Windows it's _chkstk call.
-    DYN_ALLOCA,
-
-    // For allocating variable amounts of stack space when using
-    // segmented stacks. Check if the current stacklet has enough space, and
-    // falls back to heap allocation if not.
-    SEG_ALLOCA,
-
-    // For allocating stack space when using stack clash protector.
-    // Allocation is performed by block, and each block is probed.
-    PROBED_ALLOCA,
-
-    // Memory barriers.
-    MFENCE,
-
-    // Get a random integer and indicate whether it is valid in CF.
-    RDRAND,
-
-    // Get a NIST SP800-90B & C compliant random integer and
-    // indicate whether it is valid in CF.
-    RDSEED,
-
-    // Protection keys
-    // RDPKRU - Operand 0 is chain. Operand 1 is value for ECX.
-    // WRPKRU - Operand 0 is chain. Operand 1 is value for EDX. Operand 2 is
-    // value for ECX.
-    RDPKRU,
-    WRPKRU,
-
-    // SSE42 string comparisons.
-    // These nodes produce 3 results, index, mask, and flags. X86ISelDAGToDAG
-    // will emit one or two instructions based on which results are used. If
-    // flags and index/mask this allows us to use a single instruction since
-    // we won't have to pick and opcode for flags. Instead we can rely on the
-    // DAG to CSE everything and decide at isel.
-    PCMPISTR,
-    PCMPESTR,
-
-    // Test if in transactional execution.
-    XTEST,
-
-    // Conversions between float and half-float.
-    CVTPS2PH,
-    CVTPS2PH_SAE,
-    CVTPH2PS,
-    CVTPH2PS_SAE,
-
-    // Masked version of above.
-    // SRC, RND, PASSTHRU, MASK
-    MCVTPS2PH,
-    MCVTPS2PH_SAE,
-
-    // Galois Field Arithmetic Instructions
-    GF2P8AFFINEINVQB,
-    GF2P8AFFINEQB,
-    GF2P8MULB,
-
-    // LWP insert record.
-    LWPINS,
-
-    // User level wait
-    UMWAIT,
-    TPAUSE,
-
-    // Enqueue Stores Instructions
-    ENQCMD,
-    ENQCMDS,
-
-    // For avx512-vp2intersect
-    VP2INTERSECT,
-
-    // User level interrupts - testui
-    TESTUI,
-
-    // Perform an FP80 add after changing precision control in FPCW.
-    FP80_ADD,
-
-    // Conditional compare instructions
-    CCMP,
-    CTEST,
-
-    /// X86 strict FP compare instructions.
-    FIRST_STRICTFP_OPCODE,
-    STRICT_FCMP = FIRST_STRICTFP_OPCODE,
-    STRICT_FCMPS,
-
-    // Vector packed double/float comparison.
-    STRICT_CMPP,
-
-    /// Vector comparison generating mask bits for fp and
-    /// integer signed and unsigned data types.
-    STRICT_CMPM,
-
-    // Vector float/double to signed/unsigned integer with truncation.
-    STRICT_CVTTP2SI,
-    STRICT_CVTTP2UI,
-
-    // Vector FP extend.
-    STRICT_VFPEXT,
-
-    // Vector FP round.
-    STRICT_VFPROUND,
-
-    // RndScale - Round FP Values To Include A Given Number Of Fraction Bits.
-    // Also used by the legacy (V)ROUND intrinsics where we mask out the
-    // scaling part of the immediate.
-    STRICT_VRNDSCALE,
-
-    // Vector signed/unsigned integer to float/double.
-    STRICT_CVTSI2P,
-    STRICT_CVTUI2P,
-
-    // Strict FMA nodes.
-    STRICT_FNMADD,
-    STRICT_FMSUB,
-    STRICT_FNMSUB,
-
-    // Conversions between float and half-float.
-    STRICT_CVTPS2PH,
-    STRICT_CVTPH2PS,
-
-    // Perform an FP80 add after changing precision control in FPCW.
-    STRICT_FP80_ADD,
-
-    /// Floating point max and min.
-    STRICT_FMAX,
-    STRICT_FMIN,
-    LAST_STRICTFP_OPCODE = STRICT_FMIN,
-
-    // Compare and swap.
-    FIRST_MEMORY_OPCODE,
-    LCMPXCHG_DAG = FIRST_MEMORY_OPCODE,
-    LCMPXCHG8_DAG,
-    LCMPXCHG16_DAG,
-    LCMPXCHG16_SAVE_RBX_DAG,
-
-    /// LOCK-prefixed arithmetic read-modify-write instructions.
-    /// EFLAGS, OUTCHAIN = LADD(INCHAIN, PTR, RHS)
-    LADD,
-    LSUB,
-    LOR,
-    LXOR,
-    LAND,
-    LBTS,
-    LBTC,
-    LBTR,
-    LBTS_RM,
-    LBTC_RM,
-    LBTR_RM,
-
-    /// RAO arithmetic instructions.
-    /// OUTCHAIN = AADD(INCHAIN, PTR, RHS)
-    AADD,
-    AOR,
-    AXOR,
-    AAND,
-
-    // Load, scalar_to_vector, and zero extend.
-    VZEXT_LOAD,
-
-    // extract_vector_elt, store.
-    VEXTRACT_STORE,
-
-    // scalar broadcast from memory.
-    VBROADCAST_LOAD,
-
-    // subvector broadcast from memory.
-    SUBV_BROADCAST_LOAD,
-
-    // Store FP control word into i16 memory.
-    FNSTCW16m,
-
-    // Load FP control word from i16 memory.
-    FLDCW16m,
-
-    // Store x87 FPU environment into memory.
-    FNSTENVm,
-
-    // Load x87 FPU environment from memory.
-    FLDENVm,
-
-    /// This instruction implements FP_TO_SINT with the
-    /// integer destination in memory and a FP reg source.  This corresponds
-    /// to the X86::FIST*m instructions and the rounding mode change stuff. It
-    /// has two inputs (token chain and address) and two outputs (int value
-    /// and token chain). Memory VT specifies the type to store to.
-    FP_TO_INT_IN_MEM,
-
-    /// This instruction implements SINT_TO_FP with the
-    /// integer source in memory and FP reg result.  This corresponds to the
-    /// X86::FILD*m instructions. It has two inputs (token chain and address)
-    /// and two outputs (FP value and token chain). The integer source type is
-    /// specified by the memory VT.
-    FILD,
-
-    /// This instruction implements a fp->int store from FP stack
-    /// slots. This corresponds to the fist instruction. It takes a
-    /// chain operand, value to store, address, and glue. The memory VT
-    /// specifies the type to store as.
-    FIST,
-
-    /// This instruction implements an extending load to FP stack slots.
-    /// This corresponds to the X86::FLD32m / X86::FLD64m. It takes a chain
-    /// operand, and ptr to load from. The memory VT specifies the type to
-    /// load from.
-    FLD,
-
-    /// This instruction implements a truncating store from FP stack
-    /// slots. This corresponds to the X86::FST32m / X86::FST64m. It takes a
-    /// chain operand, value to store, address, and glue. The memory VT
-    /// specifies the type to store as.
-    FST,
-
-    /// These instructions grab the address of the next argument
-    /// from a va_list. (reads and modifies the va_list in memory)
-    VAARG_64,
-    VAARG_X32,
-
-    // Vector truncating store with unsigned/signed saturation
-    VTRUNCSTOREUS,
-    VTRUNCSTORES,
-    // Vector truncating masked store with unsigned/signed saturation
-    VMTRUNCSTOREUS,
-    VMTRUNCSTORES,
-
-    // X86 specific gather and scatter
-    MGATHER,
-    MSCATTER,
-
-    // Key locker nodes that produce flags.
-    AESENC128KL,
-    AESDEC128KL,
-    AESENC256KL,
-    AESDEC256KL,
-    AESENCWIDE128KL,
-    AESDECWIDE128KL,
-    AESENCWIDE256KL,
-    AESDECWIDE256KL,
-
-    /// Compare and Add if Condition is Met. Compare value in operand 2 with
-    /// value in memory of operand 1. If condition of operand 4 is met, add
-    /// value operand 3 to m32 and write new value in operand 1. Operand 2 is
-    /// always updated with the original value from operand 1.
-    CMPCCXADD,
-
-    // Save xmm argument registers to the stack, according to %al. An operator
-    // is needed so that this can be expanded with control flow.
-    VASTART_SAVE_XMM_REGS,
-
-    // Conditional load/store instructions
-    CLOAD,
-    CSTORE,
-    LAST_MEMORY_OPCODE = CSTORE,
-  };
-  } // end namespace X86ISD
-
   namespace X86 {
     /// Current rounding mode is represented in bits 11:10 of FPSR. These
     /// values are same as corresponding constants for rounding mode used
@@ -1165,9 +204,6 @@ namespace llvm {
     EmitInstrWithCustomInserter(MachineInstr &MI,
                                 MachineBasicBlock *MBB) const override;
 
-    /// This method returns the name of a target specific DAG node.
-    const char *getTargetNodeName(unsigned Opcode) const override;
-
     /// Do not merge vector stores after legalization because that may conflict
     /// with x86-specific store splitting optimizations.
     bool mergeStoresAfterLegalization(EVT MemVT) const override {
diff --git a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
index 05a5a36ce5cbe4..0a85629c514347 100644
--- a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
+++ b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
@@ -933,10 +933,10 @@ X86TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
   if (Glue.getNode())
     RetOps.push_back(Glue);
 
-  X86ISD::NodeType opcode = X86ISD::RET_GLUE;
+  unsigned RetOpcode = X86ISD::RET_GLUE;
   if (CallConv == CallingConv::X86_INTR)
-    opcode = X86ISD::IRET;
-  return DAG.getNode(opcode, dl, MVT::Other, RetOps);
+    RetOpcode = X86ISD::IRET;
+  return DAG.getNode(RetOpcode, dl, MVT::Other, RetOps);
 }
 
 bool X86TargetLowering::isUsedByReturnOnly(SDNode *N, SDValue &Chain) const {
diff --git a/llvm/lib/Target/X86/X86InstrFragments.td b/llvm/lib/Target/X86/X86InstrFragments.td
index ea7af893ce103f..aa8d7fc9f5e4a5 100644
--- a/llvm/lib/Target/X86/X86InstrFragments.td
+++ b/llvm/lib/Target/X86/X86InstrFragments.td
@@ -141,8 +141,12 @@ def X86fshr    : SDNode<"X86ISD::FSHR",     SDTIntShiftDOp>;
 
 def X86cmp     : SDNode<"X86ISD::CMP" ,     SDTX86CmpTest>;
 def X86fcmp    : SDNode<"X86ISD::FCMP",     SDTX86FCmp>;
-def X86strict_fcmp : SDNode<"X86ISD::STRICT_FCMP", SDTX86FCmp, [SDNPHasChain]>;
-def X86strict_fcmps : SDNode<"X86ISD::STRICT_FCMPS", SDTX86FCmp, [SDNPHasChain]>;
+
+let IsStrictFP = true in {
+  def X86strict_fcmp  : SDNode<"X86ISD::STRICT_FCMP",  SDTX86FCmp, [SDNPHasChain]>;
+  def X86strict_fcmps : SDNode<"X86ISD::STRICT_FCMPS", SDTX86FCmp, [SDNPHasChain]>;
+}
+
 def X86bt      : SDNode<"X86ISD::BT",       SDTX86CmpTest>;
 
 def X86ccmp    : SDNode<"X86ISD::CCMP",     SDTX86Ccmp>;
@@ -758,8 +762,11 @@ def SDTX86CwdLoad   : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
 def SDTX86FPEnv     : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
 
 def X86fp80_add     : SDNode<"X86ISD::FP80_ADD", SDTFPBinOp, [SDNPCommutative]>;
+
+let IsStrictFP = true in
 def X86strict_fp80_add : SDNode<"X86ISD::STRICT_FP80_ADD", SDTFPBinOp,
                         [SDNPHasChain,SDNPCommutative]>;
+
 def any_X86fp80_add : PatFrags<(ops node:$lhs, node:$rhs),
                                [(X86strict_fp80_add node:$lhs, node:$rhs),
                                 (X86fp80_add node:$lhs, node:$rhs)]>;
diff --git a/llvm/lib/Target/X86/X86InstrFragmentsSIMD.td b/llvm/lib/Target/X86/X86InstrFragmentsSIMD.td
index f6231b78f4c2e8..fd460952e0a22c 100644
--- a/llvm/lib/Target/X86/X86InstrFragmentsSIMD.td
+++ b/llvm/lib/Target/X86/X86InstrFragmentsSIMD.td
@@ -46,10 +46,12 @@ def X86fminc    : SDNode<"X86ISD::FMINC", SDTFPBinOp,
 def X86fmaxc    : SDNode<"X86ISD::FMAXC", SDTFPBinOp,
     [SDNPCommutative, SDNPAssociative]>;
 
-def X86strict_fmin : SDNode<"X86ISD::STRICT_FMIN", SDTFPBinOp,
-                            [SDNPHasChain]>;
-def X86strict_fmax : SDNode<"X86ISD::STRICT_FMAX", SDTFPBinOp,
-                            [SDNPHasChain]>;
+let IsStrictFP = true in {
+  def X86strict_fmin : SDNode<"X86ISD::STRICT_FMIN", SDTFPBinOp,
+                              [SDNPHasChain]>;
+  def X86strict_fmax : SDNode<"X86ISD::STRICT_FMAX", SDTFPBinOp,
+                              [SDNPHasChain]>;
+}
 
 def X86any_fmin : PatFrags<(ops node:$src1, node:$src2),
                            [(X86strict_fmin node:$src1, node:$src2),
@@ -146,6 +148,7 @@ def X86vfpext  : SDNode<"X86ISD::VFPEXT",
                         SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVec<0>,
                                              SDTCisFP<1>, SDTCisVec<1>]>>;
 
+let IsStrictFP = true in
 def X86strict_vfpext  : SDNode<"X86ISD::STRICT_VFPEXT",
                                SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVec<0>,
                                                     SDTCisFP<1>, SDTCisVec<1>]>,
@@ -165,6 +168,7 @@ def X86vfpround2 : SDNode<"X86ISD::VFPROUND2",
                                                SDTCisSameAs<1, 2>,
                                                SDTCisOpSmallerThanOp<0, 1>]>>;
 
+let IsStrictFP = true in
 def X86strict_vfpround: SDNode<"X86ISD::STRICT_VFPROUND",
                         SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVec<0>,
                                              SDTCisFP<1>, SDTCisVec<1>,
@@ -215,7 +219,10 @@ def X86pcmpeq  : SDNode<"X86ISD::PCMPEQ", SDTIntBinOp, [SDNPCommutative]>;
 def X86pcmpgt  : SDNode<"X86ISD::PCMPGT", SDTIntBinOp>;
 
 def X86cmpp    : SDNode<"X86ISD::CMPP",      SDTX86VFCMP>;
+
+let IsStrictFP = true in
 def X86strict_cmpp : SDNode<"X86ISD::STRICT_CMPP", SDTX86VFCMP, [SDNPHasChain]>;
+
 def X86any_cmpp    : PatFrags<(ops node:$src1, node:$src2, node:$src3),
                                [(X86strict_cmpp node:$src1, node:$src2, node:$src3),
                                 (X86cmpp node:$src1, node:$src2, node:$src3)]>;
@@ -235,7 +242,10 @@ def X86CmpMaskCCScalar :
 
 def X86cmpm     : SDNode<"X86ISD::CMPM",     X86CmpMaskCC>;
 def X86cmpmm    : SDNode<"X86ISD::CMPMM",    X86MaskCmpMaskCC>;
+
+let IsStrictFP = true in
 def X86strict_cmpm : SDNode<"X86ISD::STRICT_CMPM", X86CmpMaskCC, [SDNPHasChain]>;
+
 def X86any_cmpm    : PatFrags<(ops node:$src1, node:$src2, node:$src3),
                                [(X86strict_cmpm node:$src1, node:$src2, node:$src3),
                                 (X86cmpm node:$src1, node:$src2, node:$src3)]>;
@@ -497,8 +507,11 @@ def X86VRangeSAE   : SDNode<"X86ISD::VRANGE_SAE",    SDTFPBinOpImm>;
 def X86VReduce     : SDNode<"X86ISD::VREDUCE",       SDTFPUnaryOpImm>;
 def X86VReduceSAE  : SDNode<"X86ISD::VREDUCE_SAE",   SDTFPUnaryOpImm>;
 def X86VRndScale   : SDNode<"X86ISD::VRNDSCALE",     SDTFPUnaryOpImm>;
+
+let IsStrictFP = true in
 def X86strict_VRndScale : SDNode<"X86ISD::STRICT_VRNDSCALE", SDTFPUnaryOpImm,
                                   [SDNPHasChain]>;
+
 def X86any_VRndScale    : PatFrags<(ops node:$src1, node:$src2),
                                     [(X86strict_VRndScale node:$src1, node:$src2),
                                     (X86VRndScale node:$src1, node:$src2)]>;
@@ -557,17 +570,26 @@ def X86fgetexps     : SDNode<"X86ISD::FGETEXPS", SDTFPBinOp>;
 def X86fgetexpSAEs  : SDNode<"X86ISD::FGETEXPS_SAE", SDTFPBinOp>;
 
 def X86Fnmadd    : SDNode<"X86ISD::FNMADD",    SDTFPTernaryOp, [SDNPCommutative]>;
+
+let IsStrictFP = true in
 def X86strict_Fnmadd : SDNode<"X86ISD::STRICT_FNMADD", SDTFPTernaryOp, [SDNPCommutative, SDNPHasChain]>;
+
 def X86any_Fnmadd : PatFrags<(ops node:$src1, node:$src2, node:$src3),
                              [(X86strict_Fnmadd node:$src1, node:$src2, node:$src3),
                               (X86Fnmadd node:$src1, node:$src2, node:$src3)]>;
 def X86Fmsub     : SDNode<"X86ISD::FMSUB",     SDTFPTernaryOp, [SDNPCommutative]>;
+
+let IsStrictFP = true in
 def X86strict_Fmsub : SDNode<"X86ISD::STRICT_FMSUB",     SDTFPTernaryOp, [SDNPCommutative, SDNPHasChain]>;
+
 def X86any_Fmsub : PatFrags<(ops node:$src1, node:$src2, node:$src3),
                             [(X86strict_Fmsub node:$src1, node:$src2, node:$src3),
                              (X86Fmsub node:$src1, node:$src2, node:$src3)]>;
 def X86Fnmsub    : SDNode<"X86ISD::FNMSUB",    SDTFPTernaryOp, [SDNPCommutative]>;
+
+let IsStrictFP = true in
 def X86strict_Fnmsub : SDNode<"X86ISD::STRICT_FNMSUB",    SDTFPTernaryOp, [SDNPCommutative, SDNPHasChain]>;
+
 def X86any_Fnmsub : PatFrags<(ops node:$src1, node:$src2, node:$src3),
                              [(X86strict_Fnmsub node:$src1, node:$src2, node:$src3),
                               (X86Fnmsub node:$src1, node:$src2, node:$src3)]>;
@@ -712,8 +734,12 @@ def X86cvtp2UIntRnd     : SDNode<"X86ISD::CVTP2UI_RND",  SDTFloatToIntRnd>;
 // cvtt fp-to-int staff
 def X86cvttp2si      : SDNode<"X86ISD::CVTTP2SI",  SDTFloatToInt>;
 def X86cvttp2ui      : SDNode<"X86ISD::CVTTP2UI",  SDTFloatToInt>;
-def X86strict_cvttp2si : SDNode<"X86ISD::STRICT_CVTTP2SI",  SDTFloatToInt, [SDNPHasChain]>;
-def X86strict_cvttp2ui : SDNode<"X86ISD::STRICT_CVTTP2UI",  SDTFloatToInt, [SDNPHasChain]>;
+
+let IsStrictFP = true in {
+  def X86strict_cvttp2si : SDNode<"X86ISD::STRICT_CVTTP2SI",  SDTFloatToInt, [SDNPHasChain]>;
+  def X86strict_cvttp2ui : SDNode<"X86ISD::STRICT_CVTTP2UI",  SDTFloatToInt, [SDNPHasChain]>;
+}
+
 def X86any_cvttp2si : PatFrags<(ops node:$src),
                                [(X86strict_cvttp2si node:$src),
                                 (X86cvttp2si node:$src)]>;
@@ -723,8 +749,12 @@ def X86any_cvttp2ui : PatFrags<(ops node:$src),
 
 def X86VSintToFP      : SDNode<"X86ISD::CVTSI2P",  SDTVintToFP>;
 def X86VUintToFP      : SDNode<"X86ISD::CVTUI2P",  SDTVintToFP>;
-def X86strict_VSintToFP : SDNode<"X86ISD::STRICT_CVTSI2P",  SDTVintToFP, [SDNPHasChain]>;
-def X86strict_VUintToFP : SDNode<"X86ISD::STRICT_CVTUI2P",  SDTVintToFP, [SDNPHasChain]>;
+
+let IsStrictFP = true in {
+  def X86strict_VSintToFP : SDNode<"X86ISD::STRICT_CVTSI2P", SDTVintToFP, [SDNPHasChain]>;
+  def X86strict_VUintToFP : SDNode<"X86ISD::STRICT_CVTUI2P", SDTVintToFP, [SDNPHasChain]>;
+}
+
 def X86any_VSintToFP : PatFrags<(ops node:$src),
                                 [(X86strict_VSintToFP node:$src),
                                  (X86VSintToFP node:$src)]>;
@@ -764,8 +794,11 @@ def X86mcvttp2uis     : SDNode<"X86ISD::MCVTTP2UIS", SDTMFloatToInt>;
 def SDTcvtph2ps : SDTypeProfile<1, 1, [SDTCVecEltisVT<0, f32>,
                                        SDTCVecEltisVT<1, i16>]>;
 def X86cvtph2ps        : SDNode<"X86ISD::CVTPH2PS", SDTcvtph2ps>;
+
+let IsStrictFP = true in
 def X86strict_cvtph2ps : SDNode<"X86ISD::STRICT_CVTPH2PS", SDTcvtph2ps,
                                 [SDNPHasChain]>;
+
 def X86any_cvtph2ps : PatFrags<(ops node:$src),
                                [(X86strict_cvtph2ps node:$src),
                                 (X86cvtph2ps node:$src)]>;
@@ -776,8 +809,11 @@ def SDTcvtps2ph : SDTypeProfile<1, 2, [SDTCVecEltisVT<0, i16>,
                                        SDTCVecEltisVT<1, f32>,
                                        SDTCisVT<2, i32>]>;
 def X86cvtps2ph        : SDNode<"X86ISD::CVTPS2PH", SDTcvtps2ph>;
+
+let IsStrictFP = true in
 def X86strict_cvtps2ph : SDNode<"X86ISD::STRICT_CVTPS2PH", SDTcvtps2ph,
                                 [SDNPHasChain]>;
+
 def X86any_cvtps2ph : PatFrags<(ops node:$src1, node:$src2),
                                [(X86strict_cvtps2ph node:$src1, node:$src2),
                                 (X86cvtps2ph node:$src1, node:$src2)]>;
diff --git a/llvm/lib/Target/X86/X86SelectionDAGInfo.cpp b/llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
index a21c4d714311e4..4c0ae6b31403cb 100644
--- a/llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
+++ b/llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
@@ -11,7 +11,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "X86SelectionDAGInfo.h"
-#include "X86ISelLowering.h"
 #include "X86InstrInfo.h"
 #include "X86RegisterInfo.h"
 #include "X86Subtarget.h"
@@ -19,6 +18,9 @@
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/CodeGen/TargetLowering.h"
 
+#define GET_SDNODE_DESC
+#include "X86GenSDNodeInfo.inc"
+
 using namespace llvm;
 
 #define DEBUG_TYPE "x86-selectiondag-info"
@@ -27,18 +29,72 @@ static cl::opt<bool>
     UseFSRMForMemcpy("x86-use-fsrm-for-memcpy", cl::Hidden, cl::init(false),
                      cl::desc("Use fast short rep mov in memcpy lowering"));
 
+X86SelectionDAGInfo::X86SelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(X86GenSDNodeInfo) {}
+
+const char *X86SelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
+#define NODE_NAME_CASE(NODE)                                                   \
+  case X86ISD::NODE:                                                           \
+    return "X86ISD::" #NODE;
+
+  // These nodes don't have corresponding entries in *.td files yet.
+  switch (static_cast<X86ISD::NodeType>(Opcode)) {
+    NODE_NAME_CASE(GlobalBaseReg)
+    NODE_NAME_CASE(LCMPXCHG16_SAVE_RBX_DAG)
+    NODE_NAME_CASE(PCMPESTR)
+    NODE_NAME_CASE(PCMPISTR)
+    NODE_NAME_CASE(MGATHER)
+    NODE_NAME_CASE(MSCATTER)
+    NODE_NAME_CASE(AESENCWIDE128KL)
+    NODE_NAME_CASE(AESDECWIDE128KL)
+    NODE_NAME_CASE(AESENCWIDE256KL)
+    NODE_NAME_CASE(AESDECWIDE256KL)
+  }
+#undef NODE_NAME_CASE
+
+  return SelectionDAGGenTargetInfo::getTargetNodeName(Opcode);
+}
+
 bool X86SelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
-  if (Opcode >= X86ISD::FIRST_MEMORY_OPCODE &&
-      Opcode <= X86ISD::LAST_MEMORY_OPCODE)
+  // These nodes don't have corresponding entries in *.td files yet.
+  switch (static_cast<X86ISD::NodeType>(Opcode)) {
+  default:
+    break;
+  case X86ISD::LCMPXCHG16_SAVE_RBX_DAG:
+  case X86ISD::MGATHER:
+  case X86ISD::MSCATTER:
+  case X86ISD::AESENCWIDE128KL:
+  case X86ISD::AESDECWIDE128KL:
+  case X86ISD::AESENCWIDE256KL:
+  case X86ISD::AESDECWIDE256KL:
     return true;
-  return SelectionDAGTargetInfo::isTargetMemoryOpcode(Opcode);
+  }
+
+  return SelectionDAGGenTargetInfo::isTargetMemoryOpcode(Opcode);
 }
 
-bool X86SelectionDAGInfo::isTargetStrictFPOpcode(unsigned Opcode) const {
-  if (Opcode >= X86ISD::FIRST_STRICTFP_OPCODE &&
-      Opcode <= X86ISD::LAST_STRICTFP_OPCODE)
-    return true;
-  return SelectionDAGTargetInfo::isTargetStrictFPOpcode(Opcode);
+void X86SelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
+                                           const SDNode *N) const {
+  switch (N->getOpcode()) {
+  default:
+    break;
+  case X86ISD::VP2INTERSECT:
+    // invalid number of results; expected 1, got 2
+  case X86ISD::VTRUNCSTOREUS:
+  case X86ISD::VTRUNCSTORES:
+  case X86ISD::FSETCCM_SAE:
+    // invalid number of operands; expected 3, got 4
+  case X86ISD::CVTPH2PS:
+  case X86ISD::CVTTP2SI_SAE:
+  case X86ISD::CVTTP2UI_SAE:
+  case X86ISD::CVTTP2IBS_SAE:
+    // invalid number of operands; expected 1, got 2
+  case X86ISD::CMPMM_SAE:
+    // invalid number of operands; expected 4, got 5
+    return;
+  }
+
+  SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
 }
 
 /// Returns the best type to use with repmovs/repstos depending on alignment.
diff --git a/llvm/lib/Target/X86/X86SelectionDAGInfo.h b/llvm/lib/Target/X86/X86SelectionDAGInfo.h
index e77e16bab830d5..a6fe4862487e88 100644
--- a/llvm/lib/Target/X86/X86SelectionDAGInfo.h
+++ b/llvm/lib/Target/X86/X86SelectionDAGInfo.h
@@ -15,20 +15,57 @@
 
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 
+#define GET_SDNODE_ENUM
+#include "X86GenSDNodeInfo.inc"
+
 namespace llvm {
+namespace X86ISD {
+
+enum NodeType : unsigned {
+  /// On Darwin, this node represents the result of the popl
+  /// at function entry, used for PIC code.
+  GlobalBaseReg = X86ISD::GENERATED_OPCODE_END,
+
+  // SSE42 string comparisons.
+  // These nodes produce 3 results, index, mask, and flags. X86ISelDAGToDAG
+  // will emit one or two instructions based on which results are used. If
+  // flags and index/mask this allows us to use a single instruction since
+  // we won't have to pick and opcode for flags. Instead we can rely on the
+  // DAG to CSE everything and decide at isel.
+  PCMPISTR,
+  PCMPESTR,
+
+  // Compare and swap.
+  LCMPXCHG16_SAVE_RBX_DAG,
+
+  // X86 specific gather and scatter
+  MGATHER,
+  MSCATTER,
 
-class X86SelectionDAGInfo : public SelectionDAGTargetInfo {
+  // Key locker nodes that produce flags.
+  AESENCWIDE128KL,
+  AESDECWIDE128KL,
+  AESENCWIDE256KL,
+  AESDECWIDE256KL,
+};
+
+} // namespace X86ISD
+
+class X86SelectionDAGInfo : public SelectionDAGGenTargetInfo {
   /// Returns true if it is possible for the base register to conflict with the
   /// given set of clobbers for a memory intrinsic.
   bool isBaseRegConflictPossible(SelectionDAG &DAG,
                                  ArrayRef<MCPhysReg> ClobberSet) const;
 
 public:
-  explicit X86SelectionDAGInfo() = default;
+  X86SelectionDAGInfo();
+
+  const char *getTargetNodeName(unsigned Opcode) const override;
 
   bool isTargetMemoryOpcode(unsigned Opcode) const override;
 
-  bool isTargetStrictFPOpcode(unsigned Opcode) const override;
+  void verifyTargetNode(const SelectionDAG &DAG,
+                        const SDNode *N) const override;
 
   SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, const SDLoc &dl,
                                   SDValue Chain, SDValue Dst, SDValue Src,
@@ -44,6 +81,6 @@ class X86SelectionDAGInfo : public SelectionDAGTargetInfo {
                                   MachinePointerInfo SrcPtrInfo) const override;
 };
 
-}
+} // namespace llvm
 
 #endif

>From bdc32c1b7690a52c28550c9951cef6cc3600e2ef Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 01:02:53 +0300
Subject: [PATCH 25/27] XCore

---
 llvm/lib/Target/XCore/CMakeLists.txt          |  1 +
 llvm/lib/Target/XCore/XCoreISelLowering.cpp   | 27 --------
 llvm/lib/Target/XCore/XCoreISelLowering.h     | 63 -------------------
 .../Target/XCore/XCoreSelectionDAGInfo.cpp    |  8 +++
 llvm/lib/Target/XCore/XCoreSelectionDAGInfo.h |  7 ++-
 5 files changed, 15 insertions(+), 91 deletions(-)

diff --git a/llvm/lib/Target/XCore/CMakeLists.txt b/llvm/lib/Target/XCore/CMakeLists.txt
index 447f5c54528850..f411c658b43b05 100644
--- a/llvm/lib/Target/XCore/CMakeLists.txt
+++ b/llvm/lib/Target/XCore/CMakeLists.txt
@@ -8,6 +8,7 @@ tablegen(LLVM XCoreGenDAGISel.inc -gen-dag-isel)
 tablegen(LLVM XCoreGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM XCoreGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM XCoreGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM XCoreGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM XCoreGenSubtargetInfo.inc -gen-subtarget)
 
 add_public_tablegen_target(XCoreCommonTableGen)
diff --git a/llvm/lib/Target/XCore/XCoreISelLowering.cpp b/llvm/lib/Target/XCore/XCoreISelLowering.cpp
index 9a9acaca3188eb..e343dc07f189a9 100644
--- a/llvm/lib/Target/XCore/XCoreISelLowering.cpp
+++ b/llvm/lib/Target/XCore/XCoreISelLowering.cpp
@@ -40,33 +40,6 @@ using namespace llvm;
 
 #define DEBUG_TYPE "xcore-lower"
 
-const char *XCoreTargetLowering::
-getTargetNodeName(unsigned Opcode) const
-{
-  switch ((XCoreISD::NodeType)Opcode)
-  {
-    case XCoreISD::FIRST_NUMBER      : break;
-    case XCoreISD::BL                : return "XCoreISD::BL";
-    case XCoreISD::PCRelativeWrapper : return "XCoreISD::PCRelativeWrapper";
-    case XCoreISD::DPRelativeWrapper : return "XCoreISD::DPRelativeWrapper";
-    case XCoreISD::CPRelativeWrapper : return "XCoreISD::CPRelativeWrapper";
-    case XCoreISD::LDWSP             : return "XCoreISD::LDWSP";
-    case XCoreISD::STWSP             : return "XCoreISD::STWSP";
-    case XCoreISD::RETSP             : return "XCoreISD::RETSP";
-    case XCoreISD::LADD              : return "XCoreISD::LADD";
-    case XCoreISD::LSUB              : return "XCoreISD::LSUB";
-    case XCoreISD::LMUL              : return "XCoreISD::LMUL";
-    case XCoreISD::MACCU             : return "XCoreISD::MACCU";
-    case XCoreISD::MACCS             : return "XCoreISD::MACCS";
-    case XCoreISD::CRC8              : return "XCoreISD::CRC8";
-    case XCoreISD::BR_JT             : return "XCoreISD::BR_JT";
-    case XCoreISD::BR_JT32           : return "XCoreISD::BR_JT32";
-    case XCoreISD::FRAME_TO_ARGS_OFFSET : return "XCoreISD::FRAME_TO_ARGS_OFFSET";
-    case XCoreISD::EH_RETURN         : return "XCoreISD::EH_RETURN";
-  }
-  return nullptr;
-}
-
 XCoreTargetLowering::XCoreTargetLowering(const TargetMachine &TM,
                                          const XCoreSubtarget &Subtarget)
     : TargetLowering(TM), TM(TM), Subtarget(Subtarget) {
diff --git a/llvm/lib/Target/XCore/XCoreISelLowering.h b/llvm/lib/Target/XCore/XCoreISelLowering.h
index eaa36d40cba928..0f163a0ddbcc0e 100644
--- a/llvm/lib/Target/XCore/XCoreISelLowering.h
+++ b/llvm/lib/Target/XCore/XCoreISelLowering.h
@@ -23,65 +23,6 @@ namespace llvm {
   // Forward delcarations
   class XCoreSubtarget;
 
-  namespace XCoreISD {
-    enum NodeType : unsigned {
-      // Start the numbering where the builtin ops and target ops leave off.
-      FIRST_NUMBER = ISD::BUILTIN_OP_END,
-
-      // Branch and link (call)
-      BL,
-
-      // pc relative address
-      PCRelativeWrapper,
-
-      // dp relative address
-      DPRelativeWrapper,
-
-      // cp relative address
-      CPRelativeWrapper,
-
-      // Load word from stack
-      LDWSP,
-
-      // Store word to stack
-      STWSP,
-
-      // Corresponds to retsp instruction
-      RETSP,
-
-      // Corresponds to LADD instruction
-      LADD,
-
-      // Corresponds to LSUB instruction
-      LSUB,
-
-      // Corresponds to LMUL instruction
-      LMUL,
-
-      // Corresponds to MACCU instruction
-      MACCU,
-
-      // Corresponds to MACCS instruction
-      MACCS,
-
-      // Corresponds to CRC8 instruction
-      CRC8,
-
-      // Jumptable branch.
-      BR_JT,
-
-      // Jumptable branch using long branches for each entry.
-      BR_JT32,
-
-      // Offset from frame pointer to the first (possible) on-stack argument
-      FRAME_TO_ARGS_OFFSET,
-
-      // Exception handler return. The stack is restored to the first
-      // followed by a jump to the second argument.
-      EH_RETURN,
-    };
-  }
-
   //===--------------------------------------------------------------------===//
   // TargetLowering Implementation
   //===--------------------------------------------------------------------===//
@@ -109,10 +50,6 @@ namespace llvm {
     void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,
                             SelectionDAG &DAG) const override;
 
-    /// getTargetNodeName - This method returns the name of a target specific
-    //  DAG node.
-    const char *getTargetNodeName(unsigned Opcode) const override;
-
     MachineBasicBlock *
     EmitInstrWithCustomInserter(MachineInstr &MI,
                                 MachineBasicBlock *MBB) const override;
diff --git a/llvm/lib/Target/XCore/XCoreSelectionDAGInfo.cpp b/llvm/lib/Target/XCore/XCoreSelectionDAGInfo.cpp
index 0d097076348cad..bc34ab4319690b 100644
--- a/llvm/lib/Target/XCore/XCoreSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/XCore/XCoreSelectionDAGInfo.cpp
@@ -10,11 +10,19 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "XCoreSelectionDAGInfo.h"
 #include "XCoreTargetMachine.h"
+
+#define GET_SDNODE_DESC
+#include "XCoreGenSDNodeInfo.inc"
+
 using namespace llvm;
 
 #define DEBUG_TYPE "xcore-selectiondag-info"
 
+XCoreSelectionDAGInfo::XCoreSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(XCoreGenSDNodeInfo) {}
+
 SDValue XCoreSelectionDAGInfo::EmitTargetCodeForMemcpy(
     SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
     SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline,
diff --git a/llvm/lib/Target/XCore/XCoreSelectionDAGInfo.h b/llvm/lib/Target/XCore/XCoreSelectionDAGInfo.h
index 2abf526779785d..04734699a02840 100644
--- a/llvm/lib/Target/XCore/XCoreSelectionDAGInfo.h
+++ b/llvm/lib/Target/XCore/XCoreSelectionDAGInfo.h
@@ -15,10 +15,15 @@
 
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 
+#define GET_SDNODE_ENUM
+#include "XCoreGenSDNodeInfo.inc"
+
 namespace llvm {
 
-class XCoreSelectionDAGInfo : public SelectionDAGTargetInfo {
+class XCoreSelectionDAGInfo : public SelectionDAGGenTargetInfo {
 public:
+  XCoreSelectionDAGInfo();
+
   SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &dl,
                                   SDValue Chain, SDValue Op1, SDValue Op2,
                                   SDValue Op3, Align Alignment, bool isVolatile,

>From d490b1d24417ef27e0bc0685e156a4ce7167a08f Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 03:11:40 +0300
Subject: [PATCH 26/27] Xtensa

---
 llvm/lib/Target/Xtensa/CMakeLists.txt         |  2 ++
 llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp |  1 +
 llvm/lib/Target/Xtensa/XtensaISelLowering.cpp | 23 +-----------
 llvm/lib/Target/Xtensa/XtensaISelLowering.h   | 36 -------------------
 .../Target/Xtensa/XtensaSelectionDAGInfo.cpp  | 19 ++++++++++
 .../Target/Xtensa/XtensaSelectionDAGInfo.h    | 28 +++++++++++++++
 llvm/lib/Target/Xtensa/XtensaSubtarget.cpp    | 11 +++++-
 llvm/lib/Target/Xtensa/XtensaSubtarget.h      | 10 +++---
 8 files changed, 66 insertions(+), 64 deletions(-)
 create mode 100644 llvm/lib/Target/Xtensa/XtensaSelectionDAGInfo.cpp
 create mode 100644 llvm/lib/Target/Xtensa/XtensaSelectionDAGInfo.h

diff --git a/llvm/lib/Target/Xtensa/CMakeLists.txt b/llvm/lib/Target/Xtensa/CMakeLists.txt
index 726efadc87c0b2..94f15ca3afee9a 100644
--- a/llvm/lib/Target/Xtensa/CMakeLists.txt
+++ b/llvm/lib/Target/Xtensa/CMakeLists.txt
@@ -10,6 +10,7 @@ tablegen(LLVM XtensaGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM XtensaGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM XtensaGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM XtensaGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM XtensaGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM XtensaGenSubtargetInfo.inc -gen-subtarget)
 
 add_public_tablegen_target(XtensaCommonTableGen)
@@ -22,6 +23,7 @@ add_llvm_target(XtensaCodeGen
   XtensaISelDAGToDAG.cpp
   XtensaISelLowering.cpp
   XtensaRegisterInfo.cpp
+  XtensaSelectionDAGInfo.cpp
   XtensaSubtarget.cpp
   XtensaTargetMachine.cpp
   XtensaUtils.cpp
diff --git a/llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp b/llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp
index af1110487b4274..de5c46dd1a4630 100644
--- a/llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "Xtensa.h"
+#include "XtensaSelectionDAGInfo.h"
 #include "XtensaTargetMachine.h"
 #include "XtensaUtils.h"
 #include "llvm/CodeGen/MachineFunction.h"
diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
index 7e43c03ee72cac..bd839a93fb5d00 100644
--- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
@@ -15,6 +15,7 @@
 #include "XtensaConstantPoolValue.h"
 #include "XtensaInstrInfo.h"
 #include "XtensaMachineFunctionInfo.h"
+#include "XtensaSelectionDAGInfo.h"
 #include "XtensaSubtarget.h"
 #include "XtensaTargetMachine.h"
 #include "llvm/CodeGen/CallingConvLower.h"
@@ -1218,28 +1219,6 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op,
   }
 }
 
-const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const {
-  switch (Opcode) {
-  case XtensaISD::BR_JT:
-    return "XtensaISD::BR_JT";
-  case XtensaISD::CALL:
-    return "XtensaISD::CALL";
-  case XtensaISD::EXTUI:
-    return "XtensaISD::EXTUI";
-  case XtensaISD::PCREL_WRAPPER:
-    return "XtensaISD::PCREL_WRAPPER";
-  case XtensaISD::RET:
-    return "XtensaISD::RET";
-  case XtensaISD::SELECT_CC:
-    return "XtensaISD::SELECT_CC";
-  case XtensaISD::SRCL:
-    return "XtensaISD::SRCL";
-  case XtensaISD::SRCR:
-    return "XtensaISD::SRCR";
-  }
-  return nullptr;
-}
-
 //===----------------------------------------------------------------------===//
 // Custom insertion
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.h b/llvm/lib/Target/Xtensa/XtensaISelLowering.h
index cebd7d2016c8ee..d24fb40bf34ac3 100644
--- a/llvm/lib/Target/Xtensa/XtensaISelLowering.h
+++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.h
@@ -20,40 +20,6 @@
 
 namespace llvm {
 
-namespace XtensaISD {
-enum {
-  FIRST_NUMBER = ISD::BUILTIN_OP_END,
-  BR_JT,
-
-  // Calls a function.  Operand 0 is the chain operand and operand 1
-  // is the target address.  The arguments start at operand 2.
-  // There is an optional glue operand at the end.
-  CALL,
-
-  // Extract unsigned immediate. Operand 0 is value, operand 1
-  // is bit position of the field [0..31], operand 2 is bit size
-  // of the field [1..16]
-  EXTUI,
-
-  // Wraps a TargetGlobalAddress that should be loaded using PC-relative
-  // accesses.  Operand 0 is the address.
-  PCREL_WRAPPER,
-  RET,
-
-  // Select with condition operator - This selects between a true value and
-  // a false value (ops #2 and #3) based on the boolean result of comparing
-  // the lhs and rhs (ops #0 and #1) of a conditional expression with the
-  // condition code in op #4
-  SELECT_CC,
-
-  // SRCL(R) performs shift left(right) of the concatenation of 2 registers
-  // and returns high(low) 32-bit part of 64-bit result
-  SRCL,
-  // Shift Right Combined
-  SRCR,
-};
-}
-
 class XtensaSubtarget;
 
 class XtensaTargetLowering : public TargetLowering {
@@ -74,8 +40,6 @@ class XtensaTargetLowering : public TargetLowering {
 
   bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
 
-  const char *getTargetNodeName(unsigned Opcode) const override;
-
   std::pair<unsigned, const TargetRegisterClass *>
   getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
                                StringRef Constraint, MVT VT) const override;
diff --git a/llvm/lib/Target/Xtensa/XtensaSelectionDAGInfo.cpp b/llvm/lib/Target/Xtensa/XtensaSelectionDAGInfo.cpp
new file mode 100644
index 00000000000000..3f0ba044a7f6c2
--- /dev/null
+++ b/llvm/lib/Target/Xtensa/XtensaSelectionDAGInfo.cpp
@@ -0,0 +1,19 @@
+//===- XtensaSelectionDAGInfo.cpp -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "XtensaSelectionDAGInfo.h"
+
+#define GET_SDNODE_DESC
+#include "XtensaGenSDNodeInfo.inc"
+
+using namespace llvm;
+
+XtensaSelectionDAGInfo::XtensaSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(XtensaGenSDNodeInfo) {}
+
+XtensaSelectionDAGInfo::~XtensaSelectionDAGInfo() = default;
diff --git a/llvm/lib/Target/Xtensa/XtensaSelectionDAGInfo.h b/llvm/lib/Target/Xtensa/XtensaSelectionDAGInfo.h
new file mode 100644
index 00000000000000..16a9ad2e85912c
--- /dev/null
+++ b/llvm/lib/Target/Xtensa/XtensaSelectionDAGInfo.h
@@ -0,0 +1,28 @@
+//===- XtensaSelectionDAGInfo.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_XTENSA_XTENSASELECTIONDAGINFO_H
+#define LLVM_LIB_TARGET_XTENSA_XTENSASELECTIONDAGINFO_H
+
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+
+#define GET_SDNODE_ENUM
+#include "XtensaGenSDNodeInfo.inc"
+
+namespace llvm {
+
+class XtensaSelectionDAGInfo : public SelectionDAGGenTargetInfo {
+public:
+  XtensaSelectionDAGInfo();
+
+  ~XtensaSelectionDAGInfo() override;
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_XTENSA_XTENSASELECTIONDAGINFO_H
diff --git a/llvm/lib/Target/Xtensa/XtensaSubtarget.cpp b/llvm/lib/Target/Xtensa/XtensaSubtarget.cpp
index d6b1b4bc154635..0e008b11f2ecc4 100644
--- a/llvm/lib/Target/Xtensa/XtensaSubtarget.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaSubtarget.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "XtensaSubtarget.h"
+#include "XtensaSelectionDAGInfo.h"
 #include "llvm/IR/GlobalValue.h"
 #include "llvm/Support/Debug.h"
 
@@ -41,4 +42,12 @@ XtensaSubtarget::XtensaSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
                                  const TargetMachine &TM)
     : XtensaGenSubtargetInfo(TT, CPU, /*TuneCPU=*/CPU, FS), TargetTriple(TT),
       InstrInfo(initializeSubtargetDependencies(CPU, FS)), TLInfo(TM, *this),
-      TSInfo(), FrameLowering(*this) {}
+      FrameLowering(*this) {
+  TSInfo = std::make_unique<SelectionDAGTargetInfo>();
+}
+
+XtensaSubtarget::~XtensaSubtarget() = default;
+
+const SelectionDAGTargetInfo *XtensaSubtarget::getSelectionDAGInfo() const {
+  return TSInfo.get();
+}
diff --git a/llvm/lib/Target/Xtensa/XtensaSubtarget.h b/llvm/lib/Target/Xtensa/XtensaSubtarget.h
index 948dcbc5278eaa..c88787b0615fd4 100644
--- a/llvm/lib/Target/Xtensa/XtensaSubtarget.h
+++ b/llvm/lib/Target/Xtensa/XtensaSubtarget.h
@@ -17,7 +17,6 @@
 #include "XtensaISelLowering.h"
 #include "XtensaInstrInfo.h"
 #include "XtensaRegisterInfo.h"
-#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/Target/TargetMachine.h"
@@ -33,7 +32,7 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo {
   const Triple &TargetTriple;
   XtensaInstrInfo InstrInfo;
   XtensaTargetLowering TLInfo;
-  SelectionDAGTargetInfo TSInfo;
+  std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
   XtensaFrameLowering FrameLowering;
 
   // Enabled Xtensa Density extension
@@ -45,6 +44,8 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo {
   XtensaSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
                   const TargetMachine &TM);
 
+  ~XtensaSubtarget() override;
+
   const Triple &getTargetTriple() const { return TargetTriple; }
 
   const TargetFrameLowering *getFrameLowering() const override {
@@ -58,9 +59,8 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo {
   const XtensaTargetLowering *getTargetLowering() const override {
     return &TLInfo;
   }
-  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
-    return &TSInfo;
-  }
+
+  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
 
   bool hasDensity() const { return HasDensity; }
 

>From ad38786aa63eb715104d5c863b06796b04e3218d Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Thu, 12 Dec 2024 01:59:14 +0300
Subject: [PATCH 27/27] Generic bugs

---
 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp        | 2 +-
 llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 5 ++---
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 528f92d68a7144..2c0f39de5bcb8b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -1933,7 +1933,7 @@ SDValue SelectionDAG::getJumpTable(int JTI, EVT VT, bool isTarget,
 SDValue SelectionDAG::getJumpTableDebugInfo(int JTI, SDValue Chain,
                                             const SDLoc &DL) {
   EVT PTy = getTargetLoweringInfo().getPointerTy(getDataLayout());
-  return getNode(ISD::JUMP_TABLE_DEBUG_INFO, DL, MVT::Glue, Chain,
+  return getNode(ISD::JUMP_TABLE_DEBUG_INFO, DL, MVT::Other, Chain,
                  getTargetConstant(static_cast<uint64_t>(JTI), DL, PTy, true));
 }
 
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index f8d7c3ef7bbe71..ad9cf7389c2bbb 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -3161,9 +3161,8 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
                              Guard, GuardVal, ISD::SETNE);
 
   // If the guard/stackslot do not equal, branch to failure MBB.
-  SDValue BrCond = DAG.getNode(ISD::BRCOND, dl,
-                               MVT::Other, GuardVal.getOperand(0),
-                               Cmp, DAG.getBasicBlock(SPD.getFailureMBB()));
+  SDValue BrCond = DAG.getNode(ISD::BRCOND, dl, MVT::Other, Chain, Cmp,
+                               DAG.getBasicBlock(SPD.getFailureMBB()));
   // Otherwise branch to success MBB.
   SDValue Br = DAG.getNode(ISD::BR, dl,
                            MVT::Other, BrCond,



More information about the llvm-commits mailing list