Index: lib/Target/X86/X86AsmPrinter.h =================================================================== --- lib/Target/X86/X86AsmPrinter.h +++ lib/Target/X86/X86AsmPrinter.h @@ -101,6 +101,9 @@ void EmitEndOfAsmFile(Module &M) override; + void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, + const MCSubtargetInfo *EndInfo) const override; + void EmitInstruction(const MachineInstr *MI) override; void EmitBasicBlockEnd(const MachineBasicBlock &MBB) override { Index: lib/Target/X86/X86AsmPrinter.cpp =================================================================== --- lib/Target/X86/X86AsmPrinter.cpp +++ lib/Target/X86/X86AsmPrinter.cpp @@ -546,6 +546,30 @@ OutStreamer->EmitAssemblerFlag(MCAF_Code16); } +void X86AsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, + const MCSubtargetInfo *EndInfo) const { + // If inline assembly left code directive in different state, this + // would change the compilation of the subsequent code. As we cannot + // fix this problem in the case of -fno-integrated-as explicitly fail + // with helpful error. + if (EndInfo && StartInfo.getFeatureBits() != EndInfo->getFeatureBits()) { + std::string msg; + raw_string_ostream Msg(msg); + Msg << "Inline Assembly terminated in " + << ((EndInfo->getFeatureBits()[X86::Mode64Bit]) + ? "64" + : (EndInfo->getFeatureBits()[X86::Mode32Bit]) ? "32" : "16") + << "-bit mode, but should be returned to original mode. Consider " + "adding " + << ((StartInfo.getFeatureBits()[X86::Mode64Bit]) + ? ".code64" + : (StartInfo.getFeatureBits()[X86::Mode32Bit]) ? ".code32" + : ".code16") + << " directive"; + MMI->getModule()->getContext().emitError(Msg.str()); + } +} + static void emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel, MachineModuleInfoImpl::StubValueTy &MCSym) { Index: test/CodeGen/X86/inline-asm-mode-directives.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/inline-asm-mode-directives.ll @@ -0,0 +1,19 @@ +; RUN: not llc < %s 2> %t +; RUN: FileCheck %s < %t +target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128" +target triple = "i386-unknown-linux-code16" + +; Function Attrs: nounwind +define i32 @main() #0 { + %retval = alloca i32, align 4 + store i32 0, i32* %retval, align 4 + call void asm sideeffect ".code32\0Apush 1", "~{dirflag},~{fpsr},~{flags}"() #0 + ret i32 0 +} + +; CHECK: error: Inline Assembly terminated in 32-bit mode, but should be returned to original mode. Consider adding .code16 directive +attributes #0 = { nounwind } + +!llvm.ident = !{!0} + +!0 = !{!"clang version 3.9.0 (trunk 265439) (llvm/trunk 265567)"} \ No newline at end of file