[llvm] r268737 - [mips] Fix inconsistent .cprestore behaviour between direct object emission and assembling.

Daniel Sanders via llvm-commits llvm-commits at lists.llvm.org
Fri May 6 07:37:25 PDT 2016


Author: dsanders
Date: Fri May  6 09:37:24 2016
New Revision: 268737

URL: http://llvm.org/viewvc/llvm-project?rev=268737&view=rev
Log:
[mips] Fix inconsistent .cprestore behaviour between direct object emission and assembling.

Summary:
Direct object emission has an initialization order problem where an
InitMCObjectFile is called after MipsTargetELFStreamer determines whether
PIC is enabled by default or not. There doesn't seem to be point that
initializes all cases so split the responsibility between
MipsTargetELFStreamer and MipsAsmPrinter.

Reviewers: sdardis

Subscribers: dsanders, llvm-commits, sdardis

Differential Revision: http://reviews.llvm.org/D19728

Added:
    llvm/trunk/test/MC/Mips/init-order-bug.ll
Modified:
    llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
    llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp
    llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h

Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp?rev=268737&r1=268736&r2=268737&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp Fri May  6 09:37:24 2016
@@ -652,6 +652,14 @@ MipsTargetELFStreamer::MipsTargetELFStre
                                              const MCSubtargetInfo &STI)
     : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) {
   MCAssembler &MCA = getStreamer().getAssembler();
+
+  // It's possible that MCObjectFileInfo isn't fully initialized at this point
+  // due to an initialization order problem where LLVMTargetMachine creates the
+  // target streamer before TargetLoweringObjectFile calls
+  // InitializeMCObjectFileInfo. There doesn't seem to be a single place that
+  // covers all cases so this statement covers most cases and direct object
+  // emission must call setPic() once MCObjectFileInfo has been initialized. The
+  // cases we don't handle here are covered by MipsAsmPrinter.
   Pic = MCA.getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_;
 
   const FeatureBitset &Features = STI.getFeatureBits();

Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp?rev=268737&r1=268736&r2=268737&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Fri May  6 09:37:24 2016
@@ -669,6 +669,12 @@ printRegisterList(const MachineInstr *MI
 }
 
 void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) {
+  MipsTargetStreamer &TS = getTargetStreamer();
+
+  // MipsTargetStreamer has an initialization order problem when emitting an
+  // object file directly (see MipsTargetELFStreamer for full details). Work
+  // around it by re-initializing the PIC state here.
+  TS.setPic(OutContext.getObjectFileInfo()->getRelocM());
 
   // Compute MIPS architecture attributes based on the default subtarget
   // that we'd have constructed. Module level directives aren't LTO
@@ -684,14 +690,14 @@ void MipsAsmPrinter::EmitStartOfAsmFile(
   bool IsABICalls = STI.isABICalls();
   const MipsABIInfo &ABI = MTM.getABI();
   if (IsABICalls) {
-    getTargetStreamer().emitDirectiveAbiCalls();
+    TS.emitDirectiveAbiCalls();
     Reloc::Model RM = TM.getRelocationModel();
     // FIXME: This condition should be a lot more complicated that it is here.
     //        Ideally it should test for properties of the ABI and not the ABI
     //        itself.
     //        For the moment, I'm only correcting enough to make MIPS-IV work.
     if (RM == Reloc::Static && !ABI.IsN64())
-      getTargetStreamer().emitDirectiveOptionPic0();
+      TS.emitDirectiveOptionPic0();
   }
 
   // Tell the assembler which ABI we are using
@@ -702,8 +708,8 @@ void MipsAsmPrinter::EmitStartOfAsmFile(
   // NaN: At the moment we only support:
   // 1. .nan legacy (default)
   // 2. .nan 2008
-  STI.isNaN2008() ? getTargetStreamer().emitDirectiveNaN2008()
-                  : getTargetStreamer().emitDirectiveNaNLegacy();
+  STI.isNaN2008() ? TS.emitDirectiveNaN2008()
+                  : TS.emitDirectiveNaNLegacy();
 
   // TODO: handle O64 ABI
 
@@ -716,19 +722,19 @@ void MipsAsmPrinter::EmitStartOfAsmFile(
                                                           ELF::SHT_PROGBITS, 0));
   }
 
-  getTargetStreamer().updateABIInfo(STI);
+  TS.updateABIInfo(STI);
 
   // We should always emit a '.module fp=...' but binutils 2.24 does not accept
   // it. We therefore emit it when it contradicts the ABI defaults (-mfpxx or
   // -mfp64) and omit it otherwise.
   if (ABI.IsO32() && (STI.isABI_FPXX() || STI.isFP64bit()))
-    getTargetStreamer().emitDirectiveModuleFP();
+    TS.emitDirectiveModuleFP();
 
   // We should always emit a '.module [no]oddspreg' but binutils 2.24 does not
   // accept it. We therefore emit it when it contradicts the default or an
   // option has changed the default (i.e. FPXX) and omit it otherwise.
   if (ABI.IsO32() && (!STI.useOddSPReg() || STI.isABI_FPXX()))
-    getTargetStreamer().emitDirectiveModuleOddSPReg();
+    TS.emitDirectiveModuleOddSPReg();
 }
 
 void MipsAsmPrinter::emitInlineAsmStart() const {

Modified: llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h?rev=268737&r1=268736&r2=268737&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h Fri May  6 09:37:24 2016
@@ -24,6 +24,9 @@ struct MipsABIFlagsSection;
 class MipsTargetStreamer : public MCTargetStreamer {
 public:
   MipsTargetStreamer(MCStreamer &S);
+
+  virtual void setPic(bool Value) {}
+
   virtual void emitDirectiveSetMicroMips();
   virtual void emitDirectiveSetNoMicroMips();
   virtual void emitDirectiveSetMips16();
@@ -260,6 +263,8 @@ public:
   MCELFStreamer &getStreamer();
   MipsTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI);
 
+  void setPic(bool Value) override { Pic = Value; }
+
   void emitLabel(MCSymbol *Symbol) override;
   void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
   void finish() override;

Added: llvm/trunk/test/MC/Mips/init-order-bug.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/init-order-bug.ll?rev=268737&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/init-order-bug.ll (added)
+++ llvm/trunk/test/MC/Mips/init-order-bug.ll Fri May  6 09:37:24 2016
@@ -0,0 +1,12 @@
+; RUN: llc -mtriple=mipsel-linux-gnu -relocation-model=pic -filetype=asm < %s | \
+; RUN:     llvm-mc -triple=mipsel-linux-gnu -relocation-model=pic -filetype=obj | \
+; RUN:     llvm-objdump -d - | FileCheck %s
+; RUN: llc -mtriple=mipsel-linux-gnu -relocation-model=pic -filetype=obj < %s | \
+; RUN:     llvm-objdump -d - | FileCheck %s
+
+define void @foo() {
+  call void asm sideeffect "\09.cprestore 512", "~{$1}"()
+  ret void
+}
+
+; CHECK: sw $gp, 512($sp)




More information about the llvm-commits mailing list