[llvm] r311992 - [ARM] GlobalISel: Select globals in PIC mode

Diana Picus via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 29 02:47:56 PDT 2017


Author: rovka
Date: Tue Aug 29 02:47:55 2017
New Revision: 311992

URL: http://llvm.org/viewvc/llvm-project?rev=311992&view=rev
Log:
[ARM] GlobalISel: Select globals in PIC mode

Support the selection of G_GLOBAL_VALUE in the PIC relocation model. For
simplicity we use the same pseudoinstructions for both Darwin and ELF:
(MOV|LDRLIT)_ga_pcrel(_ldr).

This is new for ELF, so it requires a small update to the ARM pseudo
expansion pass to make sure it adds the correct constant pool modifier
and add-current-address in the case of ELF.

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

Added:
    llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-isel-globals-pic.ll
    llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-select-globals-pic.mir
Modified:
    llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp
    llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp
    llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp
    llvm/trunk/lib/Target/ARM/ARMSubtarget.h
    llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-unsupported.ll

Modified: llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp?rev=311992&r1=311991&r2=311992&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp Tue Aug 29 02:47:55 2017
@@ -1308,9 +1308,11 @@ bool ARMExpandPseudo::ExpandMI(MachineBa
 
       if (IsPIC) {
         unsigned PCAdj = IsARM ? 8 : 4;
+        auto Modifier = STI->getCPModifier(GV);
         ARMPCLabelIndex = AFI->createPICLabelUId();
-        CPV = ARMConstantPoolConstant::Create(GV, ARMPCLabelIndex,
-                                              ARMCP::CPValue, PCAdj);
+        CPV = ARMConstantPoolConstant::Create(
+            GV, ARMPCLabelIndex, ARMCP::CPValue, PCAdj, Modifier,
+            /*AddCurrentAddr*/ Modifier == ARMCP::GOT_PREL);
       } else
         CPV = ARMConstantPoolConstant::Create(GV, ARMCP::no_modifier);
 

Modified: llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp?rev=311992&r1=311991&r2=311992&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp Tue Aug 29 02:47:55 2017
@@ -492,10 +492,6 @@ bool ARMInstructionSelector::selectGloba
     DEBUG(dbgs() << "ROPI and RWPI not supported yet\n");
     return false;
   }
-  if (TM.isPositionIndependent()) {
-    DEBUG(dbgs() << "PIC not supported yet\n");
-    return false;
-  }
 
   auto GV = MIB->getOperand(1).getGlobal();
   if (GV->isThreadLocal()) {
@@ -509,6 +505,28 @@ bool ARMInstructionSelector::selectGloba
   auto ObjectFormat = TII.getSubtarget().getTargetTriple().getObjectFormat();
   bool UseMovt = TII.getSubtarget().useMovt(MF);
 
+  unsigned Alignment = 4;
+  if (TM.isPositionIndependent()) {
+    bool Indirect = TII.getSubtarget().isGVIndirectSymbol(GV);
+    // FIXME: Taking advantage of MOVT for ELF is pretty involved, so we don't
+    // support it yet. See PR28229.
+    unsigned Opc =
+        UseMovt && !TII.getSubtarget().isTargetELF()
+            ? (Indirect ? ARM::MOV_ga_pcrel_ldr : ARM::MOV_ga_pcrel)
+            : (Indirect ? ARM::LDRLIT_ga_pcrel_ldr : ARM::LDRLIT_ga_pcrel);
+    MIB->setDesc(TII.get(Opc));
+
+    if (TII.getSubtarget().isTargetDarwin())
+      MIB->getOperand(1).setTargetFlags(ARMII::MO_NONLAZY);
+
+    if (Indirect)
+      MIB.addMemOperand(MF.getMachineMemOperand(
+          MachinePointerInfo::getGOT(MF), MachineMemOperand::MOLoad,
+          TM.getPointerSize(), Alignment));
+
+    return true;
+  }
+
   if (ObjectFormat == Triple::ELF) {
     if (UseMovt) {
       MIB->setDesc(TII.get(ARM::MOVi32imm));
@@ -516,7 +534,6 @@ bool ARMInstructionSelector::selectGloba
       // Load the global's address from the constant pool.
       MIB->setDesc(TII.get(ARM::LDRi12));
       MIB->RemoveOperand(1);
-      unsigned Alignment = 4;
       MIB.addConstantPoolIndex(
              MF.getConstantPool()->getConstantPoolIndex(GV, Alignment),
              /* Offset */ 0, /* TargetFlags */ 0)

Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp?rev=311992&r1=311991&r2=311992&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp Tue Aug 29 02:47:55 2017
@@ -342,6 +342,13 @@ bool ARMSubtarget::isGVIndirectSymbol(co
   return false;
 }
 
+ARMCP::ARMCPModifier ARMSubtarget::getCPModifier(const GlobalValue *GV) const {
+  if (isTargetELF() && TM.isPositionIndependent() &&
+      !TM.shouldAssumeDSOLocal(*GV->getParent(), GV))
+    return ARMCP::GOT_PREL;
+  return ARMCP::no_modifier;
+}
+
 unsigned ARMSubtarget::getMispredictionPenalty() const {
   return SchedModel.MispredictPenalty;
 }

Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=311992&r1=311991&r2=311992&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMSubtarget.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMSubtarget.h Tue Aug 29 02:47:55 2017
@@ -16,6 +16,7 @@
 
 #include "ARMBaseInstrInfo.h"
 #include "ARMBaseRegisterInfo.h"
+#include "ARMConstantPoolValue.h"
 #include "ARMFrameLowering.h"
 #include "ARMISelLowering.h"
 #include "ARMSelectionDAGInfo.h"
@@ -750,6 +751,9 @@ public:
   /// True if the GV will be accessed via an indirect symbol.
   bool isGVIndirectSymbol(const GlobalValue *GV) const;
 
+  /// Returns the constant pool modifier needed to access the GV.
+  ARMCP::ARMCPModifier getCPModifier(const GlobalValue *GV) const;
+
   /// True if fast-isel is used.
   bool useFastISel() const;
 

Added: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-isel-globals-pic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-isel-globals-pic.ll?rev=311992&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-isel-globals-pic.ll (added)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-isel-globals-pic.ll Tue Aug 29 02:47:55 2017
@@ -0,0 +1,58 @@
+; RUN: llc -mtriple armv7-linux -relocation-model=pic -global-isel %s -o - | FileCheck %s -check-prefixes=CHECK,ELF
+; RUN: llc -mtriple armv7-linux -relocation-model=pic -mattr=+no-movt -global-isel %s -o - | FileCheck %s -check-prefixes=CHECK,ELF
+; RUN: llc -mtriple armv7-darwin -relocation-model=pic -global-isel %s -o - | FileCheck %s -check-prefixes=CHECK,DARWIN,DARWIN-MOVT
+; RUN: llc -mtriple armv7-darwin -relocation-model=pic -mattr=+no-movt -global-isel %s -o - | FileCheck %s -check-prefixes=CHECK,DARWIN,DARWIN-NOMOVT
+
+ at internal_global = internal global i32 42
+define i32 @test_internal_global() {
+; CHECK-LABEL: test_internal_global:
+; ELF: ldr [[OFFSET:r[0-9]+]], [[LABEL:.L[[:alnum:]_]+]]
+; ELF: [[ANCHOR:.L[[:alnum:]_]+]]:
+; DARWIN-NOMOVT: ldr [[OFFSET:r[0-9]+]], [[LABEL:L[[:alnum:]_]+]]
+; DARWIN-MOVT: movw [[OFFSET:r[0-9]+]], :lower16:(_internal_global-([[ANCHOR:L[[:alnum:]_]+]]+8))
+; DARWIN-MOVT-NEXT: movt [[OFFSET]], :upper16:(_internal_global-([[ANCHOR]]+8))
+; DARWIN: [[ANCHOR:L[[:alnum:]_]+]]:
+; CHECK-NEXT: add r[[ADDR:[0-9]+]], pc, [[OFFSET]]
+; CHECK-NEXT: ldr r0, [r[[ADDR]]]
+; CHECK-NEXT: bx lr
+; ELF: [[LABEL]]:
+; ELF-NEXT: .long internal_global-([[ANCHOR]]+8)
+; DARWIN-NOMOVT: [[LABEL]]:
+; DARWIN-NOMOVT-NEXT: .long _internal_global-([[ANCHOR]]+8)
+; DARWIN-MOVT-NOT: .long _internal_global
+
+entry:
+  %v = load i32, i32* @internal_global
+  ret i32 %v
+}
+
+ at external_global = external global i32
+define i32 @test_external_global() {
+; CHECK-LABEL: test_external_global:
+; ELF: ldr [[OFFSET:r[0-9]+]], [[LABEL:.L[[:alnum:]_]+]]
+; ELF: [[ANCHOR:.L[[:alnum:]_]+]]:
+; ELF-NEXT: ldr r[[ADDR:[0-9]+]], [pc, [[OFFSET]]]
+; DARWIN-NOMOVT: ldr [[OFFSET:r[0-9]+]], [[LABEL:L[[:alnum:]_]+]]
+; DARWIN-MOVT: movw [[OFFSET:r[0-9]+]], :lower16:(L_external_global$non_lazy_ptr-([[ANCHOR:L[[:alnum:]_]+]]+8))
+; DARWIN-MOVT: movt [[OFFSET]], :upper16:(L_external_global$non_lazy_ptr-([[ANCHOR]]+8))
+; DARWIN: [[ANCHOR:L[[:alnum:]_]+]]:
+; DARWIN: ldr r[[ADDR:[0-9]+]], [pc, [[OFFSET]]]
+; CHECK-NEXT: ldr r0, [r[[ADDR]]]
+; CHECK-NEXT: bx lr
+; ELF: [[LABEL]]:
+; ELF: [[TMPLABEL:.L[[:alnum:]_]+]]:
+; ELF: .long external_global(GOT_PREL)-(([[ANCHOR]]+8)-[[TMPLABEL]])
+; DARWIN-NOMOVT: [[LABEL]]:
+; DARWIN-NOMOVT: .long L_external_global$non_lazy_ptr-([[ANCHOR]]+8)
+; DARWIN-NOMOVT-NOT: .long L_external_global
+entry:
+  %v = load i32, i32* @external_global
+  ret i32 %v
+}
+
+; ELF: internal_global:
+; DARWIN: _internal_global:
+; CHECK: .long 42
+; ELF: .size internal_global, 4
+; DARWIN: L_external_global$non_lazy_ptr:
+; DARWIN: .indirect_symbol _external_global

Added: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-select-globals-pic.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-select-globals-pic.mir?rev=311992&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-select-globals-pic.mir (added)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-select-globals-pic.mir Tue Aug 29 02:47:55 2017
@@ -0,0 +1,63 @@
+# RUN: llc -O0 -mtriple arm-linux -relocation-model=pic -mattr=+no-movt -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=CHECK,ELF
+# RUN: llc -O0 -mtriple arm-linux -relocation-model=pic -mattr=-no-movt,+v8m -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=CHECK,ELF
+# RUN: llc -O0 -mtriple arm-darwin -relocation-model=pic -mattr=+no-movt -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=CHECK,DARWIN-NOMOVT
+# RUN: llc -O0 -mtriple arm-darwin -relocation-model=pic -mattr=-no-movt,+v8m -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=CHECK,DARWIN-MOVT
+--- |
+  @internal_global = internal global i32 42
+  define void @test_internal_global() { ret void }
+
+  @external_global = external global i32
+  define void @test_external_global() { ret void }
+...
+---
+name:            test_internal_global
+# CHECK-LABEL: name: test_internal_global
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: gprb }
+body:             |
+  bb.0:
+    %0(p0) = G_GLOBAL_VALUE @internal_global
+    ; DARWIN-MOVT: [[G:%[0-9]+]] = MOV_ga_pcrel {{.*}}@internal_global
+    ; DARWIN-NOMOVT: [[G:%[0-9]+]] = LDRLIT_ga_pcrel {{.*}}@internal_global
+    ; ELF: [[G:%[0-9]+]] = LDRLIT_ga_pcrel {{.*}}@internal_global
+
+    %1(s32) = G_LOAD %0(p0) :: (load 4 from @internal_global)
+    ; CHECK: [[V:%[0-9]+]] = LDRi12 [[G]], 0, 14, _ :: (load 4 from @internal_global)
+
+    %r0 = COPY %1(s32)
+    ; CHECK: %r0 = COPY [[V]]
+
+    BX_RET 14, _, implicit %r0
+    ; CHECK: BX_RET 14, _, implicit %r0
+...
+---
+name:            test_external_global
+# CHECK-LABEL: name: test_external_global
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: gprb }
+body:             |
+  bb.0:
+    %0(p0) = G_GLOBAL_VALUE @external_global
+    ; DARWIN-MOVT: [[G:%[0-9]+]] = MOV_ga_pcrel_ldr {{.*}} @external_global :: (load 4 from got)
+    ; DARWIN-NOMOVT: [[G:%[0-9]+]] = LDRLIT_ga_pcrel_ldr {{.*}}@external_global :: (load 4 from got)
+    ; ELF: [[G:%[0-9]+]] = LDRLIT_ga_pcrel_ldr @external_global :: (load 4 from got)
+
+    %1(s32) = G_LOAD %0(p0) :: (load 4 from @external_global)
+    ; CHECK: [[V:%[0-9]+]] = LDRi12 [[G]], 0, 14, _ :: (load 4 from @external_global)
+
+    %r0 = COPY %1(s32)
+    ; CHECK: %r0 = COPY [[V]]
+
+    BX_RET 14, _, implicit %r0
+    ; CHECK: BX_RET 14, _, implicit %r0
+...

Modified: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-unsupported.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-unsupported.ll?rev=311992&r1=311991&r2=311992&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-unsupported.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-unsupported.ll Tue Aug 29 02:47:55 2017
@@ -117,8 +117,6 @@ define i32 @test_thread_local_global() {
 
 define i32 @test_global_reloc_models() {
 ; This is only unsupported for the PIC, ROPI, RWPI relocation modes.
-; PIC: remark: {{.*}} cannot select: {{.*}} G_GLOBAL_VALUE
-; PIC-LABEL: warning: Instruction selection used fallback path for test_global_reloc_models
 ; ROPI: remark: {{.*}} cannot select: {{.*}} G_GLOBAL_VALUE
 ; ROPI-LABEL: warning: Instruction selection used fallback path for test_global_reloc_models
 ; RWPI: remark: {{.*}} cannot select: {{.*}} G_GLOBAL_VALUE




More information about the llvm-commits mailing list