[llvm] 75265c7 - [LoongArch] Lower BlockAddress/JumpTable
Weining Lu via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 25 20:01:44 PDT 2022
Author: wanglei
Date: 2022-09-26T10:52:54+08:00
New Revision: 75265c7f4975c199cbeb544b07ca511b6fc865e6
URL: https://github.com/llvm/llvm-project/commit/75265c7f4975c199cbeb544b07ca511b6fc865e6
DIFF: https://github.com/llvm/llvm-project/commit/75265c7f4975c199cbeb544b07ca511b6fc865e6.diff
LOG: [LoongArch] Lower BlockAddress/JumpTable
This patch uses a unified interface for lower GlobalAddress ConstantPool
BlockAddress and JumpTable.
This patch allows lowering addresses by using PC-relative addressing
for DSO-local symbols, and accessing the address through the global
offset table for DSO-preemptable symbols.
Remove hardcoded `MininumJumpTableEntries` for test lower JumpTable.
Also updated some test cases using ConstantPool, due to the addition of
relocation information.
Differential Revision: https://reviews.llvm.org/D134431
Added:
llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
llvm/test/CodeGen/LoongArch/block-address.ll
llvm/test/CodeGen/LoongArch/global-address.ll
Modified:
llvm/lib/Target/LoongArch/CMakeLists.txt
llvm/lib/Target/LoongArch/LoongArch.h
llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
llvm/lib/Target/LoongArch/LoongArchISelLowering.h
llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h
llvm/test/CodeGen/LoongArch/calling-conv-lp64d.ll
llvm/test/CodeGen/LoongArch/double-imm.ll
llvm/test/CodeGen/LoongArch/float-imm.ll
llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll
llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll
llvm/test/CodeGen/LoongArch/jump-table.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/LoongArch/CMakeLists.txt b/llvm/lib/Target/LoongArch/CMakeLists.txt
index 8de85c5fde09a..bf7f730376b64 100644
--- a/llvm/lib/Target/LoongArch/CMakeLists.txt
+++ b/llvm/lib/Target/LoongArch/CMakeLists.txt
@@ -17,6 +17,7 @@ add_public_tablegen_target(LoongArchCommonTableGen)
add_llvm_target(LoongArchCodeGen
LoongArchAsmPrinter.cpp
LoongArchExpandAtomicPseudoInsts.cpp
+ LoongArchExpandPseudoInsts.cpp
LoongArchFrameLowering.cpp
LoongArchInstrInfo.cpp
LoongArchISelDAGToDAG.cpp
diff --git a/llvm/lib/Target/LoongArch/LoongArch.h b/llvm/lib/Target/LoongArch/LoongArch.h
index 5f0da3aefa118..3d0a3b9ebf55b 100644
--- a/llvm/lib/Target/LoongArch/LoongArch.h
+++ b/llvm/lib/Target/LoongArch/LoongArch.h
@@ -36,6 +36,9 @@ bool lowerLoongArchMachineOperandToMCOperand(const MachineOperand &MO,
FunctionPass *createLoongArchISelDag(LoongArchTargetMachine &TM);
FunctionPass *createLoongArchExpandAtomicPseudoPass();
void initializeLoongArchExpandAtomicPseudoPass(PassRegistry &);
+
+FunctionPass *createLoongArchPreRAExpandPseudoPass();
+void initializeLoongArchPreRAExpandPseudoPass(PassRegistry &);
} // end namespace llvm
#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCH_H
diff --git a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
new file mode 100644
index 0000000000000..a7a5cd33fec0a
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
@@ -0,0 +1,162 @@
+//===-- LoongArchExpandPseudoInsts.cpp - Expand pseudo instructions -------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a pass that expands pseudo instructions into target
+// instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LoongArch.h"
+#include "LoongArchInstrInfo.h"
+#include "LoongArchTargetMachine.h"
+#include "MCTargetDesc/LoongArchBaseInfo.h"
+#include "MCTargetDesc/LoongArchMCTargetDesc.h"
+#include "llvm/CodeGen/LivePhysRegs.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/MC/MCContext.h"
+
+using namespace llvm;
+
+#define LOONGARCH_PRERA_EXPAND_PSEUDO_NAME \
+ "LoongArch Pre-RA pseudo instruction expansion pass"
+
+namespace {
+
+class LoongArchPreRAExpandPseudo : public MachineFunctionPass {
+public:
+ const LoongArchInstrInfo *TII;
+ static char ID;
+
+ LoongArchPreRAExpandPseudo() : MachineFunctionPass(ID) {
+ initializeLoongArchPreRAExpandPseudoPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesCFG();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+ StringRef getPassName() const override {
+ return LOONGARCH_PRERA_EXPAND_PSEUDO_NAME;
+ }
+
+private:
+ bool expandMBB(MachineBasicBlock &MBB);
+ bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
+ MachineBasicBlock::iterator &NextMBBI);
+ bool expandPcalau12iInstPair(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ MachineBasicBlock::iterator &NextMBBI,
+ unsigned FlagsHi, unsigned SecondOpcode,
+ unsigned FlagsLo);
+ bool expandLoadAddressPcrel(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ MachineBasicBlock::iterator &NextMBBI);
+ bool expandLoadAddressGot(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ MachineBasicBlock::iterator &NextMBBI);
+};
+
+char LoongArchPreRAExpandPseudo::ID = 0;
+
+bool LoongArchPreRAExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
+ TII =
+ static_cast<const LoongArchInstrInfo *>(MF.getSubtarget().getInstrInfo());
+ bool Modified = false;
+ for (auto &MBB : MF)
+ Modified |= expandMBB(MBB);
+ return Modified;
+}
+
+bool LoongArchPreRAExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
+ bool Modified = false;
+
+ MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
+ while (MBBI != E) {
+ MachineBasicBlock::iterator NMBBI = std::next(MBBI);
+ Modified |= expandMI(MBB, MBBI, NMBBI);
+ MBBI = NMBBI;
+ }
+
+ return Modified;
+}
+
+bool LoongArchPreRAExpandPseudo::expandMI(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
+ MachineBasicBlock::iterator &NextMBBI) {
+ switch (MBBI->getOpcode()) {
+ case LoongArch::PseudoLA_PCREL:
+ return expandLoadAddressPcrel(MBB, MBBI, NextMBBI);
+ case LoongArch::PseudoLA_GOT:
+ return expandLoadAddressGot(MBB, MBBI, NextMBBI);
+ }
+ return false;
+}
+
+bool LoongArchPreRAExpandPseudo::expandPcalau12iInstPair(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
+ MachineBasicBlock::iterator &NextMBBI, unsigned FlagsHi,
+ unsigned SecondOpcode, unsigned FlagsLo) {
+ MachineFunction *MF = MBB.getParent();
+ MachineInstr &MI = *MBBI;
+ DebugLoc DL = MI.getDebugLoc();
+
+ Register DestReg = MI.getOperand(0).getReg();
+ Register ScratchReg =
+ MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass);
+ MachineOperand &Symbol = MI.getOperand(1);
+
+ BuildMI(MBB, MBBI, DL, TII->get(LoongArch::PCALAU12I), ScratchReg)
+ .addDisp(Symbol, 0, FlagsHi);
+
+ MachineInstr *SecondMI =
+ BuildMI(MBB, MBBI, DL, TII->get(SecondOpcode), DestReg)
+ .addReg(ScratchReg)
+ .addDisp(Symbol, 0, FlagsLo);
+
+ if (MI.hasOneMemOperand())
+ SecondMI->addMemOperand(*MF, *MI.memoperands_begin());
+
+ MI.eraseFromParent();
+ return true;
+}
+
+bool LoongArchPreRAExpandPseudo::expandLoadAddressPcrel(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
+ MachineBasicBlock::iterator &NextMBBI) {
+ MachineFunction *MF = MBB.getParent();
+ const auto &STI = MF->getSubtarget<LoongArchSubtarget>();
+ unsigned SecondOpcode = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
+ return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_PCREL_HI,
+ SecondOpcode, LoongArchII::MO_PCREL_LO);
+}
+
+bool LoongArchPreRAExpandPseudo::expandLoadAddressGot(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
+ MachineBasicBlock::iterator &NextMBBI) {
+ MachineFunction *MF = MBB.getParent();
+ const auto &STI = MF->getSubtarget<LoongArchSubtarget>();
+ unsigned SecondOpcode = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
+ return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_GOT_PC_HI,
+ SecondOpcode, LoongArchII::MO_GOT_PC_LO);
+}
+
+} // end namespace
+
+INITIALIZE_PASS(LoongArchPreRAExpandPseudo, "LoongArch-prera-expand-pseudo",
+ LOONGARCH_PRERA_EXPAND_PSEUDO_NAME, false, false)
+
+namespace llvm {
+
+FunctionPass *createLoongArchPreRAExpandPseudoPass() {
+ return new LoongArchPreRAExpandPseudo();
+}
+
+} // end namespace llvm
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 314765dcdccc8..920a9da58b859 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -58,7 +58,9 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::ROTL, GRLenVT, Expand);
setOperationAction(ISD::CTPOP, GRLenVT, Expand);
- setOperationAction({ISD::GlobalAddress, ISD::ConstantPool}, GRLenVT, Custom);
+ setOperationAction({ISD::GlobalAddress, ISD::BlockAddress, ISD::ConstantPool,
+ ISD::JumpTable},
+ GRLenVT, Custom);
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
@@ -128,8 +130,6 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::FMAXNUM_IEEE, MVT::f64, Legal);
}
- // Effectively disable jump table generation.
- setMinimumJumpTableEntries(INT_MAX);
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
setOperationAction(ISD::BR_CC, GRLenVT, Expand);
@@ -180,6 +180,10 @@ SDValue LoongArchTargetLowering::LowerOperation(SDValue Op,
return lowerGlobalAddress(Op, DAG);
case ISD::INTRINSIC_WO_CHAIN:
return lowerINTRINSIC_WO_CHAIN(Op, DAG);
+ case ISD::BlockAddress:
+ return lowerBlockAddress(Op, DAG);
+ case ISD::JumpTable:
+ return lowerJumpTable(Op, DAG);
case ISD::SHL_PARTS:
return lowerShiftLeftParts(Op, DAG);
case ISD::SRA_PARTS:
@@ -272,46 +276,66 @@ SDValue LoongArchTargetLowering::lowerFP_TO_SINT(SDValue Op,
return DAG.getNode(ISD::BITCAST, DL, Op.getValueType(), Trunc);
}
+static SDValue getTargetNode(GlobalAddressSDNode *N, SDLoc DL, EVT Ty,
+ SelectionDAG &DAG, unsigned Flags) {
+ return DAG.getTargetGlobalAddress(N->getGlobal(), DL, Ty, 0, Flags);
+}
+
+static SDValue getTargetNode(BlockAddressSDNode *N, SDLoc DL, EVT Ty,
+ SelectionDAG &DAG, unsigned Flags) {
+ return DAG.getTargetBlockAddress(N->getBlockAddress(), Ty, N->getOffset(),
+ Flags);
+}
+
+static SDValue getTargetNode(ConstantPoolSDNode *N, SDLoc DL, EVT Ty,
+ SelectionDAG &DAG, unsigned Flags) {
+ return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlign(),
+ N->getOffset(), Flags);
+}
+
+static SDValue getTargetNode(JumpTableSDNode *N, SDLoc DL, EVT Ty,
+ SelectionDAG &DAG, unsigned Flags) {
+ return DAG.getTargetJumpTable(N->getIndex(), Ty, Flags);
+}
+
+template <class NodeTy>
+SDValue LoongArchTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
+ bool IsLocal) const {
+ SDLoc DL(N);
+ EVT Ty = getPointerTy(DAG.getDataLayout());
+ SDValue Addr = getTargetNode(N, DL, Ty, DAG, 0);
+ // TODO: Check CodeModel.
+ if (IsLocal)
+ // This generates the pattern (PseudoLA_PCREL sym), which expands to
+ // (addi.w/d (pcalau12i %pc_hi20(sym)) %pc_lo12(sym)).
+ return SDValue(DAG.getMachineNode(LoongArch::PseudoLA_PCREL, DL, Ty, Addr),
+ 0);
+
+ // This generates the pattern (PseudoLA_GOT sym), which expands to (ld.w/d
+ // (pcalau12i %got_pc_hi20(sym)) %got_pc_lo12(sym)).
+ return SDValue(DAG.getMachineNode(LoongArch::PseudoLA_GOT, DL, Ty, Addr), 0);
+}
+
+SDValue LoongArchTargetLowering::lowerBlockAddress(SDValue Op,
+ SelectionDAG &DAG) const {
+ return getAddr(cast<BlockAddressSDNode>(Op), DAG);
+}
+
+SDValue LoongArchTargetLowering::lowerJumpTable(SDValue Op,
+ SelectionDAG &DAG) const {
+ return getAddr(cast<JumpTableSDNode>(Op), DAG);
+}
+
SDValue LoongArchTargetLowering::lowerConstantPool(SDValue Op,
SelectionDAG &DAG) const {
- SDLoc DL(Op);
- EVT Ty = Op.getValueType();
- ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
-
- // FIXME: Only support PC-relative addressing to access the symbol.
- // Target flags will be added later.
- if (!isPositionIndependent()) {
- SDValue ConstantN = DAG.getTargetConstantPool(
- N->getConstVal(), Ty, N->getAlign(), N->getOffset());
- SDValue AddrHi(DAG.getMachineNode(LoongArch::PCALAU12I, DL, Ty, ConstantN),
- 0);
- SDValue Addr(DAG.getMachineNode(Subtarget.is64Bit() ? LoongArch::ADDI_D
- : LoongArch::ADDI_W,
- DL, Ty, AddrHi, ConstantN),
- 0);
- return Addr;
- }
- report_fatal_error("Unable to lower ConstantPool");
+ return getAddr(cast<ConstantPoolSDNode>(Op), DAG);
}
SDValue LoongArchTargetLowering::lowerGlobalAddress(SDValue Op,
SelectionDAG &DAG) const {
- SDLoc DL(Op);
- EVT Ty = getPointerTy(DAG.getDataLayout());
- const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
- unsigned ADDIOp = Subtarget.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
-
- // TODO: Support dso_preemptable and target flags.
- if (GV->isDSOLocal()) {
- SDValue GAHi =
- DAG.getTargetGlobalAddress(GV, DL, Ty, 0, LoongArchII::MO_PCREL_HI);
- SDValue GALo =
- DAG.getTargetGlobalAddress(GV, DL, Ty, 0, LoongArchII::MO_PCREL_LO);
- SDValue AddrHi(DAG.getMachineNode(LoongArch::PCALAU12I, DL, Ty, GAHi), 0);
-
- return SDValue(DAG.getMachineNode(ADDIOp, DL, Ty, AddrHi, GALo), 0);
- }
- report_fatal_error("Unable to lowerGlobalAddress");
+ GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
+ assert(N->getOffset() == 0 && "unexpected offset in global node");
+ return getAddr(N, DAG, N->getGlobal()->isDSOLocal());
}
SDValue LoongArchTargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
index fa70ae450fa1d..714c6398d3a91 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
@@ -130,7 +130,11 @@ class LoongArchTargetLowering : public TargetLowering {
bool IsRet, CallLoweringInfo *CLI,
LoongArchCCAssignFn Fn) const;
+ template <class NodeTy>
+ SDValue getAddr(NodeTy *N, SelectionDAG &DAG, bool IsLocal = true) const;
SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const;
diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
index 6b802a410a58d..a90fb8960a8c1 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -919,6 +919,12 @@ let isBarrier = 1, isReturn = 1, isTerminator = 1 in
def PseudoRET : Pseudo<(outs), (ins), [(loongarch_ret)]>,
PseudoInstExpansion<(JIRL R0, R1, 0)>;
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+def PseudoLA_PCREL : Pseudo<(outs GPR:$dst), (ins grlenimm:$src), []>;
+
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+def PseudoLA_GOT : Pseudo<(outs GPR:$dst), (ins grlenimm:$src), []>;
+
/// BSTRINS and BSTRPICK
let Predicates = [IsLA32] in {
diff --git a/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp b/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
index 68b42956b697a..af17ffc759886 100644
--- a/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
@@ -47,6 +47,12 @@ static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym,
case LoongArchII::MO_PCREL_LO:
Kind = LoongArchMCExpr::VK_LoongArch_PCALA_LO12;
break;
+ case LoongArchII::MO_GOT_PC_HI:
+ Kind = LoongArchMCExpr::VK_LoongArch_GOT_HI20;
+ break;
+ case LoongArchII::MO_GOT_PC_LO:
+ Kind = LoongArchMCExpr::VK_LoongArch_GOT_LO12;
+ break;
// TODO: Handle more target-flags.
}
@@ -94,9 +100,12 @@ bool llvm::lowerLoongArchMachineOperandToMCOperand(const MachineOperand &MO,
MCOp = lowerSymbolOperand(
MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), AP);
break;
- // TODO: lower special operands
case MachineOperand::MO_BlockAddress:
+ MCOp = lowerSymbolOperand(
+ MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP);
+ break;
case MachineOperand::MO_JumpTableIndex:
+ MCOp = lowerSymbolOperand(MO, AP.GetJTISymbol(MO.getIndex()), AP);
break;
}
return true;
diff --git a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
index 7f45c7ae1cd19..ee6f585cec9d1 100644
--- a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
@@ -27,6 +27,8 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTarget() {
// Register the target.
RegisterTargetMachine<LoongArchTargetMachine> X(getTheLoongArch32Target());
RegisterTargetMachine<LoongArchTargetMachine> Y(getTheLoongArch64Target());
+ auto *PR = PassRegistry::getPassRegistry();
+ initializeLoongArchPreRAExpandPseudoPass(*PR);
}
static std::string computeDataLayout(const Triple &TT) {
@@ -103,6 +105,7 @@ class LoongArchPassConfig : public TargetPassConfig {
void addIRPasses() override;
bool addInstSelector() override;
void addPreEmitPass2() override;
+ void addPreRegAlloc() override;
};
} // end namespace
@@ -129,3 +132,7 @@ void LoongArchPassConfig::addPreEmitPass2() {
// forward progress in the LL/SC block.
addPass(createLoongArchExpandAtomicPseudoPass());
}
+
+void LoongArchPassConfig::addPreRegAlloc() {
+ addPass(createLoongArchPreRAExpandPseudoPass());
+}
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h
index 72afab3ec3051..77938b997ec01 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h
@@ -31,6 +31,8 @@ enum {
MO_CALL_PLT,
MO_PCREL_HI,
MO_PCREL_LO,
+ MO_GOT_PC_HI,
+ MO_GOT_PC_LO,
// TODO: Add more flags.
};
} // end namespace LoongArchII
diff --git a/llvm/test/CodeGen/LoongArch/block-address.ll b/llvm/test/CodeGen/LoongArch/block-address.ll
new file mode 100644
index 0000000000000..63d310dd9beab
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/block-address.ll
@@ -0,0 +1,39 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32
+; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64
+
+ at addr = dso_local global ptr null
+
+define void @test_blockaddress() nounwind {
+; LA32-LABEL: test_blockaddress:
+; LA32: # %bb.0:
+; LA32-NEXT: pcalau12i $a0, %pc_hi20(addr)
+; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(addr)
+; LA32-NEXT: pcalau12i $a1, %pc_hi20(.Ltmp0)
+; LA32-NEXT: addi.w $a1, $a1, %pc_lo12(.Ltmp0)
+; LA32-NEXT: st.w $a1, $a0, 0
+; LA32-NEXT: ld.w $a0, $a0, 0
+; LA32-NEXT: jr $a0
+; LA32-NEXT: .Ltmp0: # Block address taken
+; LA32-NEXT: .LBB0_1: # %block
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_blockaddress:
+; LA64: # %bb.0:
+; LA64-NEXT: pcalau12i $a0, %pc_hi20(addr)
+; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(addr)
+; LA64-NEXT: pcalau12i $a1, %pc_hi20(.Ltmp0)
+; LA64-NEXT: addi.d $a1, $a1, %pc_lo12(.Ltmp0)
+; LA64-NEXT: st.d $a1, $a0, 0
+; LA64-NEXT: ld.d $a0, $a0, 0
+; LA64-NEXT: jr $a0
+; LA64-NEXT: .Ltmp0: # Block address taken
+; LA64-NEXT: .LBB0_1: # %block
+; LA64-NEXT: ret
+ store volatile ptr blockaddress(@test_blockaddress, %block), ptr @addr
+ %val = load volatile ptr, ptr @addr
+ indirectbr ptr %val, [label %block]
+
+block:
+ ret void
+}
diff --git a/llvm/test/CodeGen/LoongArch/calling-conv-lp64d.ll b/llvm/test/CodeGen/LoongArch/calling-conv-lp64d.ll
index 28f571e5c6289..ae2ce72914399 100644
--- a/llvm/test/CodeGen/LoongArch/calling-conv-lp64d.ll
+++ b/llvm/test/CodeGen/LoongArch/calling-conv-lp64d.ll
@@ -462,30 +462,30 @@ define i64 @caller_double_in_gpr_exhausted_fprs() nounwind {
; CHECK: # %bb.0:
; CHECK-NEXT: addi.d $sp, $sp, -16
; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
-; CHECK-NEXT: pcalau12i $a0, .LCPI21_0
-; CHECK-NEXT: addi.d $a0, $a0, .LCPI21_0
-; CHECK-NEXT: pcalau12i $a1, .LCPI21_1
-; CHECK-NEXT: addi.d $a1, $a1, .LCPI21_1
-; CHECK-NEXT: pcalau12i $a2, .LCPI21_2
-; CHECK-NEXT: addi.d $a2, $a2, .LCPI21_2
-; CHECK-NEXT: pcalau12i $a3, .LCPI21_3
-; CHECK-NEXT: addi.d $a3, $a3, .LCPI21_3
-; CHECK-NEXT: pcalau12i $a4, .LCPI21_4
-; CHECK-NEXT: addi.d $a4, $a4, .LCPI21_4
-; CHECK-NEXT: pcalau12i $a5, .LCPI21_5
-; CHECK-NEXT: addi.d $a5, $a5, .LCPI21_5
-; CHECK-NEXT: addi.d $a6, $zero, 1
-; CHECK-NEXT: movgr2fr.d $fa0, $a6
-; CHECK-NEXT: ffint.d.l $fa0, $fa0
-; CHECK-NEXT: fld.d $fa1, $a5, 0
-; CHECK-NEXT: fld.d $fa2, $a4, 0
-; CHECK-NEXT: fld.d $fa3, $a3, 0
-; CHECK-NEXT: fld.d $fa4, $a2, 0
-; CHECK-NEXT: fld.d $fa5, $a1, 0
+; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI21_0)
+; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI21_0)
+; CHECK-NEXT: fld.d $fa1, $a0, 0
+; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI21_1)
+; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI21_1)
+; CHECK-NEXT: fld.d $fa2, $a0, 0
+; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI21_2)
+; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI21_2)
+; CHECK-NEXT: fld.d $fa3, $a0, 0
+; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI21_3)
+; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI21_3)
+; CHECK-NEXT: fld.d $fa4, $a0, 0
+; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI21_4)
+; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI21_4)
+; CHECK-NEXT: fld.d $fa5, $a0, 0
+; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI21_5)
+; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI21_5)
; CHECK-NEXT: fld.d $fa6, $a0, 0
-; CHECK-NEXT: pcalau12i $a0, .LCPI21_6
-; CHECK-NEXT: addi.d $a0, $a0, .LCPI21_6
+; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI21_6)
+; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI21_6)
; CHECK-NEXT: fld.d $fa7, $a0, 0
+; CHECK-NEXT: addi.d $a0, $zero, 1
+; CHECK-NEXT: movgr2fr.d $fa0, $a0
+; CHECK-NEXT: ffint.d.l $fa0, $fa0
; CHECK-NEXT: ori $a0, $zero, 0
; CHECK-NEXT: lu32i.d $a0, 131072
; CHECK-NEXT: lu52i.d $a0, $a0, 1026
diff --git a/llvm/test/CodeGen/LoongArch/double-imm.ll b/llvm/test/CodeGen/LoongArch/double-imm.ll
index f21deb0c00389..3e89db3ec5c8c 100644
--- a/llvm/test/CodeGen/LoongArch/double-imm.ll
+++ b/llvm/test/CodeGen/LoongArch/double-imm.ll
@@ -35,15 +35,15 @@ define double @f64_negative_zero() nounwind {
define double @f64_constant_pi() nounwind {
; LA32-LABEL: f64_constant_pi:
; LA32: # %bb.0:
-; LA32-NEXT: pcalau12i $a0, .LCPI2_0
-; LA32-NEXT: addi.w $a0, $a0, .LCPI2_0
+; LA32-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_0)
+; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI2_0)
; LA32-NEXT: fld.d $fa0, $a0, 0
; LA32-NEXT: ret
;
; LA64-LABEL: f64_constant_pi:
; LA64: # %bb.0:
-; LA64-NEXT: pcalau12i $a0, .LCPI2_0
-; LA64-NEXT: addi.d $a0, $a0, .LCPI2_0
+; LA64-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_0)
+; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI2_0)
; LA64-NEXT: fld.d $fa0, $a0, 0
; LA64-NEXT: ret
ret double 3.1415926535897931159979634685441851615905761718750
diff --git a/llvm/test/CodeGen/LoongArch/float-imm.ll b/llvm/test/CodeGen/LoongArch/float-imm.ll
index d9c184571caab..e2cbf4bf9b3e8 100644
--- a/llvm/test/CodeGen/LoongArch/float-imm.ll
+++ b/llvm/test/CodeGen/LoongArch/float-imm.ll
@@ -33,15 +33,15 @@ define float @f32_negative_zero() nounwind {
define float @f32_constant_pi() nounwind {
; LA32-LABEL: f32_constant_pi:
; LA32: # %bb.0:
-; LA32-NEXT: pcalau12i $a0, .LCPI2_0
-; LA32-NEXT: addi.w $a0, $a0, .LCPI2_0
+; LA32-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_0)
+; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI2_0)
; LA32-NEXT: fld.s $fa0, $a0, 0
; LA32-NEXT: ret
;
; LA64-LABEL: f32_constant_pi:
; LA64: # %bb.0:
-; LA64-NEXT: pcalau12i $a0, .LCPI2_0
-; LA64-NEXT: addi.d $a0, $a0, .LCPI2_0
+; LA64-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_0)
+; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI2_0)
; LA64-NEXT: fld.s $fa0, $a0, 0
; LA64-NEXT: ret
ret float 3.14159274101257324218750
diff --git a/llvm/test/CodeGen/LoongArch/global-address.ll b/llvm/test/CodeGen/LoongArch/global-address.ll
new file mode 100644
index 0000000000000..56ab2ab27de32
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/global-address.ll
@@ -0,0 +1,53 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc --mtriple=loongarch32 --relocation-model=static < %s | FileCheck %s --check-prefix=LA32NOPIC
+; RUN: llc --mtriple=loongarch32 --relocation-model=pic < %s | FileCheck %s --check-prefix=LA32PIC
+; RUN: llc --mtriple=loongarch64 --relocation-model=static < %s | FileCheck %s --check-prefix=LA64NOPIC
+; RUN: llc --mtriple=loongarch64 --relocation-model=pic < %s | FileCheck %s --check-prefix=LA64PIC
+
+ at g = dso_local global i32 zeroinitializer, align 4
+ at G = global i32 zeroinitializer, align 4
+
+define void @foo() nounwind {
+; LA32NOPIC-LABEL: foo:
+; LA32NOPIC: # %bb.0:
+; LA32NOPIC-NEXT: pcalau12i $a0, %got_hi20(G)
+; LA32NOPIC-NEXT: ld.w $a0, $a0, %got_lo12(G)
+; LA32NOPIC-NEXT: ld.w $a0, $a0, 0
+; LA32NOPIC-NEXT: pcalau12i $a0, %pc_hi20(g)
+; LA32NOPIC-NEXT: addi.w $a0, $a0, %pc_lo12(g)
+; LA32NOPIC-NEXT: ld.w $a0, $a0, 0
+; LA32NOPIC-NEXT: ret
+;
+; LA32PIC-LABEL: foo:
+; LA32PIC: # %bb.0:
+; LA32PIC-NEXT: pcalau12i $a0, %got_hi20(G)
+; LA32PIC-NEXT: ld.w $a0, $a0, %got_lo12(G)
+; LA32PIC-NEXT: ld.w $a0, $a0, 0
+; LA32PIC-NEXT: pcalau12i $a0, %pc_hi20(.Lg$local)
+; LA32PIC-NEXT: addi.w $a0, $a0, %pc_lo12(.Lg$local)
+; LA32PIC-NEXT: ld.w $a0, $a0, 0
+; LA32PIC-NEXT: ret
+;
+; LA64NOPIC-LABEL: foo:
+; LA64NOPIC: # %bb.0:
+; LA64NOPIC-NEXT: pcalau12i $a0, %got_hi20(G)
+; LA64NOPIC-NEXT: ld.d $a0, $a0, %got_lo12(G)
+; LA64NOPIC-NEXT: ld.w $a0, $a0, 0
+; LA64NOPIC-NEXT: pcalau12i $a0, %pc_hi20(g)
+; LA64NOPIC-NEXT: addi.d $a0, $a0, %pc_lo12(g)
+; LA64NOPIC-NEXT: ld.w $a0, $a0, 0
+; LA64NOPIC-NEXT: ret
+;
+; LA64PIC-LABEL: foo:
+; LA64PIC: # %bb.0:
+; LA64PIC-NEXT: pcalau12i $a0, %got_hi20(G)
+; LA64PIC-NEXT: ld.d $a0, $a0, %got_lo12(G)
+; LA64PIC-NEXT: ld.w $a0, $a0, 0
+; LA64PIC-NEXT: pcalau12i $a0, %pc_hi20(.Lg$local)
+; LA64PIC-NEXT: addi.d $a0, $a0, %pc_lo12(.Lg$local)
+; LA64PIC-NEXT: ld.w $a0, $a0, 0
+; LA64PIC-NEXT: ret
+ %V = load volatile i32, ptr @G
+ %v = load volatile i32, ptr @g
+ ret void
+}
diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll
index eaa3feba36205..070027b698436 100644
--- a/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll
+++ b/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll
@@ -116,8 +116,8 @@ define i32 @convert_double_to_i32(double %a) nounwind {
define i32 @convert_double_to_u32(double %a) nounwind {
; LA32-LABEL: convert_double_to_u32:
; LA32: # %bb.0:
-; LA32-NEXT: pcalau12i $a0, .LCPI7_0
-; LA32-NEXT: addi.w $a0, $a0, .LCPI7_0
+; LA32-NEXT: pcalau12i $a0, %pc_hi20(.LCPI7_0)
+; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI7_0)
; LA32-NEXT: fld.d $fa1, $a0, 0
; LA32-NEXT: fsub.d $fa2, $fa0, $fa1
; LA32-NEXT: ftintrz.w.d $fa2, $fa2
@@ -173,8 +173,8 @@ define i64 @convert_double_to_u64(double %a) nounwind {
;
; LA64-LABEL: convert_double_to_u64:
; LA64: # %bb.0:
-; LA64-NEXT: pcalau12i $a0, .LCPI9_0
-; LA64-NEXT: addi.d $a0, $a0, .LCPI9_0
+; LA64-NEXT: pcalau12i $a0, %pc_hi20(.LCPI9_0)
+; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI9_0)
; LA64-NEXT: fld.d $fa1, $a0, 0
; LA64-NEXT: fsub.d $fa2, $fa0, $fa1
; LA64-NEXT: ftintrz.l.d $fa2, $fa2
@@ -232,8 +232,8 @@ define double @convert_u32_to_double(i32 %a) nounwind {
; LA32-NEXT: lu12i.w $a1, 275200
; LA32-NEXT: st.w $a1, $sp, 12
; LA32-NEXT: st.w $a0, $sp, 8
-; LA32-NEXT: pcalau12i $a0, .LCPI12_0
-; LA32-NEXT: addi.w $a0, $a0, .LCPI12_0
+; LA32-NEXT: pcalau12i $a0, %pc_hi20(.LCPI12_0)
+; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI12_0)
; LA32-NEXT: fld.d $fa0, $a0, 0
; LA32-NEXT: fld.d $fa1, $sp, 8
; LA32-NEXT: fsub.d $fa0, $fa1, $fa0
@@ -242,12 +242,12 @@ define double @convert_u32_to_double(i32 %a) nounwind {
;
; LA64-LABEL: convert_u32_to_double:
; LA64: # %bb.0:
+; LA64-NEXT: pcalau12i $a1, %pc_hi20(.LCPI12_0)
+; LA64-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI12_0)
+; LA64-NEXT: fld.d $fa0, $a1, 0
; LA64-NEXT: lu52i.d $a1, $zero, 1107
-; LA64-NEXT: movgr2fr.d $fa0, $a1
-; LA64-NEXT: pcalau12i $a1, .LCPI12_0
-; LA64-NEXT: addi.d $a1, $a1, .LCPI12_0
-; LA64-NEXT: fld.d $fa1, $a1, 0
-; LA64-NEXT: fsub.d $fa0, $fa0, $fa1
+; LA64-NEXT: movgr2fr.d $fa1, $a1
+; LA64-NEXT: fsub.d $fa0, $fa1, $fa0
; LA64-NEXT: lu12i.w $a1, 275200
; LA64-NEXT: bstrins.d $a0, $a1, 63, 32
; LA64-NEXT: movgr2fr.d $fa1, $a0
@@ -273,8 +273,8 @@ define double @convert_u64_to_double(i64 %a) nounwind {
; LA64-NEXT: lu52i.d $a2, $zero, 1107
; LA64-NEXT: or $a1, $a1, $a2
; LA64-NEXT: movgr2fr.d $fa0, $a1
-; LA64-NEXT: pcalau12i $a1, .LCPI13_0
-; LA64-NEXT: addi.d $a1, $a1, .LCPI13_0
+; LA64-NEXT: pcalau12i $a1, %pc_hi20(.LCPI13_0)
+; LA64-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI13_0)
; LA64-NEXT: fld.d $fa1, $a1, 0
; LA64-NEXT: fsub.d $fa0, $fa0, $fa1
; LA64-NEXT: lu12i.w $a1, 275200
diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll
index 3661d709fb042..559206a4db5ac 100644
--- a/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll
+++ b/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll
@@ -181,8 +181,8 @@ define zeroext i16 @convert_float_to_u16(float %a) nounwind {
define i32 @convert_float_to_u32(float %a) nounwind {
; LA32F-LABEL: convert_float_to_u32:
; LA32F: # %bb.0:
-; LA32F-NEXT: pcalau12i $a0, .LCPI6_0
-; LA32F-NEXT: addi.w $a0, $a0, .LCPI6_0
+; LA32F-NEXT: pcalau12i $a0, %pc_hi20(.LCPI6_0)
+; LA32F-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI6_0)
; LA32F-NEXT: fld.s $fa1, $a0, 0
; LA32F-NEXT: fsub.s $fa2, $fa0, $fa1
; LA32F-NEXT: ftintrz.w.s $fa2, $fa2
@@ -200,8 +200,8 @@ define i32 @convert_float_to_u32(float %a) nounwind {
;
; LA32D-LABEL: convert_float_to_u32:
; LA32D: # %bb.0:
-; LA32D-NEXT: pcalau12i $a0, .LCPI6_0
-; LA32D-NEXT: addi.w $a0, $a0, .LCPI6_0
+; LA32D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI6_0)
+; LA32D-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI6_0)
; LA32D-NEXT: fld.s $fa1, $a0, 0
; LA32D-NEXT: fsub.s $fa2, $fa0, $fa1
; LA32D-NEXT: ftintrz.w.s $fa2, $fa2
@@ -219,8 +219,8 @@ define i32 @convert_float_to_u32(float %a) nounwind {
;
; LA64F-LABEL: convert_float_to_u32:
; LA64F: # %bb.0:
-; LA64F-NEXT: pcalau12i $a0, .LCPI6_0
-; LA64F-NEXT: addi.d $a0, $a0, .LCPI6_0
+; LA64F-NEXT: pcalau12i $a0, %pc_hi20(.LCPI6_0)
+; LA64F-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI6_0)
; LA64F-NEXT: fld.s $fa1, $a0, 0
; LA64F-NEXT: fsub.s $fa2, $fa0, $fa1
; LA64F-NEXT: ftintrz.w.s $fa2, $fa2
@@ -266,8 +266,8 @@ define i64 @convert_float_to_u64(float %a) nounwind {
;
; LA64F-LABEL: convert_float_to_u64:
; LA64F: # %bb.0:
-; LA64F-NEXT: pcalau12i $a0, .LCPI7_0
-; LA64F-NEXT: addi.d $a0, $a0, .LCPI7_0
+; LA64F-NEXT: pcalau12i $a0, %pc_hi20(.LCPI7_0)
+; LA64F-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI7_0)
; LA64F-NEXT: fld.s $fa1, $a0, 0
; LA64F-NEXT: fsub.s $fa2, $fa0, $fa1
; LA64F-NEXT: ftintrz.w.s $fa2, $fa2
@@ -285,8 +285,8 @@ define i64 @convert_float_to_u64(float %a) nounwind {
;
; LA64D-LABEL: convert_float_to_u64:
; LA64D: # %bb.0:
-; LA64D-NEXT: pcalau12i $a0, .LCPI7_0
-; LA64D-NEXT: addi.d $a0, $a0, .LCPI7_0
+; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI7_0)
+; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI7_0)
; LA64D-NEXT: fld.s $fa1, $a0, 0
; LA64D-NEXT: fsub.s $fa2, $fa0, $fa1
; LA64D-NEXT: ftintrz.l.s $fa2, $fa2
@@ -503,8 +503,8 @@ define float @convert_u32_to_float(i32 %a) nounwind {
; LA32D-NEXT: lu12i.w $a1, 275200
; LA32D-NEXT: st.w $a1, $sp, 12
; LA32D-NEXT: st.w $a0, $sp, 8
-; LA32D-NEXT: pcalau12i $a0, .LCPI14_0
-; LA32D-NEXT: addi.w $a0, $a0, .LCPI14_0
+; LA32D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI14_0)
+; LA32D-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI14_0)
; LA32D-NEXT: fld.d $fa0, $a0, 0
; LA32D-NEXT: fld.d $fa1, $sp, 8
; LA32D-NEXT: fsub.d $fa0, $fa1, $fa0
diff --git a/llvm/test/CodeGen/LoongArch/jump-table.ll b/llvm/test/CodeGen/LoongArch/jump-table.ll
index db0fb059df271..fb75ce2eb912f 100644
--- a/llvm/test/CodeGen/LoongArch/jump-table.ll
+++ b/llvm/test/CodeGen/LoongArch/jump-table.ll
@@ -1,8 +1,17 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s \
+; RUN: llc --mtriple=loongarch32 --min-jump-table-entries=5 < %s \
; RUN: | FileCheck %s --check-prefix=LA32
-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s \
+; RUN: llc --mtriple=loongarch64 --min-jump-table-entries=5 < %s \
; RUN: | FileCheck %s --check-prefix=LA64
+; RUN: llc --mtriple=loongarch32 --min-jump-table-entries=4 < %s \
+; RUN: | FileCheck %s --check-prefix=LA32-JT
+; RUN: llc --mtriple=loongarch64 --min-jump-table-entries=4 < %s \
+; RUN: | FileCheck %s --check-prefix=LA64-JT
+
+;; The default mininum number of entries to use a jump table is 4.
+;;
+;; Note: The parameter `--min-jump-table-entries` will have no effect once we
+;; have set the default value using `setMinimumJumpTableEntries`.
define void @switch_4_arms(i32 %in, ptr %out) nounwind {
; LA32-LABEL: switch_4_arms:
@@ -69,6 +78,55 @@ define void @switch_4_arms(i32 %in, ptr %out) nounwind {
; LA64-NEXT: st.w $a2, $a1, 0
; LA64-NEXT: .LBB0_10: # %exit
; LA64-NEXT: ret
+;
+; LA32-JT-LABEL: switch_4_arms:
+; LA32-JT: # %bb.0: # %entry
+; LA32-JT-NEXT: addi.w $a2, $a0, -1
+; LA32-JT-NEXT: ori $a0, $zero, 3
+; LA32-JT-NEXT: bltu $a0, $a2, .LBB0_6
+; LA32-JT-NEXT: # %bb.1: # %entry
+; LA32-JT-NEXT: pcalau12i $a3, %pc_hi20(.LJTI0_0)
+; LA32-JT-NEXT: addi.w $a3, $a3, %pc_lo12(.LJTI0_0)
+; LA32-JT-NEXT: alsl.w $a2, $a2, $a3, 2
+; LA32-JT-NEXT: ld.w $a2, $a2, 0
+; LA32-JT-NEXT: jr $a2
+; LA32-JT-NEXT: .LBB0_2: # %bb1
+; LA32-JT-NEXT: ori $a0, $zero, 4
+; LA32-JT-NEXT: b .LBB0_5
+; LA32-JT-NEXT: .LBB0_3: # %bb3
+; LA32-JT-NEXT: ori $a0, $zero, 2
+; LA32-JT-NEXT: b .LBB0_5
+; LA32-JT-NEXT: .LBB0_4: # %bb4
+; LA32-JT-NEXT: ori $a0, $zero, 1
+; LA32-JT-NEXT: .LBB0_5: # %exit
+; LA32-JT-NEXT: st.w $a0, $a1, 0
+; LA32-JT-NEXT: .LBB0_6: # %exit
+; LA32-JT-NEXT: ret
+;
+; LA64-JT-LABEL: switch_4_arms:
+; LA64-JT: # %bb.0: # %entry
+; LA64-JT-NEXT: bstrpick.d $a0, $a0, 31, 0
+; LA64-JT-NEXT: addi.d $a2, $a0, -1
+; LA64-JT-NEXT: ori $a0, $zero, 3
+; LA64-JT-NEXT: bltu $a0, $a2, .LBB0_6
+; LA64-JT-NEXT: # %bb.1: # %entry
+; LA64-JT-NEXT: slli.d $a2, $a2, 3
+; LA64-JT-NEXT: pcalau12i $a3, %pc_hi20(.LJTI0_0)
+; LA64-JT-NEXT: addi.d $a3, $a3, %pc_lo12(.LJTI0_0)
+; LA64-JT-NEXT: ldx.d $a2, $a2, $a3
+; LA64-JT-NEXT: jr $a2
+; LA64-JT-NEXT: .LBB0_2: # %bb1
+; LA64-JT-NEXT: ori $a0, $zero, 4
+; LA64-JT-NEXT: b .LBB0_5
+; LA64-JT-NEXT: .LBB0_3: # %bb3
+; LA64-JT-NEXT: ori $a0, $zero, 2
+; LA64-JT-NEXT: b .LBB0_5
+; LA64-JT-NEXT: .LBB0_4: # %bb4
+; LA64-JT-NEXT: ori $a0, $zero, 1
+; LA64-JT-NEXT: .LBB0_5: # %exit
+; LA64-JT-NEXT: st.w $a0, $a1, 0
+; LA64-JT-NEXT: .LBB0_6: # %exit
+; LA64-JT-NEXT: ret
entry:
switch i32 %in, label %exit [
i32 1, label %bb1
More information about the llvm-commits
mailing list