[llvm] 6ee2f77 - [PowerPC][GISel] add support for fpconstant

Chen Zheng via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 13 18:39:37 PST 2023


Author: Chen Zheng
Date: 2023-02-14T02:39:22Z
New Revision: 6ee2f770efb6b1b02438db025af0899ed5bf9313

URL: https://github.com/llvm/llvm-project/commit/6ee2f770efb6b1b02438db025af0899ed5bf9313
DIFF: https://github.com/llvm/llvm-project/commit/6ee2f770efb6b1b02438db025af0899ed5bf9313.diff

LOG: [PowerPC][GISel] add support for fpconstant

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D133340

Added: 
    llvm/test/CodeGen/PowerPC/GlobalISel/fconstant-unsupported.ll
    llvm/test/CodeGen/PowerPC/GlobalISel/fconstant.ll
    llvm/test/MachineVerifier/test_g_constant_pool.mir

Modified: 
    llvm/docs/GlobalISel/GenericOpcode.rst
    llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
    llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
    llvm/include/llvm/Support/TargetOpcodes.def
    llvm/include/llvm/Target/GenericOpcodes.td
    llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
    llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
    llvm/lib/CodeGen/MachineVerifier.cpp
    llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
    llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
    llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
    llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir

Removed: 
    


################################################################################
diff  --git a/llvm/docs/GlobalISel/GenericOpcode.rst b/llvm/docs/GlobalISel/GenericOpcode.rst
index d12563b7f0614..14d164f79bad0 100644
--- a/llvm/docs/GlobalISel/GenericOpcode.rst
+++ b/llvm/docs/GlobalISel/GenericOpcode.rst
@@ -69,6 +69,15 @@ The address of a basic block.
 
   %0:_(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block)
 
+G_CONSTANT_POOL
+^^^^^^^^^^^^^^^
+
+The address of an object in the constant pool.
+
+.. code-block:: none
+
+  %0:_(p0) = G_CONSTANT_POOL %const.0
+
 Integer Extension and Truncation
 --------------------------------
 

diff  --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index a019bc9876bda..f57d2b68c86dc 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -359,6 +359,7 @@ class LegalizerHelper {
   LegalizeResult bitcastInsertVectorElt(MachineInstr &MI, unsigned TypeIdx,
                                         LLT CastTy);
 
+  LegalizeResult lowerFConstant(MachineInstr &MI);
   LegalizeResult lowerBitcast(MachineInstr &MI);
   LegalizeResult lowerLoad(GAnyLoad &MI);
   LegalizeResult lowerStore(GStore &MI);

diff  --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index e5b48d9d52c03..a4168d924f7de 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -458,6 +458,17 @@ class MachineIRBuilder {
   /// \return a MachineInstrBuilder for the newly created instruction.
   MachineInstrBuilder buildGlobalValue(const DstOp &Res, const GlobalValue *GV);
 
+  /// Build and insert \p Res = G_CONSTANT_POOL \p Idx
+  ///
+  /// G_CONSTANT_POOL materializes the address of an object in the constant
+  /// pool.
+  ///
+  /// \pre setBasicBlock or setMI must have been called.
+  /// \pre \p Res must be a generic virtual register with pointer type.
+  ///
+  /// \return a MachineInstrBuilder for the newly created instruction.
+  MachineInstrBuilder buildConstantPool(const DstOp &Res, unsigned Idx);
+
   /// Build and insert \p Res = G_PTR_ADD \p Op0, \p Op1
   ///
   /// G_PTR_ADD adds \p Op1 addressible units to the pointer specified by \p Op0,

diff  --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def
index d3fe1eec38d75..5fd6523137ea4 100644
--- a/llvm/include/llvm/Support/TargetOpcodes.def
+++ b/llvm/include/llvm/Support/TargetOpcodes.def
@@ -290,6 +290,10 @@ HANDLE_TARGET_OPCODE(G_FRAME_INDEX)
 /// Generic reference to global value.
 HANDLE_TARGET_OPCODE(G_GLOBAL_VALUE)
 
+/// Generic instruction to materialize the address of an object in the constant
+/// pool.
+HANDLE_TARGET_OPCODE(G_CONSTANT_POOL)
+
 /// Generic instruction to extract blocks of bits from the register given
 /// (typically a sub-register COPY after instruction selection).
 HANDLE_TARGET_OPCODE(G_EXTRACT)

diff  --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td
index 734717155daa5..f777aa1e04779 100644
--- a/llvm/include/llvm/Target/GenericOpcodes.td
+++ b/llvm/include/llvm/Target/GenericOpcodes.td
@@ -106,6 +106,12 @@ def G_GLOBAL_VALUE : GenericInstruction {
   let hasSideEffects = false;
 }
 
+def G_CONSTANT_POOL : GenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins unknown:$src);
+  let hasSideEffects = false;
+}
+
 def G_INTTOPTR : GenericInstruction {
   let OutOperandList = (outs type0:$dst);
   let InOperandList = (ins type1:$src);

diff  --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 5c651371bd3c0..ad3a88ae82cb6 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -21,6 +21,7 @@
 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
 #include "llvm/CodeGen/GlobalISel/Utils.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/TargetFrameLowering.h"
@@ -2630,6 +2631,32 @@ static void getUnmergePieces(SmallVectorImpl<Register> &Pieces,
     Pieces.push_back(Unmerge.getReg(I));
 }
 
+LegalizerHelper::LegalizeResult
+LegalizerHelper::lowerFConstant(MachineInstr &MI) {
+  Register Dst = MI.getOperand(0).getReg();
+
+  MachineFunction &MF = MIRBuilder.getMF();
+  const DataLayout &DL = MIRBuilder.getDataLayout();
+
+  unsigned AddrSpace = DL.getDefaultGlobalsAddressSpace();
+  LLT AddrPtrTy = LLT::pointer(AddrSpace, DL.getPointerSizeInBits(AddrSpace));
+  Align Alignment = Align(DL.getABITypeAlign(
+      getFloatTypeForLLT(MF.getFunction().getContext(), MRI.getType(Dst))));
+
+  auto Addr = MIRBuilder.buildConstantPool(
+      AddrPtrTy, MF.getConstantPool()->getConstantPoolIndex(
+                     MI.getOperand(1).getFPImm(), Alignment));
+
+  MachineMemOperand *MMO = MF.getMachineMemOperand(
+      MachinePointerInfo::getConstantPool(MF), MachineMemOperand::MOLoad,
+      MRI.getType(Dst), Alignment);
+
+  MIRBuilder.buildLoadInstr(TargetOpcode::G_LOAD, Dst, Addr, *MMO);
+  MI.eraseFromParent();
+
+  return Legalized;
+}
+
 LegalizerHelper::LegalizeResult
 LegalizerHelper::lowerBitcast(MachineInstr &MI) {
   Register Dst = MI.getOperand(0).getReg();
@@ -3250,6 +3277,8 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
   switch(MI.getOpcode()) {
   default:
     return UnableToLegalize;
+  case TargetOpcode::G_FCONSTANT:
+    return lowerFConstant(MI);
   case TargetOpcode::G_BITCAST:
     return lowerBitcast(MI);
   case TargetOpcode::G_SREM:

diff  --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 9100e064f30fb..c26f7374ee913 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -164,6 +164,15 @@ MachineInstrBuilder MachineIRBuilder::buildGlobalValue(const DstOp &Res,
   return MIB;
 }
 
+MachineInstrBuilder MachineIRBuilder::buildConstantPool(const DstOp &Res,
+                                                        unsigned Idx) {
+  assert(Res.getLLTTy(*getMRI()).isPointer() && "invalid operand type");
+  auto MIB = buildInstr(TargetOpcode::G_CONSTANT_POOL);
+  Res.addDefToMIB(*getMRI(), MIB);
+  MIB.addConstantPoolIndex(Idx);
+  return MIB;
+}
+
 MachineInstrBuilder MachineIRBuilder::buildJumpTable(const LLT PtrTy,
                                                      unsigned JTI) {
   return buildInstr(TargetOpcode::G_JUMP_TABLE, {PtrTy}, {})

diff  --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 53aafb88d61b4..94f0040c1aec9 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -1746,6 +1746,13 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
       report("alignment immediate must be >= 1", MI);
     break;
   }
+  case TargetOpcode::G_CONSTANT_POOL: {
+    if (!MI->getOperand(1).isCPI())
+      report("Src operand 1 must be a constant pool index", MI);
+    if (!MRI->getType(MI->getOperand(0).getReg()).isPointer())
+      report("Dst operand 0 must be a pointer", MI);
+    break;
+  }
   default:
     break;
   }

diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp b/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
index ef11a93f3152e..97f3e0963d7b5 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
+++ b/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
@@ -12,6 +12,7 @@
 
 #include "PPC.h"
 #include "PPCInstrInfo.h"
+#include "PPCMachineFunctionInfo.h"
 #include "PPCRegisterBankInfo.h"
 #include "PPCSubtarget.h"
 #include "PPCTargetMachine.h"
@@ -54,6 +55,8 @@ class PPCInstructionSelector : public InstructionSelector {
 
   bool selectZExt(MachineInstr &I, MachineBasicBlock &MBB,
                   MachineRegisterInfo &MRI) const;
+  bool selectConstantPool(MachineInstr &I, MachineBasicBlock &MBB,
+                          MachineRegisterInfo &MRI) const;
 
   std::optional<bool> selectI64ImmDirect(MachineInstr &I,
                                          MachineBasicBlock &MBB,
@@ -62,6 +65,7 @@ class PPCInstructionSelector : public InstructionSelector {
   bool selectI64Imm(MachineInstr &I, MachineBasicBlock &MBB,
                     MachineRegisterInfo &MRI) const;
 
+  const PPCTargetMachine &TM;
   const PPCSubtarget &STI;
   const PPCInstrInfo &TII;
   const PPCRegisterInfo &TRI;
@@ -85,7 +89,8 @@ class PPCInstructionSelector : public InstructionSelector {
 PPCInstructionSelector::PPCInstructionSelector(const PPCTargetMachine &TM,
                                                const PPCSubtarget &STI,
                                                const PPCRegisterBankInfo &RBI)
-    : STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()), RBI(RBI),
+    : TM(TM), STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()),
+      RBI(RBI),
 #define GET_GLOBALISEL_PREDICATES_INIT
 #include "PPCGenGlobalISel.inc"
 #undef GET_GLOBALISEL_PREDICATES_INIT
@@ -636,6 +641,66 @@ bool PPCInstructionSelector::selectI64Imm(MachineInstr &I,
   return true;
 }
 
+bool PPCInstructionSelector::selectConstantPool(
+    MachineInstr &I, MachineBasicBlock &MBB, MachineRegisterInfo &MRI) const {
+  const DebugLoc &DbgLoc = I.getDebugLoc();
+  MachineFunction *MF = MBB.getParent();
+
+  // TODO: handle 32-bit.
+  // TODO: Enabling floating point constant pool selection on AIX requires
+  // global isel on big endian target enabled first.
+  // See CallLowering::enableBigEndian().
+  if (!STI.isPPC64() || !STI.isLittleEndian())
+    return false;
+
+  MF->getInfo<PPCFunctionInfo>()->setUsesTOCBasePtr();
+
+  const Register DstReg = I.getOperand(0).getReg();
+  unsigned CPI = I.getOperand(1).getIndex();
+
+  // Address stored in the TOC entry. This is related to code model and the ABI
+  // we are currently using. For now we only handle 64-bit Linux LE. PowerPC
+  // only supports small, medium and large code model.
+  const CodeModel::Model CModel = TM.getCodeModel();
+  assert(!(CModel == CodeModel::Tiny || CModel == CodeModel::Kernel) &&
+         "PowerPC doesn't support tiny or kernel code models.");
+
+  const MCRegister TOCReg = STI.getTOCPointerRegister();
+  MachineMemOperand *MMO = MF->getMachineMemOperand(
+      MachinePointerInfo::getGOT(*MF), MachineMemOperand::MOLoad,
+      MRI.getType(DstReg), MF->getDataLayout().getPointerABIAlignment(0));
+
+  MachineInstr *MI = nullptr;
+  // For now we only handle 64-bit Linux.
+  if (CModel == CodeModel::Small) {
+    // For small code model, generate LDtocCPT(CPI, X2).
+    MI = BuildMI(MBB, I, DbgLoc, TII.get(PPC::LDtocCPT), DstReg)
+             .addConstantPoolIndex(CPI)
+             .addReg(TOCReg)
+             .addMemOperand(MMO);
+  } else {
+    Register HaAddrReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
+    BuildMI(MBB, I, DbgLoc, TII.get(PPC::ADDIStocHA8), HaAddrReg)
+        .addReg(TOCReg)
+        .addConstantPoolIndex(CPI);
+
+    if (CModel == CodeModel::Large)
+      // For large code model, generate LDtocL(CPI, ADDIStocHA8(X2, CPI))
+      MI = BuildMI(MBB, I, DbgLoc, TII.get(PPC::LDtocL), DstReg)
+               .addConstantPoolIndex(CPI)
+               .addReg(HaAddrReg)
+               .addMemOperand(MMO);
+    else
+      // For medium code model, generate ADDItocL(CPI, ADDIStocHA8(X2, CPI))
+      MI = BuildMI(MBB, I, DbgLoc, TII.get(PPC::ADDItocL), DstReg)
+               .addReg(HaAddrReg)
+               .addConstantPoolIndex(CPI);
+  }
+
+  I.eraseFromParent();
+  return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
+}
+
 bool PPCInstructionSelector::select(MachineInstr &I) {
   auto &MBB = *I.getParent();
   auto &MF = *MBB.getParent();
@@ -704,6 +769,8 @@ bool PPCInstructionSelector::select(MachineInstr &I) {
     return selectZExt(I, MBB, MRI);
   case TargetOpcode::G_CONSTANT:
     return selectI64Imm(I, MBB, MRI);
+  case TargetOpcode::G_CONSTANT_POOL:
+    return selectConstantPool(I, MBB, MRI);
   }
   return false;
 }

diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp b/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
index 1a25fcde8815d..2e0d12c4e633b 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
+++ b/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
@@ -54,5 +54,8 @@ PPCLegalizerInfo::PPCLegalizerInfo(const PPCSubtarget &ST) {
   getActionDefinitionsBuilder({G_LOAD, G_STORE})
       .legalForTypesWithMemDesc({{S64, P0, S64, 8}, {S32, P0, S32, 4}});
 
+  getActionDefinitionsBuilder(G_FCONSTANT).lowerFor({S32, S64});
+  getActionDefinitionsBuilder(G_CONSTANT_POOL).legalFor({P0});
+
   getLegacyLegalizerInfo().computeTables();
 }

diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
index ff8bb16ba9c8a..0ae44ecc52b22 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
+++ b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
@@ -118,6 +118,9 @@ PPCRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
   case TargetOpcode::G_CONSTANT:
     OperandsMapping = getOperandsMapping({getValueMapping(PMI_GPR64), nullptr});
     break;
+  case TargetOpcode::G_CONSTANT_POOL:
+    OperandsMapping = getOperandsMapping({getValueMapping(PMI_GPR64), nullptr});
+    break;
   case TargetOpcode::G_FPTOUI:
   case TargetOpcode::G_FPTOSI: {
     Register SrcReg = MI.getOperand(1).getReg();

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
index 036a1c876d327..54d9a765a4692 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
@@ -86,6 +86,10 @@
 # DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
 # DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
 #
+# DEBUG-NEXT: G_CONSTANT_POOL (opcode {{[0-9]+}}): 1 type index, 0 imm indices
+# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
+#
 # DEBUG-NEXT: G_EXTRACT (opcode {{[0-9]+}}): 2 type indices, 1 imm index
 # DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
 # DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected

diff  --git a/llvm/test/CodeGen/PowerPC/GlobalISel/fconstant-unsupported.ll b/llvm/test/CodeGen/PowerPC/GlobalISel/fconstant-unsupported.ll
new file mode 100644
index 0000000000000..f809282318786
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/GlobalISel/fconstant-unsupported.ll
@@ -0,0 +1,13 @@
+; RUN: not --crash llc -global-isel -mtriple=powerpc-unknown-linux-gnu \
+; RUN:   -o - < %s 2>&1 | FileCheck %s --check-prefix=BE
+; RUN: not --crash llc -global-isel -mtriple=powerpcle-unknown-linux-gnu \
+; RUN:   -o - < %s 2>&1 | FileCheck %s --check-prefix=BIT32
+
+; BE: LLVM ERROR: unable to translate in big endian mode
+
+; BIT32: LLVM ERROR: unable to legalize instruction: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD{{.*}}load (s64) from constant-pool
+
+define double @foo() {
+  entry:
+    ret double 1.000000e+00
+}

diff  --git a/llvm/test/CodeGen/PowerPC/GlobalISel/fconstant.ll b/llvm/test/CodeGen/PowerPC/GlobalISel/fconstant.ll
new file mode 100644
index 0000000000000..994752bb673e0
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/GlobalISel/fconstant.ll
@@ -0,0 +1,56 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+
+; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -global-isel -code-model=small \
+; RUN:   -verify-machineinstrs -o - < %s | FileCheck %s --check-prefix=SMALL
+; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -global-isel -code-model=medium \
+; RUN:   -verify-machineinstrs -o - < %s | FileCheck %s --check-prefix=MEDIUM
+; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -global-isel -code-model=large \
+; RUN:   -verify-machineinstrs -o - < %s | FileCheck %s --check-prefix=LARGE
+
+define float @foo_float() {
+; SMALL-LABEL: foo_float:
+; SMALL:       # %bb.0: # %entry
+; SMALL-NEXT:    ld 3, .LC0 at toc(2)
+; SMALL-NEXT:    lfs 1, 0(3)
+; SMALL-NEXT:    blr
+;
+; MEDIUM-LABEL: foo_float:
+; MEDIUM:       # %bb.0: # %entry
+; MEDIUM-NEXT:    addis 3, 2, .LCPI0_0 at toc@ha
+; MEDIUM-NEXT:    addi 3, 3, .LCPI0_0 at toc@l
+; MEDIUM-NEXT:    lfs 1, 0(3)
+; MEDIUM-NEXT:    blr
+;
+; LARGE-LABEL: foo_float:
+; LARGE:       # %bb.0: # %entry
+; LARGE-NEXT:    addis 3, 2, .LC0 at toc@ha
+; LARGE-NEXT:    ld 3, .LC0 at toc@l(3)
+; LARGE-NEXT:    lfs 1, 0(3)
+; LARGE-NEXT:    blr
+entry:
+  ret float 1.000000e+00
+}
+
+define double @foo_double() {
+; SMALL-LABEL: foo_double:
+; SMALL:       # %bb.0: # %entry
+; SMALL-NEXT:    ld 3, .LC1 at toc(2)
+; SMALL-NEXT:    lfd 1, 0(3)
+; SMALL-NEXT:    blr
+;
+; MEDIUM-LABEL: foo_double:
+; MEDIUM:       # %bb.0: # %entry
+; MEDIUM-NEXT:    addis 3, 2, .LCPI1_0 at toc@ha
+; MEDIUM-NEXT:    addi 3, 3, .LCPI1_0 at toc@l
+; MEDIUM-NEXT:    lfd 1, 0(3)
+; MEDIUM-NEXT:    blr
+;
+; LARGE-LABEL: foo_double:
+; LARGE:       # %bb.0: # %entry
+; LARGE-NEXT:    addis 3, 2, .LC1 at toc@ha
+; LARGE-NEXT:    ld 3, .LC1 at toc@l(3)
+; LARGE-NEXT:    lfd 1, 0(3)
+; LARGE-NEXT:    blr
+entry:
+  ret double 1.000000e+00
+}

diff  --git a/llvm/test/MachineVerifier/test_g_constant_pool.mir b/llvm/test/MachineVerifier/test_g_constant_pool.mir
new file mode 100644
index 0000000000000..3ec29f795d83b
--- /dev/null
+++ b/llvm/test/MachineVerifier/test_g_constant_pool.mir
@@ -0,0 +1,40 @@
+# RUN: not --crash llc -o - -march=arm64 -global-isel -run-pass=none \
+# RUN:   -verify-machineinstrs %s 2>&1 | FileCheck %s
+# REQUIRES: aarch64-registered-target
+
+---
+name:            test_constant_pool
+constants:
+  - id:          0
+    value:       'double 3.250000e+00'
+stack:
+  - { id: 0, size: 64, alignment: 8 }
+legalized:       true
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+liveins:
+body:             |
+  bb.0:
+
+    ; CHECK: Bad machine code: Too few operands
+    %0:_(p0) = G_CONSTANT_POOL
+
+    ; CHECK: Bad machine code: Src operand 1 must be a constant pool index
+    %1:_(p0) = G_CONSTANT_POOL 1
+
+    ; CHECK: Bad machine code: Src operand 1 must be a constant pool index
+    %2:_(p0) = G_CONSTANT_POOL i32 1
+
+    ; CHECK: Bad machine code: Src operand 1 must be a constant pool index
+    %3:_(p0) = G_CONSTANT_POOL %stack.0
+
+    ; CHECK: Dst operand 0 must be a pointer
+    %4:_(s32) = G_CONSTANT_POOL %const.0
+
+    ; CHECK: Dst operand 0 must be a pointer
+    %5:_(s64) = G_CONSTANT_POOL %const.0
+
+    ; CHECK-NOT: %6
+    %6:_(p0) = G_CONSTANT_POOL %const.0
+...


        


More information about the llvm-commits mailing list