Fix for PR1095:
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
diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h
index c922d4c..6d80a7e 100644
--- a/include/llvm/Target/TargetAsmInfo.h
+++ b/include/llvm/Target/TargetAsmInfo.h
@@ -89,7 +89,10 @@
     /// 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 @@
     /// 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 @@
     const char *getInlineAsmEnd() const {
       return InlineAsmEnd;
     }
+    unsigned getAssemblerDialect() const {
+      return AssemblerDialect;
+    }
     const char *getZeroDirective() const {
       return ZeroDirective;
     }
diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp
index 606c4b8..caa9da0 100644
--- a/lib/CodeGen/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter.cpp
@@ -698,9 +698,9 @@
   
   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.
   
diff --git a/lib/Target/PowerPC/PPCTargetAsmInfo.cpp b/lib/Target/PowerPC/PPCTargetAsmInfo.cpp
index 6045cfa..7912f70 100644
--- a/lib/Target/PowerPC/PPCTargetAsmInfo.cpp
+++ b/lib/Target/PowerPC/PPCTargetAsmInfo.cpp
@@ -16,6 +16,12 @@
 #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 @@
   LCOMMDirective = "\t.lcomm\t";
   InlineAsmStart = "# InlineAsm Start";
   InlineAsmEnd = "# InlineAsm End";
+  AssemblerDialect = PPC_OLD_MNEMONICS;
   
   NeedsSet = true;
   AddressSize = isPPC64 ? 8 : 4;
@@ -56,6 +63,7 @@
   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)
diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp
index c2f3e03..b184500 100644
--- a/lib/Target/TargetAsmInfo.cpp
+++ b/lib/Target/TargetAsmInfo.cpp
@@ -32,6 +32,7 @@
   FunctionAddrSuffix(""),
   InlineAsmStart("#APP"),
   InlineAsmEnd("#NO_APP"),
+  AssemblerDialect(0),
   ZeroDirective("\t.zero\t"),
   ZeroDirectiveSuffix(0),
   AsciiDirective("\t.ascii\t"),
diff --git a/lib/Target/X86/X86TargetAsmInfo.cpp b/lib/Target/X86/X86TargetAsmInfo.cpp
index 5f15645..021976e 100644
--- a/lib/Target/X86/X86TargetAsmInfo.cpp
+++ b/lib/Target/X86/X86TargetAsmInfo.cpp
@@ -21,6 +21,12 @@
 #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 @@
   // FIXME - Should be simplified.
 
   AsmTransCBE = x86_asm_table;
+  AssemblerDialect = X86_ATT;
   
   switch (Subtarget->TargetType) {
   case X86Subtarget::isDarwin:
diff --git a/lib/Target/X86/X86TargetAsmInfo.h b/lib/Target/X86/X86TargetAsmInfo.h
index 0f69859..cc509d1 100644
--- a/lib/Target/X86/X86TargetAsmInfo.h
+++ b/lib/Target/X86/X86TargetAsmInfo.h
@@ -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
index 0000000..916e168
--- /dev/null
+++ b/test/CodeGen/PowerPC/2007-01-15-AsmDialect.ll
@@ -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
+}