From: Daniel Sanders Date: Fri, 6 May 2016 14:37:24 +0000 (+0000) Subject: [mips] Fix inconsistent .cprestore behaviour between direct object emission and assem... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=98bdc0b79f936eb86cf129972f9efe987a583bdf;p=llvm [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268737 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 58c1f0ee4ee..23c46351b82 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -652,6 +652,14 @@ MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S, 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(); diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index cd35b0caee5..24afb8863a6 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -669,6 +669,12 @@ printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O) { } 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(Module &M) { 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(Module &M) { // 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(Module &M) { 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 { diff --git a/lib/Target/Mips/MipsTargetStreamer.h b/lib/Target/Mips/MipsTargetStreamer.h index a60943b8a41..2b39da6ade5 100644 --- a/lib/Target/Mips/MipsTargetStreamer.h +++ b/lib/Target/Mips/MipsTargetStreamer.h @@ -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; diff --git a/test/MC/Mips/init-order-bug.ll b/test/MC/Mips/init-order-bug.ll new file mode 100644 index 00000000000..9682dce97e9 --- /dev/null +++ b/test/MC/Mips/init-order-bug.ll @@ -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)