Skip to content

Commit 2e47b93

Browse files
[ARM] Honour -mno-movt in stack protector handling (#109022)
When -mno-movt is passed to Clang, the ARM codegen correctly avoids movt/movw pairs to take the address of __stack_chk_guard in the stack protector code emitted into the function pro- and epilogues. However, the Thumb2 codegen fails to do so, and happily emits movw/movt pairs unless it is generating an ELF binary and the symbol might be in a different DSO. Let's incorporate a check for useMovt() in the logic here, so movt/movw are never emitted when -mno-movt is specified. Suggestions welcome for how/where to add a test case for this. Signed-off-by: Ard Biesheuvel <[email protected]>
1 parent 18952bd commit 2e47b93

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

llvm/lib/Target/ARM/Thumb2InstrInfo.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,11 @@ void Thumb2InstrInfo::expandLoadStackGuard(
264264
}
265265

266266
const auto *GV = cast<GlobalValue>((*MI->memoperands_begin())->getValue());
267-
if (MF.getSubtarget<ARMSubtarget>().isTargetELF() && !GV->isDSOLocal())
267+
const ARMSubtarget &Subtarget = MF.getSubtarget<ARMSubtarget>();
268+
if (Subtarget.isTargetELF() && !GV->isDSOLocal())
268269
expandLoadStackGuardBase(MI, ARM::t2LDRLIT_ga_pcrel, ARM::t2LDRi12);
270+
else if (!Subtarget.useMovt())
271+
expandLoadStackGuardBase(MI, ARM::tLDRLIT_ga_abs, ARM::t2LDRi12);
269272
else if (MF.getTarget().isPositionIndependent())
270273
expandLoadStackGuardBase(MI, ARM::t2MOV_ga_pcrel, ARM::t2LDRi12);
271274
else
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
; RUN: llc -relocation-model=static -mattr=+no-movt < %s | FileCheck %s
2+
3+
target triple = "thumbv7a-linux-gnueabi"
4+
5+
define i32 @test1() #0 {
6+
; CHECK-LABEL: test1:
7+
; CHECK: @ %bb.0:
8+
; CHECK-NEXT: push {r7, lr}
9+
; CHECK-NEXT: sub.w sp, sp, #1032
10+
; CHECK-NEXT: ldr r0, .LCPI0_0
11+
; CHECK-NEXT: ldr r0, [r0]
12+
; CHECK-NEXT: str.w r0, [sp, #1028]
13+
; CHECK-NEXT: add r0, sp, #4
14+
; CHECK-NEXT: bl foo
15+
; CHECK-NEXT: ldr.w r0, [sp, #1028]
16+
; CHECK-NEXT: ldr r1, .LCPI0_0
17+
; CHECK-NEXT: ldr r1, [r1]
18+
; CHECK-NEXT: cmp r1, r0
19+
; CHECK-NEXT: ittt eq
20+
; CHECK-NEXT: moveq r0, #0
21+
; CHECK-NEXT: addeq.w sp, sp, #1032
22+
; CHECK-NEXT: popeq {r7, pc}
23+
; CHECK-NEXT: .LBB0_1:
24+
; CHECK-NEXT: bl __stack_chk_fail
25+
%a1 = alloca [256 x i32], align 4
26+
call void @foo(ptr %a1) #3
27+
ret i32 0
28+
}
29+
30+
declare void @foo(ptr)
31+
32+
attributes #0 = { nounwind sspstrong }

0 commit comments

Comments
 (0)