]> granicus.if.org Git - llvm/commitdiff
[mips] Handle variables with an explicit section and interactions with .sdata, .sbss
authorSimon Dardis <simon.dardis@imgtec.com>
Wed, 16 Aug 2017 12:18:04 +0000 (12:18 +0000)
committerSimon Dardis <simon.dardis@imgtec.com>
Wed, 16 Aug 2017 12:18:04 +0000 (12:18 +0000)
If a variable has an explicit section such as .sdata or .sbss, it is placed
in that section and accessed in a gp relative manner. This overrides the global
-G setting.

Otherwise if a variable has a explicit section attached to it, such as '.rodata'
or '.mysection', it is not placed in the small data section. This also overrides
the global -G setting.

Reviewers: atanasyan, nitesh.jain

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311001 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MipsTargetObjectFile.cpp
test/CodeGen/Mips/gpopt-explict-section.ll [new file with mode: 0644]

index 3bf32e81d57cd5680cfe48ddae67210b5170d278..9db6b7b1bcd6adb3cece95a953270027a44abe97 100644 (file)
@@ -106,6 +106,22 @@ IsGlobalInSmallSectionImpl(const GlobalObject *GO,
   if (!GVA)
     return false;
 
+  // If the variable has an explicit section, it is placed in that section but
+  // it's addressing mode may change.
+  if (GVA->hasSection()) {
+    StringRef Section = GVA->getSection();
+
+    // Explicitly placing any variable in the small data section overrides
+    // the global -G value.
+    if (Section == ".sdata" || Section == ".sbss")
+      return true;
+
+    // Otherwise reject accessing it through the gp pointer. There are some
+    // historic cases which GCC doesn't appear to respect any more. These
+    // are .lit4, .lit8 and .srdata. For the moment reject these as well.
+    return false;
+  }
+
   // Enforce -mlocal-sdata.
   if (!LocalSData && GVA->hasLocalLinkage())
     return false;
diff --git a/test/CodeGen/Mips/gpopt-explict-section.ll b/test/CodeGen/Mips/gpopt-explict-section.ll
new file mode 100644 (file)
index 0000000..f1518ba
--- /dev/null
@@ -0,0 +1,53 @@
+; RUN: llc < %s -march=mips -mcpu=mips32 -mips-ssection-threshold=8 \
+; RUN:     -relocation-model=static -mattr=+noabicalls -mgpopt \
+; RUN:   | FileCheck %s
+
+; Test that object with an explicit section that is not .sdata or .sbss are not
+; considered in the small data section if they would otherwise qualify to be in
+; small data section. Also test that explicitly placing something in the small
+; data section uses %gp_rel addressing mode.
+
+@a = global [2 x i32] zeroinitializer, section ".rodata", align 4
+@b = global [4 x i32] zeroinitializer, section ".sdata", align 4
+@c = global [4 x i32] zeroinitializer, section ".sbss", align 4
+
+; CHECK-LABEL: g
+; CHECK:       lui $[[R:[0-9]+]], %hi(a)
+; CHECK:       lw  ${{[0-9]+}}, %lo(a)($[[R]])
+
+define i32 @g() {
+entry:
+  %0 = load i32, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @a, i32 0, i32 0), align 4
+  ret i32 %0
+}
+
+; CHECK-LABEL: f:
+; CHECK-LABEL: lw ${{[0-9]+}}, %gp_rel(b)($gp)
+
+define i32 @f() {
+entry:
+  %0 = load i32, i32* getelementptr inbounds ([4 x i32], [4 x i32]* @b, i32 0, i32 0), align 4
+  ret i32 %0
+}
+
+; CHECK-LABEL: h:
+; CHECK-LABEL: lw ${{[0-9]+}}, %gp_rel(c)($gp)
+
+define i32 @h() {
+entry:
+  %0 = load i32, i32* getelementptr inbounds ([4 x i32], [4 x i32]* @c, i32 0, i32 0), align 4
+  ret i32 %0
+}
+
+
+; CHECK:  .type a,@object
+; CHECK:  .section  .rodata,"a",@progbits
+; CHECK:  .globl  a
+
+; CHECK:  .type b,@object
+; CHECK:  .section  .sdata,"aw",@progbits
+; CHECK:  .globl  b
+
+; CHECK:  .type c,@object
+; CHECK:  .section  .sbss,"aw",@nobits
+; CHECK:  .globl  c