[llvm] 4fb0e01 - [ARM] Generate out-of-line jump tables for XO without 32-bit branch
John Brawn via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 28 05:30:48 PDT 2023
Author: John Brawn
Date: 2023-06-28T13:30:39+01:00
New Revision: 4fb0e0114f626c6a492738f609744eab5d331310
URL: https://github.com/llvm/llvm-project/commit/4fb0e0114f626c6a492738f609744eab5d331310
DIFF: https://github.com/llvm/llvm-project/commit/4fb0e0114f626c6a492738f609744eab5d331310.diff
LOG: [ARM] Generate out-of-line jump tables for XO without 32-bit branch
When we only have a 16-bit pc-relative branch instruction we generate
a table of address for a jump table. Currently this is placed inline,
but this won't work with execute-only memory. In this case generate
the jump table out-of-line.
Differential Revision: https://reviews.llvm.org/D153774
Added:
Modified:
llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
llvm/lib/Target/ARM/ARMISelLowering.cpp
llvm/test/CodeGen/ARM/execute-only.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
index 590612e95f515..a6682f0ca162c 100644
--- a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
+++ b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
@@ -605,6 +605,10 @@ void ARMConstantIslands::doInitialJumpTablePlacement(
auto MJTI = MF->getJumpTableInfo();
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
+ // Only inline jump tables are placed in the function.
+ if (MJTI->getEntryKind() != MachineJumpTableInfo::EK_Inline)
+ return;
+
MachineBasicBlock *LastCorrectlyNumberedBB = nullptr;
for (MachineBasicBlock &MBB : *MF) {
auto MI = MBB.getLastNonDebugInstr();
@@ -777,6 +781,11 @@ initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {
// Compute block offsets and known bits.
BBUtils->adjustBBOffsetsAfter(&MF->front());
+ // We only care about jump table instructions when jump tables are inline.
+ MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
+ bool InlineJumpTables =
+ MJTI && MJTI->getEntryKind() == MachineJumpTableInfo::EK_Inline;
+
// Now go back through the instructions and build up our data structures.
for (MachineBasicBlock &MBB : *MF) {
// If this block doesn't fall through into the next MBB, then this is
@@ -799,7 +808,8 @@ initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {
continue; // Ignore other JT branches
case ARM::t2BR_JT:
case ARM::tBR_JTr:
- T2JumpTables.push_back(&I);
+ if (InlineJumpTables)
+ T2JumpTables.push_back(&I);
continue; // Does not get an entry in ImmBranches
case ARM::Bcc:
isCond = true;
@@ -846,7 +856,8 @@ initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {
// Scan the instructions for constant pool operands.
for (unsigned op = 0, e = I.getNumOperands(); op != e; ++op)
- if (I.getOperand(op).isCPI() || I.getOperand(op).isJTI()) {
+ if (I.getOperand(op).isCPI() ||
+ (I.getOperand(op).isJTI() && InlineJumpTables)) {
// We found one. The addressing mode tells us the max displacement
// from the PC that this instruction permits.
diff --git a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
index bf75e2279b7a1..f628a725f71fb 100644
--- a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
@@ -23,6 +23,7 @@
#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Support/Debug.h"
@@ -1041,6 +1042,15 @@ void ARMExpandPseudo::ExpandTMOV32BitImm(MachineBasicBlock &MBB,
Lower0_7 = Lower0_7.addExternalSymbol(ES, TF | ARMII::MO_LO_0_7);
break;
}
+ case MachineOperand::MO_JumpTableIndex: {
+ unsigned Idx = MO.getIndex();
+ unsigned TF = MO.getTargetFlags();
+ Upper8_15 = Upper8_15.addJumpTableIndex(Idx, TF | ARMII::MO_HI_8_15);
+ Upper0_7 = Upper0_7.addJumpTableIndex(Idx, TF | ARMII::MO_HI_0_7);
+ Lower8_15 = Lower8_15.addJumpTableIndex(Idx, TF | ARMII::MO_LO_8_15);
+ Lower0_7 = Lower0_7.addJumpTableIndex(Idx, TF | ARMII::MO_LO_0_7);
+ break;
+ }
default: {
const GlobalValue *GV = MO.getGlobal();
unsigned TF = MO.getTargetFlags();
@@ -2764,6 +2774,17 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
ExpandTMOV32BitImm(MBB, MBBI);
return true;
+ case ARM::tLEApcrelJT:
+ // Inline jump tables are handled in ARMAsmPrinter.
+ if (MI.getMF()->getJumpTableInfo()->getEntryKind() ==
+ MachineJumpTableInfo::EK_Inline)
+ return false;
+
+ // Use a 32-bit immediate move to generate the address of the jump table.
+ assert(STI->isThumb() && "Non-inline jump tables expected only in thumb");
+ ExpandTMOV32BitImm(MBB, MBBI);
+ return true;
+
case ARM::SUBS_PC_LR: {
MachineInstrBuilder MIB =
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::SUBri), ARM::PC)
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 6bffbc0435959..a12fd783fb998 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -3484,6 +3484,11 @@ SDValue ARMTargetLowering::LowerConstantPool(SDValue Op,
}
unsigned ARMTargetLowering::getJumpTableEncoding() const {
+ // If we don't have a 32-bit pc-relative branch instruction then the jump
+ // table consists of block addresses. Usually this is inline, but for
+ // execute-only it must be placed out-of-line.
+ if (Subtarget->genExecuteOnly() && !Subtarget->hasV8MBaselineOps())
+ return MachineJumpTableInfo::EK_BlockAddress;
return MachineJumpTableInfo::EK_Inline;
}
diff --git a/llvm/test/CodeGen/ARM/execute-only.ll b/llvm/test/CodeGen/ARM/execute-only.ll
index 1123efbc11a75..304b8553b574d 100644
--- a/llvm/test/CodeGen/ARM/execute-only.ll
+++ b/llvm/test/CodeGen/ARM/execute-only.ll
@@ -45,6 +45,27 @@ define i32 @jump_table(i32 %c, i32 %a, i32 %b) #0 {
; CHECK-NEXT: b.w
; CHECK-NEXT: b.w
+; CHECK-T1-LABEL: jump_table:
+; CHECK-T1: lsls [[REG_OFFSET:r[0-9]+]], {{r[0-9]+}}, #2
+; CHECK-T1-NEXT: movs [[REG_JT:r[0-9]+]], :upper8_15:.LJTI1_0
+; CHECK-T1-NEXT: lsls [[REG_JT]], [[REG_JT]], #8
+; CHECK-T1-NEXT: adds [[REG_JT]], :upper0_7:.LJTI1_0
+; CHECK-T1-NEXT: lsls [[REG_JT]], [[REG_JT]], #8
+; CHECK-T1-NEXT: adds [[REG_JT]], :lower8_15:.LJTI1_0
+; CHECK-T1-NEXT: lsls [[REG_JT]], [[REG_JT]], #8
+; CHECK-T1-NEXT: adds [[REG_JT]], :lower0_7:.LJTI1_0
+; CHECK-T1-NEXT: ldr [[REG_ENTRY:r[0-9]+]], [[[REG_JT]], [[REG_OFFSET]]]
+; CHECK-T1-NEXT: mov pc, [[REG_ENTRY]]
+; CHECK-T1: .section .rodata,"a",%progbits
+; CHECK-T1-NEXT: .p2align 2, 0x0
+; CHECK-T1-NEXT: .LJTI1_0:
+; CHECK-T1-NEXT: .long
+; CHECK-T1-NEXT: .long
+; CHECK-T1-NEXT: .long
+; CHECK-T1-NEXT: .long
+; CHECK-T1-NEXT: .long
+; CHECK-T1-NEXT: .long
+
entry:
switch i32 %c, label %return [
i32 1, label %sw.bb
More information about the llvm-commits
mailing list