diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp index 1ffdde0360cf6..4c78379ccf5c4 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -4978,7 +4978,7 @@ void ARMBaseInstrInfo::expandLoadStackGuardBase(MachineBasicBlock::iterator MI, TargetFlags |= ARMII::MO_DLLIMPORT; else if (IsIndirect) TargetFlags |= ARMII::MO_COFFSTUB; - } else if (Subtarget.isGVInGOT(GV)) { + } else if (IsIndirect) { TargetFlags |= ARMII::MO_GOT; } diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.cpp b/llvm/lib/Target/ARM/ARMInstrInfo.cpp index 00db13f2eb520..ccc883f646a62 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMInstrInfo.cpp @@ -104,8 +104,11 @@ void ARMInstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI) const { const GlobalValue *GV = cast((*MI->memoperands_begin())->getValue()); - if (!Subtarget.useMovt() || Subtarget.isGVInGOT(GV)) { - if (TM.isPositionIndependent()) + bool ForceELFGOTPIC = Subtarget.isTargetELF() && !GV->isDSOLocal(); + if (!Subtarget.useMovt() || ForceELFGOTPIC) { + // For ELF non-PIC, use GOT PIC code sequence as well because R_ARM_GOT_ABS + // does not have assembler support. + if (TM.isPositionIndependent() || ForceELFGOTPIC) expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_pcrel, ARM::LDRi12); else expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_abs, ARM::LDRi12); diff --git a/llvm/test/CodeGen/ARM/stack-guard-elf.ll b/llvm/test/CodeGen/ARM/stack-guard-elf.ll index 6c0421d6a3c9e..7a342d003c72d 100644 --- a/llvm/test/CodeGen/ARM/stack-guard-elf.ll +++ b/llvm/test/CodeGen/ARM/stack-guard-elf.ll @@ -1,5 +1,9 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +;; direct-access-external-data is false due to PIC Level, so __stack_chk_guard +;; is dso_preemtable. Check that we use GOT PIC code sequence as well because +;; R_ARM_GOT_ABS does not have assembler support. ; RUN: llc -relocation-model=static < %s | FileCheck %s +; RUN: llc -relocation-model=pic < %s | FileCheck %s target triple = "armv7a-linux-gnueabi" @@ -9,16 +13,18 @@ define i32 @test1() #0 { ; CHECK-NEXT: push {r11, lr} ; CHECK-NEXT: sub sp, sp, #8 ; CHECK-NEXT: sub sp, sp, #1024 -; CHECK-NEXT: movw r0, :lower16:__stack_chk_guard -; CHECK-NEXT: movt r0, :upper16:__stack_chk_guard +; CHECK-NEXT: ldr r0, .LCPI0_0 +; CHECK-NEXT: .LPC0_0: +; CHECK-NEXT: add r0, pc, r0 ; CHECK-NEXT: ldr r0, [r0] ; CHECK-NEXT: ldr r0, [r0] ; CHECK-NEXT: str r0, [sp, #1028] ; CHECK-NEXT: add r0, sp, #4 ; CHECK-NEXT: bl foo -; CHECK-NEXT: movw r1, :lower16:__stack_chk_guard ; CHECK-NEXT: ldr r0, [sp, #1028] -; CHECK-NEXT: movt r1, :upper16:__stack_chk_guard +; CHECK-NEXT: ldr r1, .LCPI0_1 +; CHECK-NEXT: .LPC0_1: +; CHECK-NEXT: add r1, pc, r1 ; CHECK-NEXT: ldr r1, [r1] ; CHECK-NEXT: ldr r1, [r1] ; CHECK-NEXT: cmp r1, r0 @@ -28,6 +34,14 @@ define i32 @test1() #0 { ; CHECK-NEXT: popeq {r11, pc} ; CHECK-NEXT: .LBB0_1: ; CHECK-NEXT: bl __stack_chk_fail +; CHECK-NEXT: .p2align 2 +; CHECK-NEXT: @ %bb.2: +; CHECK-NEXT: .LCPI0_0: +; CHECK-NEXT: .Ltmp0: +; CHECK-NEXT: .long __stack_chk_guard(GOT_PREL)-((.LPC0_0+8)-.Ltmp0) +; CHECK-NEXT: .LCPI0_1: +; CHECK-NEXT: .Ltmp1: +; CHECK-NEXT: .long __stack_chk_guard(GOT_PREL)-((.LPC0_1+8)-.Ltmp1) %a1 = alloca [256 x i32], align 4 call void @foo(ptr %a1) #3 ret i32 0