[PATCH] D20067: Error if inline assembly ends in unexpected mode

Nirav Dave via llvm-commits llvm-commits at lists.llvm.org
Mon May 9 07:19:39 PDT 2016


niravd created this revision.
niravd added a reviewer: dwmw2.
niravd added a subscriber: llvm-commits.

Inline assembly may issue directives that change the
bit-mode (i.e. .code16/.code32/.code64) but these changes do not do not
persist past the inline assembly call as is reasonable. In the case that
inline assembly terminates with a different mode, incorrect assembly may
be generated.

As this situation is likely a mistake and should be dealt with by the
user throw an error message.

http://reviews.llvm.org/D20067

Files:
  lib/Target/X86/X86AsmPrinter.cpp
  lib/Target/X86/X86AsmPrinter.h
  test/CodeGen/X86/inline-asm-mode-directives.ll

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
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) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D20067.56572.patch
Type: text/x-patch
Size: 2963 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160509/f9bbe9e4/attachment.bin>


More information about the llvm-commits mailing list