[llvm] 8336d38 - [ARM] Correctly handle combining segmented stacks with execute-only

John Brawn via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 28 02:41:40 PDT 2023


Author: John Brawn
Date: 2023-07-28T10:37:40+01:00
New Revision: 8336d38be92d253582feadb728ac3691a6f3c39c

URL: https://github.com/llvm/llvm-project/commit/8336d38be92d253582feadb728ac3691a6f3c39c
DIFF: https://github.com/llvm/llvm-project/commit/8336d38be92d253582feadb728ac3691a6f3c39c.diff

LOG: [ARM] Correctly handle combining segmented stacks with execute-only

Using segmented stacks with execute-only mostly works, but we need to
use the correct movi32 opcode in 6-M, and there's one place where for
thumb1 (i.e. 6-M and 8-M.base) a constant pool was unconditionally
used which needed to be fixed.

Differential Revision: https://reviews.llvm.org/D156339

Added: 
    llvm/test/CodeGen/ARM/execute-only-segmented-stack.ll

Modified: 
    llvm/lib/Target/ARM/ARMFrameLowering.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
index 4496d4928ebe9e..7bcf95efa8f704 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -2966,6 +2966,7 @@ void ARMFrameLowering::adjustForSegmentedStacks(
   // We save R4 and R5 before use and restore them before leaving the function.
   unsigned ScratchReg0 = ARM::R4;
   unsigned ScratchReg1 = ARM::R5;
+  unsigned MovOp = ST->useMovt() ? ARM::t2MOVi32imm : ARM::tMOVi32imm;
   uint64_t AlignedStackSize;
 
   MachineBasicBlock *PrevStackMBB = MF.CreateMachineBasicBlock();
@@ -3083,8 +3084,8 @@ void ARMFrameLowering::adjustForSegmentedStacks(
           .addImm(AlignedStackSize)
           .add(predOps(ARMCC::AL));
     } else {
-      if (Thumb2) {
-        BuildMI(McrMBB, DL, TII.get(ARM::t2MOVi32imm), ScratchReg0)
+      if (Thumb2 || ST->genExecuteOnly()) {
+        BuildMI(McrMBB, DL, TII.get(MovOp), ScratchReg0)
             .addImm(AlignedStackSize);
       } else {
         auto MBBI = McrMBB->end();
@@ -3119,16 +3120,21 @@ void ARMFrameLowering::adjustForSegmentedStacks(
   }
 
   if (Thumb && ST->isThumb1Only()) {
-    unsigned PCLabelId = ARMFI->createPICLabelUId();
-    ARMConstantPoolValue *NewCPV = ARMConstantPoolSymbol::Create(
-        MF.getFunction().getContext(), "__STACK_LIMIT", PCLabelId, 0);
-    MachineConstantPool *MCP = MF.getConstantPool();
-    unsigned CPI = MCP->getConstantPoolIndex(NewCPV, Align(4));
-
-    // ldr SR0, [pc, offset(STACK_LIMIT)]
-    BuildMI(GetMBB, DL, TII.get(ARM::tLDRpci), ScratchReg0)
-        .addConstantPoolIndex(CPI)
-        .add(predOps(ARMCC::AL));
+    if (ST->genExecuteOnly()) {
+      BuildMI(GetMBB, DL, TII.get(MovOp), ScratchReg0)
+          .addExternalSymbol("__STACK_LIMIT");
+    } else {
+      unsigned PCLabelId = ARMFI->createPICLabelUId();
+      ARMConstantPoolValue *NewCPV = ARMConstantPoolSymbol::Create(
+          MF.getFunction().getContext(), "__STACK_LIMIT", PCLabelId, 0);
+      MachineConstantPool *MCP = MF.getConstantPool();
+      unsigned CPI = MCP->getConstantPoolIndex(NewCPV, Align(4));
+
+      // ldr SR0, [pc, offset(STACK_LIMIT)]
+      BuildMI(GetMBB, DL, TII.get(ARM::tLDRpci), ScratchReg0)
+          .addConstantPoolIndex(CPI)
+          .add(predOps(ARMCC::AL));
+    }
 
     // ldr SR0, [SR0]
     BuildMI(GetMBB, DL, TII.get(ARM::tLDRi), ScratchReg0)
@@ -3188,8 +3194,8 @@ void ARMFrameLowering::adjustForSegmentedStacks(
           .addImm(AlignedStackSize)
           .add(predOps(ARMCC::AL));
     } else {
-      if (Thumb2) {
-        BuildMI(AllocMBB, DL, TII.get(ARM::t2MOVi32imm), ScratchReg0)
+      if (Thumb2 || ST->genExecuteOnly()) {
+        BuildMI(AllocMBB, DL, TII.get(MovOp), ScratchReg0)
             .addImm(AlignedStackSize);
       } else {
         auto MBBI = AllocMBB->end();
@@ -3221,8 +3227,8 @@ void ARMFrameLowering::adjustForSegmentedStacks(
           .addImm(alignToARMConstant(ARMFI->getArgumentStackSize()))
           .add(predOps(ARMCC::AL));
     } else {
-      if (Thumb2) {
-        BuildMI(AllocMBB, DL, TII.get(ARM::t2MOVi32imm), ScratchReg1)
+      if (Thumb2 || ST->genExecuteOnly()) {
+        BuildMI(AllocMBB, DL, TII.get(MovOp), ScratchReg1)
             .addImm(alignToARMConstant(ARMFI->getArgumentStackSize()));
       } else {
         auto MBBI = AllocMBB->end();

diff  --git a/llvm/test/CodeGen/ARM/execute-only-segmented-stack.ll b/llvm/test/CodeGen/ARM/execute-only-segmented-stack.ll
new file mode 100644
index 00000000000000..5541a7cc20667b
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/execute-only-segmented-stack.ll
@@ -0,0 +1,47 @@
+; RUN: llc -mtriple=thumbv6m-linux-eabi      -mattr=+execute-only %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NOMOVW-SIZE,CHECK-NOMOVW-LIMIT
+; RUN: llc -mtriple=thumbv8m.base-linux-eabi -mattr=+execute-only %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MOVW-SIZE,CHECK-MOVW-LIMIT
+; RUN: llc -mtriple=thumbv7m-linux-eabi      -mattr=+execute-only %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MOVW-SIZE,CHECK-MRC-LIMIT
+; RUN: llc -mtriple=thumbv8m.main-linux-eabi -mattr=+execute-only %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MOVW-SIZE,CHECK-MRC-LIMIT
+
+%struct.large_struct = type { [500 x i8] }
+declare void @fn(ptr)
+
+; CHECK-LABEL:             test:
+; CHECK:                   mov  [[SP:r[0-9]+]], sp
+; CHECK-MOVW-SIZE-NEXT:    movw [[SIZE:r[0-9]+]], #4032
+; CHECK-NOMOVW-SIZE-NEXT:  movs [[SIZE:r[0-9]+]], #15
+; CHECK-NOMOVW-SIZE-NEXT:  lsls [[SIZE]], [[SIZE]], #8
+; CHECK-NOMOVW-SIZE-NEXT:  adds [[SIZE]], #192
+; CHECK-NEXT:              sub{{s?}} [[SP]], [[SP]], [[SIZE]]
+; CHECK-MOVW-LIMIT-NEXT:   movw [[LIMIT:r[0-9]+]], :lower16:__STACK_LIMIT
+; CHECK-MOVW-LIMIT-NEXT:   movt [[LIMIT]], :upper16:__STACK_LIMIT
+; CHECK-NOMOVW-LIMIT-NEXT: movs [[LIMIT:r[0-9]+]], :upper8_15:__STACK_LIMIT
+; CHECK-NOMOVW-LIMIT-NEXT: lsls [[LIMIT]], [[LIMIT]], #8
+; CHECK-NOMOVW-LIMIT-NEXT: adds [[LIMIT]], :upper0_7:__STACK_LIMIT
+; CHECK-NOMOVW-LIMIT-NEXT: lsls [[LIMIT]], [[LIMIT]], #8
+; CHECK-NOMOVW-LIMIT-NEXT: adds [[LIMIT]], :lower8_15:__STACK_LIMIT
+; CHECK-NOMOVW-LIMIT-NEXT: lsls [[LIMIT]], [[LIMIT]], #8
+; CHECK-NOMOVW-LIMIT-NEXT: adds [[LIMIT]], :lower0_7:__STACK_LIMIT
+; CHECK-MRC-LIMIT-NEXT:    p15, #0, [[LIMIT:r[0-9]+]], c13, c0, #3
+; CHECK-NEXT:              ldr [[LIMIT]], [[[LIMIT]]{{.*}}]
+; CHECK-NEXT:              cmp [[LIMIT]], [[SP]]
+; CHECK-NEXT:              bls
+; CHECK-NEXT:              @{{.*}}:
+; CHECK-MOVW-SIZE-NEXT:    movw r4, #4032
+; CHECK-NOMOVW-SIZE-NEXT:  movs r4, #15
+; CHECK-NOMOVW-SIZE-NEXT:  lsls r4, r4, #8
+; CHECK-NOMOVW-SIZE-NEXT:  adds r4, #192
+; CHECK-MOVW-SIZE-NEXT:    movw r5, #484
+; CHECK-NOMOVW-SIZE-NEXT:  movs r5, #1
+; CHECK-NOMOVW-SIZE-NEXT:  lsls r5, r5, #8
+; CHECK-NOMOVW-SIZE-NEXT:  adds r5, #228
+; CHECK-NEXT:              push {lr}
+; CHECK-NEXT:              bl __morestack
+
+define void @test(ptr byval(%struct.large_struct) align 4 %arg) #0 {
+  %ptr = alloca i32, i32 1000
+  call void @fn(ptr %ptr)
+  ret void
+}
+
+attributes #0 = { "split-stack" }


        


More information about the llvm-commits mailing list