[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