Skip to content

Commit

Permalink
[ARM] Generate out-of-line jump tables for XO without 32-bit branch
Browse files Browse the repository at this point in the history
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
  • Loading branch information
john-brawn-arm committed Jun 28, 2023
1 parent 6afdf40 commit 4fb0e01
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 2 deletions.
15 changes: 13 additions & 2 deletions llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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.

Expand Down
21 changes: 21 additions & 0 deletions llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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)
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/ARM/ARMISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
21 changes: 21 additions & 0 deletions llvm/test/CodeGen/ARM/execute-only.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 4fb0e01

Please sign in to comment.