Fix for PR1095:
authorBill Wendling <isanbard@gmail.com>
Tue, 16 Jan 2007 03:42:04 +0000 (03:42 +0000)
committerBill Wendling <isanbard@gmail.com>
Tue, 16 Jan 2007 03:42:04 +0000 (03:42 +0000)
LLVM would miscompile ASM dialects when compiling for PPC. Added dialects for
the X86 and PPC backends. It defaults to "0", the first variant of a compound
inline asm expression.

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

include/llvm/Target/TargetAsmInfo.h
lib/CodeGen/AsmPrinter.cpp
lib/Target/PowerPC/PPCTargetAsmInfo.cpp
lib/Target/TargetAsmInfo.cpp
lib/Target/X86/X86TargetAsmInfo.cpp
lib/Target/X86/X86TargetAsmInfo.h
test/CodeGen/PowerPC/2007-01-15-AsmDialect.ll [new file with mode: 0644]

index c922d4c3d9bfbcaf91c1353137208ab864a280ce..6d80a7ebc86e39848a958613237dc3c85fa760eb 100644 (file)
@@ -89,7 +89,10 @@ namespace llvm {
     /// emit before and after an inline assembly statement.
     const char *InlineAsmStart;           // Defaults to "#APP\n"
     const char *InlineAsmEnd;             // Defaults to "#NO_APP\n"
-    
+
+    /// AssemblerDialect - Which dialect of an assembler variant to use.
+    unsigned AssemblerDialect;            // Defaults to 0
+
     //===--- Data Emission Directives -------------------------------------===//
 
     /// ZeroDirective - this should be set to the directive used to get some
@@ -128,7 +131,7 @@ namespace llvm {
     /// Otherwise, it emits ".align log2(N)", e.g. 3 to align to an 8 byte
     /// boundary.
     bool AlignmentIsInBytes;              // Defaults to true
-    
+
     //===--- Section Switching Directives ---------------------------------===//
     
     /// SwitchToSectionDirective - This is the directive used when we want to
@@ -343,6 +346,9 @@ namespace llvm {
     const char *getInlineAsmEnd() const {
       return InlineAsmEnd;
     }
+    unsigned getAssemblerDialect() const {
+      return AssemblerDialect;
+    }
     const char *getZeroDirective() const {
       return ZeroDirective;
     }
index 606c4b8ba52e803dddd8d12c8da45601d74055ef..caa9da0d2ff29ae01c20c8a15cb0785537323b8b 100644 (file)
@@ -698,9 +698,9 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const {
   
   O << TAI->getInlineAsmStart() << "\n\t";
 
-  // The variant of the current asmprinter: FIXME: change.
-  int AsmPrinterVariant = 0;
-  
+  // The variant of the current asmprinter.
+  int AsmPrinterVariant = TAI->getAssemblerDialect();
+
   int CurVariant = -1;            // The number of the {.|.|.} region we are in.
   const char *LastEmitted = AsmStr; // One past the last character emitted.
   
index 6045cfa161d9e1ee958d24482122493bc3c194b5..7912f705738aa2b205d40933d7cc67aa76a14fea 100644 (file)
 #include "llvm/Function.h"
 using namespace llvm;
 
+// ASM variant to use.
+enum {
+  PPC_OLD_MNEMONICS = 0,
+  PPC_NEW_MNEMONICS = 1
+};
+
 PPCTargetAsmInfo::PPCTargetAsmInfo(const PPCTargetMachine &TM) {
   bool isPPC64 = TM.getSubtargetImpl()->isPPC64();
   
@@ -26,6 +32,7 @@ PPCTargetAsmInfo::PPCTargetAsmInfo(const PPCTargetMachine &TM) {
   LCOMMDirective = "\t.lcomm\t";
   InlineAsmStart = "# InlineAsm Start";
   InlineAsmEnd = "# InlineAsm End";
+  AssemblerDialect = PPC_OLD_MNEMONICS;
   
   NeedsSet = true;
   AddressSize = isPPC64 ? 8 : 4;
@@ -56,6 +63,7 @@ DarwinTargetAsmInfo::DarwinTargetAsmInfo(const PPCTargetMachine &TM)
   UsedDirective = "\t.no_dead_strip\t";
   WeakRefDirective = "\t.weak_reference\t";
   HiddenDirective = "\t.private_extern\t";
+  AssemblerDialect = PPC_NEW_MNEMONICS;
 }
 
 LinuxTargetAsmInfo::LinuxTargetAsmInfo(const PPCTargetMachine &TM)
index c2f3e034363847c8d2d7334264cadaa526965477..b1845007440138881ffe225cdd0f249d5ea2626f 100644 (file)
@@ -32,6 +32,7 @@ TargetAsmInfo::TargetAsmInfo() :
   FunctionAddrSuffix(""),
   InlineAsmStart("#APP"),
   InlineAsmEnd("#NO_APP"),
+  AssemblerDialect(0),
   ZeroDirective("\t.zero\t"),
   ZeroDirectiveSuffix(0),
   AsciiDirective("\t.ascii\t"),
index 5f156451818d792c2ae1580a2010f76a52a1ee5c..021976eea762c9374190b507ab1fbf8781d741de 100644 (file)
 #include "llvm/ADT/StringExtras.h"
 using namespace llvm;
 
+// ASM variant to use.
+enum {
+  X86_ATT   = 0,
+  X86_INTEL = 1
+};
+
 static const char* x86_asm_table[] = {"{si}", "S",
                                       "{di}", "D",
                                       "{ax}", "a",
@@ -38,6 +44,7 @@ X86TargetAsmInfo::X86TargetAsmInfo(const X86TargetMachine &TM) {
   // FIXME - Should be simplified.
 
   AsmTransCBE = x86_asm_table;
+  AssemblerDialect = X86_ATT;
   
   switch (Subtarget->TargetType) {
   case X86Subtarget::isDarwin:
index 0f698590ae7122f366ea186f67aca9bab2d9a3f8..cc509d1853734468649f10499d2b5f84a8b932b5 100644 (file)
@@ -17,7 +17,7 @@
 #include "llvm/Target/TargetAsmInfo.h"
 
 namespace llvm {
-  
+
   // Forward declaration.
   class X86TargetMachine;
 
diff --git a/test/CodeGen/PowerPC/2007-01-15-AsmDialect.ll b/test/CodeGen/PowerPC/2007-01-15-AsmDialect.ll
new file mode 100644 (file)
index 0000000..916e168
--- /dev/null
@@ -0,0 +1,26 @@
+; RUN: llvm-as < %s | llc -march=ppc32 | grep cntlzw
+
+define i32 %foo() {
+entry:
+       %retval = alloca i32, align 4           ; <i32*> [#uses=2]
+       %tmp = alloca i32, align 4              ; <i32*> [#uses=2]
+       %ctz_x = alloca i32, align 4            ; <i32*> [#uses=3]
+       %ctz_c = alloca i32, align 4            ; <i32*> [#uses=2]
+       "alloca point" = bitcast i32 0 to i32           ; <i32> [#uses=0]
+       store i32 61440, i32* %ctz_x
+       %tmp = load i32* %ctz_x         ; <i32> [#uses=1]
+       %tmp1 = sub i32 0, %tmp         ; <i32> [#uses=1]
+       %tmp2 = load i32* %ctz_x                ; <i32> [#uses=1]
+       %tmp3 = and i32 %tmp1, %tmp2            ; <i32> [#uses=1]
+       %tmp4 = call i32 asm "$(cntlz$|cntlzw$) $0,$1", "=r,r,~{dirflag},~{fpsr},~{flags}"( i32 %tmp3 )         ; <i32> [#uses=1]
+       store i32 %tmp4, i32* %ctz_c
+       %tmp5 = load i32* %ctz_c                ; <i32> [#uses=1]
+       store i32 %tmp5, i32* %tmp
+       %tmp6 = load i32* %tmp          ; <i32> [#uses=1]
+       store i32 %tmp6, i32* %retval
+       br label %return
+
+return:                ; preds = %entry
+       %retval = load i32* %retval             ; <i32> [#uses=1]
+       ret i32 %retval
+}