[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