[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