[prev in list] [next in list] [prev in thread] [next in thread] 

List:       mono-patches
Subject:    [Mono-patches] [mono/llvm] [153 commits] f830231a: Keep track of
From:       "Devang Patel (dpatel () apple ! com)" <mono-patches () lists ! ximian ! com>
Date:       2011-03-31 15:48:26
Message-ID: 20110331154826.982422212B () mono ! ximian ! com
[Download RAW message or body]


   Branch: refs/heads/mono
     Home: https://github.com/mono/llvm

   Commit: f830231a336bafe3c39a18ba5857f1f6ea19f12d
   Author: Devang Patel <dpatel@apple.com>
     Date: 03/24/2011 16:30:50
      URL: https://github.com/mono/llvm/commit/f830231a336bafe3c39a18ba5857f1f6ea19f12d


Keep track of directory namd and fIx regression caused by Rafael's patch r119613.

A better approach would be to move source id handling inside MC.


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

Changed paths:
 M lib/CodeGen/AsmPrinter/DwarfDebug.cpp
 M lib/CodeGen/AsmPrinter/DwarfDebug.h
 M test/CodeGen/X86/unknown-location.ll
Added paths:
 A test/DebugInfo/dbg-file-name.ll

Modified: lib/CodeGen/AsmPrinter/DwarfDebug.cpp
===================================================================
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -516,7 +516,8 @@ void DwarfDebug::addSourceLine(DIE *Die, DIVariable V) {
   unsigned Line = V.getLineNumber();
   if (Line == 0)
     return;
-  unsigned FileID = GetOrCreateSourceID(V.getContext().getFilename());
+  unsigned FileID = GetOrCreateSourceID(V.getContext().getFilename(),
+                                        V.getContext().getDirectory());
   assert(FileID && "Invalid file id");
   addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
   addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@@ -532,7 +533,8 @@ void DwarfDebug::addSourceLine(DIE *Die, DIGlobalVariable G) {
   unsigned Line = G.getLineNumber();
   if (Line == 0)
     return;
-  unsigned FileID = GetOrCreateSourceID(G.getContext().getFilename());
+  unsigned FileID = GetOrCreateSourceID(G.getContext().getFilename(),
+                                        G.getContext().getDirectory());
   assert(FileID && "Invalid file id");
   addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
   addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@@ -551,7 +553,7 @@ void DwarfDebug::addSourceLine(DIE *Die, DISubprogram SP) {
   unsigned Line = SP.getLineNumber();
   if (!SP.getContext().Verify())
     return;
-  unsigned FileID = GetOrCreateSourceID(SP.getFilename());
+  unsigned FileID = GetOrCreateSourceID(SP.getFilename(), SP.getDirectory());
   assert(FileID && "Invalid file id");
   addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
   addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@@ -567,7 +569,7 @@ void DwarfDebug::addSourceLine(DIE *Die, DIType Ty) {
   unsigned Line = Ty.getLineNumber();
   if (Line == 0 || !Ty.getContext().Verify())
     return;
-  unsigned FileID = GetOrCreateSourceID(Ty.getFilename());
+  unsigned FileID = GetOrCreateSourceID(Ty.getFilename(), Ty.getDirectory());
   assert(FileID && "Invalid file id");
   addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
   addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@@ -585,7 +587,7 @@ void DwarfDebug::addSourceLine(DIE *Die, DINameSpace NS) {
     return;
   StringRef FN = NS.getFilename();
 
-  unsigned FileID = GetOrCreateSourceID(FN);
+  unsigned FileID = GetOrCreateSourceID(FN, NS.getDirectory());
   assert(FileID && "Invalid file id");
   addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
   addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@@ -1859,10 +1861,21 @@ DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {
 /// in the SourceIds map. This can update DirectoryNames and SourceFileNames
 /// maps as well.
 
-unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName){
+unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName, 
+                                         StringRef DirName) {
   // If FE did not provide a file name, then assume stdin.
   if (FileName.empty())
-    return GetOrCreateSourceID("<stdin>");
+    return GetOrCreateSourceID("<stdin>", StringRef());
+
+  // MCStream expects full path name as filename.
+  if (!DirName.empty() && !FileName.startswith("/")) {
+    std::string FullPathName(DirName.data());
+    if (!DirName.endswith("/"))
+      FullPathName += "/";
+    FullPathName += FileName.data();
+    // Here FullPathName will be copied into StringMap by GetOrCreateSourceID.
+    return GetOrCreateSourceID(StringRef(FullPathName), StringRef());
+  }
 
   StringMapEntry<unsigned> &Entry = SourceIdMap.GetOrCreateValue(FileName);
   if (Entry.getValue())
@@ -1872,7 +1885,7 @@ unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName){
   Entry.setValue(SrcId);
 
   // Print out a .file directive to specify files for .loc directives.
-  Asm->OutStreamer.EmitDwarfFileDirective(SrcId, FileName);
+  Asm->OutStreamer.EmitDwarfFileDirective(SrcId, Entry.getKey());
 
   return SrcId;
 }
@@ -1898,7 +1911,7 @@ void DwarfDebug::constructCompileUnit(const MDNode *N) {
   DICompileUnit DIUnit(N);
   StringRef FN = DIUnit.getFilename();
   StringRef Dir = DIUnit.getDirectory();
-  unsigned ID = GetOrCreateSourceID(FN);
+  unsigned ID = GetOrCreateSourceID(FN, Dir);
 
   DIE *Die = new DIE(dwarf::DW_TAG_compile_unit);
   addString(Die, dwarf::DW_AT_producer, dwarf::DW_FORM_string,
@@ -3102,7 +3115,7 @@ DbgScope *DwarfDebug::findDbgScope(const MachineInstr *MInsn) {
 MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col,
                                        const MDNode *S) {
   StringRef Fn;
-
+  StringRef Dir;
   unsigned Src = 1;
   if (S) {
     DIDescriptor Scope(S);
@@ -3110,19 +3123,23 @@ MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, \
unsigned Col,  if (Scope.isCompileUnit()) {
       DICompileUnit CU(S);
       Fn = CU.getFilename();
+      Dir = CU.getDirectory();
     } else if (Scope.isFile()) {
       DIFile F(S);
       Fn = F.getFilename();
+      Dir = F.getDirectory();
     } else if (Scope.isSubprogram()) {
       DISubprogram SP(S);
       Fn = SP.getFilename();
+      Dir = SP.getDirectory();
     } else if (Scope.isLexicalBlock()) {
       DILexicalBlock DB(S);
       Fn = DB.getFilename();
+      Dir = DB.getDirectory();
     } else
       assert(0 && "Unexpected scope info");
 
-    Src = GetOrCreateSourceID(Fn);
+    Src = GetOrCreateSourceID(Fn, Dir);
   }
 
   Asm->OutStreamer.EmitDwarfLocDirective(Src, Line, Col, DWARF2_FLAG_IS_STMT,
Modified: lib/CodeGen/AsmPrinter/DwarfDebug.h
===================================================================
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -518,7 +518,7 @@ private:
   /// GetOrCreateSourceID - Look up the source id with the given directory and
   /// source file names. If none currently exists, create a new id and insert it
   /// in the SourceIds map.
-  unsigned GetOrCreateSourceID(StringRef FullName);
+  unsigned GetOrCreateSourceID(StringRef DirName, StringRef FullName);
 
   /// constructCompileUnit - Create new CompileUnit for the given 
   /// metadata node with tag DW_TAG_compile_unit.
Modified: test/CodeGen/X86/unknown-location.ll
===================================================================
--- a/test/CodeGen/X86/unknown-location.ll
+++ b/test/CodeGen/X86/unknown-location.ll
@@ -9,7 +9,7 @@
 ; CHECK-NEXT: Ltmp
 ; CHECK-NEXT:         cltd
 ; CHECK-NEXT:         idivl   %r8d
-; CHECK-NEXT:         .loc 1 4 3
+; CHECK-NEXT:         .loc 2 4 3
 ; CHECK-NEXT: Ltmp
 ; CHECK-NEXT:         addl    %ecx, %eax
 ; CHECK-NEXT:         ret

Added: test/DebugInfo/dbg-file-name.ll
===================================================================
--- /dev/null
+++ b/test/DebugInfo/dbg-file-name.ll
@@ -0,0 +1,67 @@
+; RUN: llc -O0 < %s | FileCheck %s
+; Radar 8884898
+; CHECK: file	1 "/Users/manav/one/two/simple.c"
+
+@.str = private unnamed_addr constant [8 x i8] c"i = %d\0A\00", align 4
+@.str1 = private unnamed_addr constant [12 x i8] c"i + 1 = %d\0A\00", align 4
+
+define void @foo(i32 %i) nounwind {
+entry:
+  %i_addr = alloca i32, align 4
+  %"alloca point" = bitcast i32 0 to i32
+  call void @llvm.dbg.declare(metadata !{i32* %i_addr}, metadata !9), !dbg !10
+  store i32 %i, i32* %i_addr
+  %0 = load i32* %i_addr, align 4, !dbg !11
+  %1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([8 x i8]* @.str, i32 \
0, i32 0), i32 %0) nounwind, !dbg !11 +  %2 = load i32* %i_addr, align 4, !dbg !13
+  %3 = add nsw i32 %2, 1, !dbg !13
+  %4 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str1, \
i32 0, i32 0), i32 %3) nounwind, !dbg !13 +  br label %return, !dbg !14
+
+return:                                           ; preds = %entry
+  ret void, !dbg !14
+}
+
+declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
+
+declare i32 @printf(i8*, ...) nounwind
+
+define i32 @main() nounwind {
+entry:
+  %retval = alloca i32
+  %0 = alloca i32
+  %"alloca point" = bitcast i32 0 to i32
+  call void @foo(i32 2) nounwind, !dbg !15
+  call void @foo(i32 4) nounwind, !dbg !17
+  store i32 0, i32* %0, align 4, !dbg !18
+  %1 = load i32* %0, align 4, !dbg !18
+  store i32 %1, i32* %retval, align 4, !dbg !18
+  br label %return, !dbg !18
+
+return:                                           ; preds = %entry
+  %retval1 = load i32* %retval, !dbg !18
+  ret i32 %retval1, !dbg !18
+}
+
+!llvm.dbg.sp = !{!0, !6}
+
+!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"foo", metadata !"foo", \
metadata !"foo", metadata !1, i32 4, metadata !3, i1 false, i1 true, i32 0, i32 0, \
null, i32 256, i1 false, void (i32)* @foo} ; [ DW_TAG_subprogram ] +!1 = metadata \
!{i32 589865, metadata !"simple.c", metadata !"/Users/manav/one/two", metadata !2} ; \
[ DW_TAG_file_type ] +!2 = metadata !{i32 589841, i32 0, i32 1, metadata !"simple.c", \
metadata !"/Users/manav/one/two", metadata !"LLVM build 00", i1 true, i1 false, \
metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 589845, metadata \
!1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, \
i32 0, null} ; [ DW_TAG_subroutine_type ] +!4 = metadata !{null, metadata !5}
+!5 = metadata !{i32 589860, metadata !1, metadata !"int", metadata !1, i32 0, i64 \
32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 589870, \
i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"main", metadata \
!1, i32 9, metadata !7, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 \
()* @main} ; [ DW_TAG_subprogram ] +!7 = metadata !{i32 589845, metadata !1, metadata \
!"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !8, i32 0, null} \
; [ DW_TAG_subroutine_type ] +!8 = metadata !{metadata !5}
+!9 = metadata !{i32 590081, metadata !0, metadata !"i", metadata !1, i32 4, metadata \
!5, i32 0} ; [ DW_TAG_arg_variable ] +!10 = metadata !{i32 4, i32 0, metadata !0, \
null} +!11 = metadata !{i32 5, i32 0, metadata !12, null}
+!12 = metadata !{i32 589835, metadata !0, i32 4, i32 0, metadata !1, i32 0} ; [ \
DW_TAG_lexical_block ] +!13 = metadata !{i32 6, i32 0, metadata !12, null}
+!14 = metadata !{i32 7, i32 0, metadata !12, null}
+!15 = metadata !{i32 10, i32 0, metadata !16, null}
+!16 = metadata !{i32 589835, metadata !6, i32 9, i32 0, metadata !1, i32 1} ; [ \
DW_TAG_lexical_block ] +!17 = metadata !{i32 11, i32 0, metadata !16, null}
+!18 = metadata !{i32 12, i32 0, metadata !16, null}
+



   Commit: c03250eee02ef0d791456a69fceb13375a4ac56a
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/24/2011 16:42:48
      URL: https://github.com/mono/llvm/commit/c03250eee02ef0d791456a69fceb13375a4ac56a


ADR was added with the wrong encoding for inst{24-21}, and the ARM decoder was \
fooled. Set the encoding bits to {0,?,?,0}, not 0.  Plus delegate the disassembly of \
ADR to the more generic ADDri/SUBri instructions, and add a test case for that.


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

Changed paths:
 M lib/Target/ARM/ARMInstrInfo.td
 M test/MC/Disassembler/ARM/arm-tests.txt
 M utils/TableGen/ARMDecoderEmitter.cpp

Modified: lib/Target/ARM/ARMInstrInfo.td
===================================================================
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -1253,7 +1253,7 @@ let neverHasSideEffects = 1, isReMaterializable = 1 in
 // The 'adr' mnemonic encodes differently if the label is before or after
 // the instruction. The {24-21} opcode bits are set by the fixup, as we don't
 // know until then which form of the instruction will be used.
-def ADR : AI1<0, (outs GPR:$Rd), (ins adrlabel:$label),
+def ADR : AI1<{0,?,?,0}, (outs GPR:$Rd), (ins adrlabel:$label),
                  MiscFrm, IIC_iALUi, "adr", "\t$Rd, #$label", []> {
   bits<4> Rd;
   bits<12> label;
Modified: test/MC/Disassembler/ARM/arm-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/arm-tests.txt
+++ b/test/MC/Disassembler/ARM/arm-tests.txt
@@ -1,5 +1,8 @@
 # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 | FileCheck %s
 
+# CHECK:	addpl	r4, pc, #19, 8
+0x4c 0x45 0x8f 0x52
+
 # CHECK:	b	#0
 0x00 0x00 0x00 0xea
 
Modified: utils/TableGen/ARMDecoderEmitter.cpp
===================================================================
--- a/utils/TableGen/ARMDecoderEmitter.cpp
+++ b/utils/TableGen/ARMDecoderEmitter.cpp
@@ -1584,6 +1584,10 @@ ARMDEBackend::populateInstruction(const CodeGenInstruction \
&CGI,  Name == "MOVr_TC")
       return false;
 
+    // Delegate ADR disassembly to the more generic ADDri/SUBri instructions.
+    if (Name == "ADR")
+      return false;
+
     //
     // The following special cases are for conflict resolutions.
     //


   Commit: 36c2c76b0adf523239c75fb0da61182f8fd93fee
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/24/2011 16:56:23
      URL: https://github.com/mono/llvm/commit/36c2c76b0adf523239c75fb0da61182f8fd93fee


Remove these two test files as they cause llvm-i686-linux-vg_leak build to fail \
'test-llvm'. These two are test cases which should result in 'invalid instruction \
encoding' from running llvm-mc -disassemble.


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

Removed paths:
 D test/MC/Disassembler/ARM/invalid-CPS3p-arm.txt
 D test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt

   Commit: 7dbdd0cc9ed52f17cb27fe055073f9e262e6cdd8
   Author: Bruno Cardoso Lopes <bruno.cardoso@gmail.com>
     Date: 03/24/2011 17:04:58
      URL: https://github.com/mono/llvm/commit/7dbdd0cc9ed52f17cb27fe055073f9e262e6cdd8


Add asm parsing support w/ testcases for strex/ldrex family of instructions

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

Changed paths:
 M lib/MC/MCDisassembler/EDInfo.h
 M lib/MC/MCDisassembler/EDOperand.cpp
 M lib/Target/ARM/ARMInstrFormats.td
 M lib/Target/ARM/ARMInstrInfo.td
 M lib/Target/ARM/ARMInstrThumb2.td
 M lib/Target/ARM/AsmParser/ARMAsmParser.cpp
 M lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
 M lib/Target/ARM/InstPrinter/ARMInstPrinter.h
 M test/MC/ARM/arm_instructions.s
 M test/MC/ARM/thumb2.s
 M utils/TableGen/EDEmitter.cpp

Modified: lib/MC/MCDisassembler/EDInfo.h
===================================================================
--- a/lib/MC/MCDisassembler/EDInfo.h
+++ b/lib/MC/MCDisassembler/EDInfo.h
@@ -35,6 +35,7 @@ enum OperandTypes {
   kOperandTypeARMAddrMode5,
   kOperandTypeARMAddrMode6,
   kOperandTypeARMAddrMode6Offset,
+  kOperandTypeARMAddrMode7,
   kOperandTypeARMAddrModePC,
   kOperandTypeARMRegisterList,
   kOperandTypeARMTBAddrMode,
@@ -51,7 +52,8 @@ enum OperandTypes {
   kOperandTypeThumb2AddrModeImm12,
   kOperandTypeThumb2AddrModeSoReg,
   kOperandTypeThumb2AddrModeImm8s4,
-  kOperandTypeThumb2AddrModeImm8s4Offset
+  kOperandTypeThumb2AddrModeImm8s4Offset,
+  kOperandTypeThumb2AddrModeReg
 };
 
 enum OperandFlags {
Modified: lib/MC/MCDisassembler/EDOperand.cpp
===================================================================
--- a/lib/MC/MCDisassembler/EDOperand.cpp
+++ b/lib/MC/MCDisassembler/EDOperand.cpp
@@ -73,6 +73,8 @@ EDOperand::EDOperand(const EDDisassembler &disassembler,
     case kOperandTypeThumb2AddrModeImm8Offset:
     case kOperandTypeARMTBAddrMode:
     case kOperandTypeThumb2AddrModeImm8s4Offset:
+    case kOperandTypeARMAddrMode7:
+    case kOperandTypeThumb2AddrModeReg:
       numMCOperands = 1;
       break;
     case kOperandTypeThumb2SoReg:
@@ -256,6 +258,7 @@ int EDOperand::isMemory() {
   case kOperandTypeARMAddrMode4:
   case kOperandTypeARMAddrMode5:
   case kOperandTypeARMAddrMode6:
+  case kOperandTypeARMAddrMode7:
   case kOperandTypeARMAddrModePC:
   case kOperandTypeARMBranchTarget:
   case kOperandTypeThumbAddrModeS1:
@@ -269,6 +272,7 @@ int EDOperand::isMemory() {
   case kOperandTypeThumb2AddrModeImm12:
   case kOperandTypeThumb2AddrModeSoReg:
   case kOperandTypeThumb2AddrModeImm8s4:
+  case kOperandTypeThumb2AddrModeReg:
     return 1;
   }
 }
Modified: lib/Target/ARM/ARMInstrFormats.td
===================================================================
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -434,11 +434,11 @@ class AIstrex<bits<2> opcod, dag oops, dag iops, InstrItinClass \
itin,  opc, asm, "", pattern> {
   bits<4> Rd;
   bits<4> Rt;
-  bits<4> Rn;
+  bits<4> addr;
   let Inst{27-23} = 0b00011;
   let Inst{22-21} = opcod;
   let Inst{20}    = 0;
-  let Inst{19-16} = Rn;
+  let Inst{19-16} = addr;
   let Inst{15-12} = Rd;
   let Inst{11-4}  = 0b11111001;
   let Inst{3-0}   = Rt;
Modified: lib/Target/ARM/ARMInstrInfo.td
===================================================================
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -590,6 +590,21 @@ def addrmodepc : Operand<i32>,
   let MIOperandInfo = (ops GPR, i32imm);
 }
 
+def MemMode7AsmOperand : AsmOperandClass {
+  let Name = "MemMode7";
+  let SuperClasses = [];
+}
+
+// addrmode7 := reg
+// Used by load/store exclusive instructions. Useful to enable right assembly
+// parsing and printing. Not used for any codegen matching.
+//
+def addrmode7 : Operand<i32> {
+  let PrintMethod = "printAddrMode7Operand";
+  let MIOperandInfo = (ops GPR);
+  let ParserMatchClass = MemMode7AsmOperand;
+}
+
 def nohash_imm : Operand<i32> {
   let PrintMethod = "printNoHashImmediate";
 }
@@ -3294,39 +3309,26 @@ let usesCustomInserter = 1 in {
 }
 
 let mayLoad = 1 in {
-def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
-                    "ldrexb", "\t$Rt, [$Rn]",
-                    []>;
-def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
-                    "ldrexh", "\t$Rt, [$Rn]",
-                    []>;
-def LDREX  : AIldrex<0b00, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
-                    "ldrex", "\t$Rt, [$Rn]",
-                    []>;
-def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins GPR:$Rn),
-                    NoItinerary,
-                    "ldrexd", "\t$Rt, $Rt2, [$Rn]",
-                    []>;
+def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins addrmode7:$addr), NoItinerary,
+                    "ldrexb", "\t$Rt, $addr", []>;
+def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins addrmode7:$addr), NoItinerary,
+                    "ldrexh", "\t$Rt, $addr", []>;
+def LDREX  : AIldrex<0b00, (outs GPR:$Rt), (ins addrmode7:$addr), NoItinerary,
+                    "ldrex", "\t$Rt, $addr", []>;
+def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins addrmode7:$addr),
+                    NoItinerary, "ldrexd", "\t$Rt, $Rt2, $addr", []>;
 }
 
 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
-def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$src, GPR:$Rn),
-                    NoItinerary,
-                    "strexb", "\t$Rd, $src, [$Rn]",
-                    []>;
-def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
-                    NoItinerary,
-                    "strexh", "\t$Rd, $Rt, [$Rn]",
-                    []>;
-def STREX  : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
-                    NoItinerary,
-                    "strex", "\t$Rd, $Rt, [$Rn]",
-                    []>;
+def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$Rt, addrmode7:$addr),
+                    NoItinerary, "strexb", "\t$Rd, $Rt, $addr", []>;
+def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, addrmode7:$addr),
+                    NoItinerary, "strexh", "\t$Rd, $Rt, $addr", []>;
+def STREX  : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, addrmode7:$addr),
+                    NoItinerary, "strex", "\t$Rd, $Rt, $addr", []>;
 def STREXD : AIstrex<0b01, (outs GPR:$Rd),
-                    (ins GPR:$Rt, GPR:$Rt2, GPR:$Rn),
-                    NoItinerary,
-                    "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]",
-                    []>;
+                    (ins GPR:$Rt, GPR:$Rt2, addrmode7:$addr),
+                    NoItinerary, "strexd", "\t$Rd, $Rt, $Rt2, $addr", []>;
 }
 
 // Clear-Exclusive is for disassembly only.
Modified: lib/Target/ARM/ARMInstrThumb2.td
===================================================================
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -145,6 +145,15 @@ def t2addrmode_so_reg : Operand<i32>,
   let ParserMatchClass = MemMode5AsmOperand;
 }
 
+// t2addrmode_reg := reg
+// Used by load/store exclusive instructions. Useful to enable right assembly
+// parsing and printing. Not used for any codegen matching.
+//
+def t2addrmode_reg : Operand<i32> {
+  let PrintMethod = "printAddrMode7Operand";
+  let MIOperandInfo = (ops tGPR);
+  let ParserMatchClass = MemMode7AsmOperand;
+}
 
 //===----------------------------------------------------------------------===//
 // Multiclass helpers...
@@ -2821,9 +2830,9 @@ class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, \
SizeFlagVal sz,  let Inst{5-4} = opcod;
   let Inst{3-0} = 0b1111;
 
-  bits<4> Rn;
+  bits<4> addr;
   bits<4> Rt;
-  let Inst{19-16} = Rn;
+  let Inst{19-16} = addr;
   let Inst{15-12} = Rt;
 }
 class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
@@ -2837,37 +2846,37 @@ class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode \
am, SizeFlagVal sz,  let Inst{5-4} = opcod;
 
   bits<4> Rd;
-  bits<4> Rn;
+  bits<4> addr;
   bits<4> Rt;
-  let Inst{11-8}  = Rd;
-  let Inst{19-16} = Rn;
+  let Inst{3-0}  = Rd;
+  let Inst{19-16} = addr;
   let Inst{15-12} = Rt;
 }
 
 let mayLoad = 1 in {
-def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
-                         Size4Bytes, NoItinerary, "ldrexb", "\t$Rt, [$Rn]",
+def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$Rt), (ins t2addrmode_reg:$addr), \
AddrModeNone, +                         Size4Bytes, NoItinerary, "ldrexb", "\t$Rt, \
$addr",  "", []>;
-def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
-                         Size4Bytes, NoItinerary, "ldrexh", "\t$Rt, [$Rn]",
+def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$Rt), (ins t2addrmode_reg:$addr), \
AddrModeNone, +                         Size4Bytes, NoItinerary, "ldrexh", "\t$Rt, \
$addr",  "", []>;
-def t2LDREX  : Thumb2I<(outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
+def t2LDREX  : Thumb2I<(outs rGPR:$Rt), (ins t2addrmode_reg:$addr), AddrModeNone,
                        Size4Bytes, NoItinerary,
-                       "ldrex", "\t$Rt, [$Rn]", "",
+                       "ldrex", "\t$Rt, $addr", "",
                       []> {
   let Inst{31-27} = 0b11101;
   let Inst{26-20} = 0b0000101;
   let Inst{11-8} = 0b1111;
   let Inst{7-0} = 0b00000000; // imm8 = 0
 
-  bits<4> Rn;
   bits<4> Rt;
-  let Inst{19-16} = Rn;
+  bits<4> addr;
+  let Inst{19-16} = addr;
   let Inst{15-12} = Rt;
 }
-def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$Rt, rGPR:$Rt2), (ins rGPR:$Rn),
+def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$Rt, rGPR:$Rt2), (ins \
t2addrmode_reg:$addr),  AddrModeNone, Size4Bytes, NoItinerary,
-                         "ldrexd", "\t$Rt, $Rt2, [$Rn]", "",
+                         "ldrexd", "\t$Rt, $Rt2, $addr", "",
                          [], {?, ?, ?, ?}> {
   bits<4> Rt2;
   let Inst{11-8} = Rt2;
@@ -2875,31 +2884,31 @@ def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$Rt, rGPR:$Rt2), \
(ins rGPR:$Rn),  }
 
 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
-def t2STREXB : T2I_strex<0b00, (outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
-                         AddrModeNone, Size4Bytes, NoItinerary,
-                         "strexb", "\t$Rd, $Rt, [$Rn]", "", []>;
-def t2STREXH : T2I_strex<0b01, (outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
-                         AddrModeNone, Size4Bytes, NoItinerary,
-                         "strexh", "\t$Rd, $Rt, [$Rn]", "", []>;
-def t2STREX  : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
-                       AddrModeNone, Size4Bytes, NoItinerary,
-                       "strex", "\t$Rd, $Rt, [$Rn]", "",
-                      []> {
+def t2STREXB : T2I_strex<0b00, (outs rGPR:$Rd), (ins rGPR:$Rt, \
t2addrmode_reg:$addr), +                  AddrModeNone, Size4Bytes, NoItinerary,
+                  "strexb", "\t$Rd, $Rt, $addr", "", []>;
+def t2STREXH : T2I_strex<0b01, (outs rGPR:$Rd), (ins rGPR:$Rt, \
t2addrmode_reg:$addr), +                  AddrModeNone, Size4Bytes, NoItinerary,
+                  "strexh", "\t$Rd, $Rt, $addr", "", []>;
+def t2STREX  : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt, t2addrmode_reg:$addr),
+                  AddrModeNone, Size4Bytes, NoItinerary,
+                  "strex", "\t$Rd, $Rt, $addr", "",
+                  []> {
   let Inst{31-27} = 0b11101;
   let Inst{26-20} = 0b0000100;
   let Inst{7-0} = 0b00000000; // imm8 = 0
 
   bits<4> Rd;
-  bits<4> Rn;
+  bits<4> addr;
   bits<4> Rt;
   let Inst{11-8}  = Rd;
-  let Inst{19-16} = Rn;
+  let Inst{19-16} = addr;
   let Inst{15-12} = Rt;
 }
 def t2STREXD : T2I_strex<0b11, (outs rGPR:$Rd),
-                         (ins rGPR:$Rt, rGPR:$Rt2, rGPR:$Rn),
+                         (ins rGPR:$Rt, rGPR:$Rt2, t2addrmode_reg:$addr),
                          AddrModeNone, Size4Bytes, NoItinerary,
-                         "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]", "", [],
+                         "strexd", "\t$Rd, $Rt, $Rt2, $addr", "", [],
                          {?, ?, ?, ?}> {
   bits<4> Rt2;
   let Inst{11-8} = Rt2;
Modified: lib/Target/ARM/AsmParser/ARMAsmParser.cpp
===================================================================
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -350,6 +350,23 @@ public:
     int64_t Value = CE->getValue();
     return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
   }
+  bool isMemMode7() const {
+    if (!isMemory() ||
+        getMemPreindexed() ||
+        getMemPostindexed() ||
+        getMemOffsetIsReg() ||
+        getMemNegative() ||
+        getMemWriteback())
+      return false;
+
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
+    if (!CE) return false;
+
+    if (CE->getValue())
+      return false;
+
+    return true;
+  }
   bool isMemModeRegThumb() const {
     if (!isMemory() || !getMemOffsetIsReg() || getMemWriteback())
       return false;
@@ -438,6 +455,15 @@ public:
     Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
   }
 
+  void addMemMode7Operands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && isMemMode7() && "Invalid number of operands!");
+    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
+
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
+    assert((CE || CE->getValue() == 0) &&
+           "No offset operand support in mode 7");
+  }
+
   void addMemMode5Operands(MCInst &Inst, unsigned N) const {
     assert(N == 2 && isMemMode5() && "Invalid number of operands!");
 
Modified: lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
===================================================================
--- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
+++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
@@ -317,6 +317,12 @@ void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, \
unsigned OpNum,  O << "]";
 }
 
+void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum,
+                                           raw_ostream &O) {
+  const MCOperand &MO1 = MI->getOperand(OpNum);
+  O << "[" << getRegisterName(MO1.getReg()) << "]";
+}
+
 void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI,
                                                  unsigned OpNum,
                                                  raw_ostream &O) {
Modified: lib/Target/ARM/InstPrinter/ARMInstPrinter.h
===================================================================
--- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
+++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
@@ -51,6 +51,7 @@ public:
   void printLdStmModeOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
   void printAddrMode5Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
   void printAddrMode6Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+  void printAddrMode7Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
   void printAddrMode6OffsetOperand(const MCInst *MI, unsigned OpNum,
                                    raw_ostream &O);
 
Modified: test/MC/ARM/arm_instructions.s
===================================================================
--- a/test/MC/ARM/arm_instructions.s
+++ b/test/MC/ARM/arm_instructions.s
@@ -284,3 +284,28 @@
 
 @ CHECK: add	r1, r2, r3, lsl r4      @ encoding: [0x13,0x14,0x82,0xe0]
   add r1, r2, r3, lsl r4
+
+@ CHECK: strexb  r0, r1, [r2] @ encoding: [0x91,0x0f,0xc2,0xe1]
+        strexb  r0, r1, [r2]
+
+@ CHECK: strexh  r0, r1, [r2] @ encoding: [0x91,0x0f,0xe2,0xe1]
+        strexh  r0, r1, [r2]
+
+@ CHECK: strex  r0, r1, [r2] @ encoding: [0x91,0x0f,0x82,0xe1]
+        strex  r0, r1, [r2]
+
+@ CHECK: strexd  r0, r2, r3, [r1] @ encoding: [0x92,0x0f,0xa1,0xe1]
+        strexd  r0, r2, r3, [r1]
+
+@ CHECK: ldrexb  r0, [r0] @ encoding: [0x9f,0x0f,0xd0,0xe1]
+        ldrexb  r0, [r0]
+
+@ CHECK: ldrexh  r0, [r0] @ encoding: [0x9f,0x0f,0xf0,0xe1]
+        ldrexh  r0, [r0]
+
+@ CHECK: ldrex  r0, [r0] @ encoding: [0x9f,0x0f,0x90,0xe1]
+        ldrex  r0, [r0]
+
+@ CHECK: ldrexd  r0, r1, [r0] @ encoding: [0x9f,0x0f,0xb0,0xe1]
+        ldrexd  r0, r1, [r0]
+
Modified: test/MC/ARM/thumb2.s
===================================================================
--- a/test/MC/ARM/thumb2.s
+++ b/test/MC/ARM/thumb2.s
@@ -284,3 +284,19 @@
 @ CHECK: msr  cpsr_fsxc, r0 @ encoding: [0x80,0xf3,0x00,0x8f]
   msr  cpsr_fsxc, r0
 
+@ CHECK: strexb  r0, r1, [r2] @ encoding: [0xc2,0xe8,0x40,0x1f]
+  strexb  r0, r1, [r2]
+@ CHECK: strexh  r0, r1, [r2] @ encoding: [0xc2,0xe8,0x50,0x1f]
+  strexh  r0, r1, [r2]
+@ CHECK: strex  r0, r1, [r2] @ encoding: [0x42,0xe8,0x00,0x10]
+  strex  r0, r1, [r2]
+@ CHECK: strexd  r0, r2, r3, [r1] @ encoding: [0xc1,0xe8,0x70,0x23]
+  strexd  r0, r2, r3, [r1]
+@ CHECK: ldrexb  r0, [r0] @ encoding: [0xd0,0xe8,0x4f,0x0f]
+  ldrexb  r0, [r0]
+@ CHECK: ldrexh  r0, [r0] @ encoding: [0xd0,0xe8,0x5f,0x0f]
+  ldrexh  r0, [r0]
+@ CHECK: ldrex  r0, [r0] @ encoding: [0x50,0xe8,0x00,0x0f]
+  ldrex  r0, [r0]
+@ CHECK: ldrexd  r0, r1, [r0] @ encoding: [0xd0,0xe8,0x7f,0x01]
+  ldrexd  r0, r1, [r0]
Modified: utils/TableGen/EDEmitter.cpp
===================================================================
--- a/utils/TableGen/EDEmitter.cpp
+++ b/utils/TableGen/EDEmitter.cpp
@@ -637,10 +637,12 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
   MISC("am6offset", "kOperandTypeARMAddrMode6Offset");            // R, I, I
   MISC("addrmode6dup", "kOperandTypeARMAddrMode6");               // R, R, I, I
   MISC("addrmodepc", "kOperandTypeARMAddrModePC");                // R, I
+  MISC("addrmode7", "kOperandTypeARMAddrMode7");                  // R
   MISC("reglist", "kOperandTypeARMRegisterList");                 // I, R, ...
   MISC("dpr_reglist", "kOperandTypeARMDPRRegisterList");          // I, R, ...
   MISC("spr_reglist", "kOperandTypeARMSPRRegisterList");          // I, R, ...
   MISC("it_mask", "kOperandTypeThumbITMask");                     // I
+  MISC("t2addrmode_reg", "kOperandTypeThumb2AddrModeReg");        // R
   MISC("t2addrmode_imm8", "kOperandTypeThumb2AddrModeImm8");      // R, I
   MISC("t2am_imm8_offset", "kOperandTypeThumb2AddrModeImm8Offset");//I
   MISC("t2addrmode_imm12", "kOperandTypeThumb2AddrModeImm12");    // R, I
@@ -858,6 +860,7 @@ static void emitCommonEnums(raw_ostream &o, unsigned int &i) {
   operandTypes.addEntry("kOperandTypeARMAddrMode5");
   operandTypes.addEntry("kOperandTypeARMAddrMode6");
   operandTypes.addEntry("kOperandTypeARMAddrMode6Offset");
+  operandTypes.addEntry("kOperandTypeARMAddrMode7");
   operandTypes.addEntry("kOperandTypeARMAddrModePC");
   operandTypes.addEntry("kOperandTypeARMRegisterList");
   operandTypes.addEntry("kOperandTypeARMDPRRegisterList");
@@ -869,6 +872,7 @@ static void emitCommonEnums(raw_ostream &o, unsigned int &i) {
   operandTypes.addEntry("kOperandTypeThumbAddrModeRR");
   operandTypes.addEntry("kOperandTypeThumbAddrModeSP");
   operandTypes.addEntry("kOperandTypeThumbAddrModePC");
+  operandTypes.addEntry("kOperandTypeThumb2AddrModeReg");
   operandTypes.addEntry("kOperandTypeThumb2SoReg");
   operandTypes.addEntry("kOperandTypeThumb2SoImm");
   operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8");


   Commit: 7b4458d7f43544c0861cffdc5f516b73ba397bdf
   Author: Benjamin Kramer <benny.kra@googlemail.com>
     Date: 03/24/2011 17:14:28
      URL: https://github.com/mono/llvm/commit/7b4458d7f43544c0861cffdc5f516b73ba397bdf


Plug a leak in the arm disassembler and put the tests back.


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

Changed paths:
 M lib/Target/ARM/Disassembler/ARMDisassembler.cpp
Added paths:
 A test/MC/Disassembler/ARM/invalid-CPS3p-arm.txt
 A test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt

Modified: lib/Target/ARM/Disassembler/ARMDisassembler.cpp
===================================================================
--- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -18,6 +18,7 @@
 #include "ARMDisassembler.h"
 #include "ARMDisassemblerCore.h"
 
+#include "llvm/ADT/OwningPtr.h"
 #include "llvm/MC/EDInstInfo.h"
 #include "llvm/MC/MCInst.h"
 #include "llvm/Target/TargetRegistry.h"
@@ -384,15 +385,13 @@ bool ARMDisassembler::getInstruction(MCInst &MI,
       showBitVector(errs(), insn);
     });
 
-  ARMBasicMCBuilder *Builder = CreateMCBuilder(Opcode, Format);
+  OwningPtr<ARMBasicMCBuilder> Builder(CreateMCBuilder(Opcode, Format));
   if (!Builder)
     return false;
 
   if (!Builder->Build(MI, insn))
     return false;
 
-  delete Builder;
-
   return true;
 }
 

Added: test/MC/Disassembler/ARM/invalid-CPS3p-arm.txt
===================================================================
--- /dev/null
+++ b/test/MC/Disassembler/ARM/invalid-CPS3p-arm.txt
@@ -0,0 +1,5 @@
+# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid \
instruction encoding} +
+# invalid (imod, M, iflags) combination
+0x93 0x1c 0x02 0xf1
+

Added: test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt
===================================================================
--- /dev/null
+++ b/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt
@@ -0,0 +1,5 @@
+# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid \
instruction encoding} +
+# core registers out of range
+0xa5 0xba 0x52 0xed
+



   Commit: 40c254a2b00c1054e8a99d3993647afe95c2b83e
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/24/2011 17:36:56
      URL: https://github.com/mono/llvm/commit/40c254a2b00c1054e8a99d3993647afe95c2b83e


T2 Load/Store Multiple:
These instructions were changed to not embed the addressing mode within the MC \
instructions We also need to update the corresponding assert stmt.  Also add a test \
case.


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

Changed paths:
 M lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
 M test/MC/Disassembler/ARM/thumb-tests.txt

Modified: lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
===================================================================
--- a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
+++ b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
@@ -1140,7 +1140,7 @@ static bool DisassembleThumb2LdStMul(MCInst &MI, unsigned \
Opcode, uint32_t insn,  Opcode == ARM::t2STMIA || Opcode == ARM::t2STMIA_UPD ||
           Opcode == ARM::t2STMDB || Opcode == ARM::t2STMDB_UPD)
          && "Unexpected opcode");
-  assert(NumOps >= 5 && "Thumb2 LdStMul expects NumOps >= 5");
+  assert(NumOps >= 4 && "Thumb2 LdStMul expects NumOps >= 4");
 
   NumOpsAdded = 0;
 
Modified: test/MC/Disassembler/ARM/thumb-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/thumb-tests.txt
+++ b/test/MC/Disassembler/ARM/thumb-tests.txt
@@ -136,3 +136,6 @@
 
 # CHECK:	vcmpe.f64	d8, #0
 0xb5 0xee 0xc0 0x8b
+
+# CHECK:	stmdb.w	sp, {r0, r2, r3, r8, r11, lr}
+0x0d 0xe9 0x0d 0x49


   Commit: 40d06fda96a41f73463e7bae9a3d6a9cdebdd612
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/24/2011 17:42:55
      URL: https://github.com/mono/llvm/commit/40d06fda96a41f73463e7bae9a3d6a9cdebdd612


Plug a leak by ThumbDisassembler::getInstruction(), thanks to Benjamin Kramer!


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

Changed paths:
 M lib/Target/ARM/Disassembler/ARMDisassembler.cpp

Modified: lib/Target/ARM/Disassembler/ARMDisassembler.cpp
===================================================================
--- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -465,7 +465,7 @@ bool ThumbDisassembler::getInstruction(MCInst &MI,
       showBitVector(errs(), insn);
     });
 
-  ARMBasicMCBuilder *Builder = CreateMCBuilder(Opcode, Format);
+  OwningPtr<ARMBasicMCBuilder> Builder(CreateMCBuilder(Opcode, Format));
   if (!Builder)
     return false;
 
@@ -474,8 +474,6 @@ bool ThumbDisassembler::getInstruction(MCInst &MI,
   if (!Builder->Build(MI, insn))
     return false;
 
-  delete Builder;
-
   return true;
 }
 


   Commit: ab2eaed4178e8b890045bd0c2479d94ebd55c369
   Author: Eric Christopher <echristo@apple.com>
     Date: 03/24/2011 17:59:03
      URL: https://github.com/mono/llvm/commit/ab2eaed4178e8b890045bd0c2479d94ebd55c369


Testcase for llvm-gcc commit r128230.


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

Added paths:
 A test/FrontendC/vla-3.c

Added: test/FrontendC/vla-3.c
===================================================================
--- /dev/null
+++ b/test/FrontendC/vla-3.c
@@ -0,0 +1,12 @@
+// RUN: %llvmgcc -std=gnu99 %s -S -o - | grep ".*alloca.*align 16"
+
+void adr(char *);
+
+void vlaalign(int size)
+{
+    char __attribute__((aligned(16))) tmp[size+32];
+    char tmp2[size+16];
+
+    adr(tmp);
+}
+



   Commit: 1783e0e0b9ee2ad9c710e55e9420b96adc86da77
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/24/2011 18:04:39
      URL: https://github.com/mono/llvm/commit/1783e0e0b9ee2ad9c710e55e9420b96adc86da77


Handle the added VBICiv*i* NEON instructions, too.


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

Changed paths:
 M lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
 M test/MC/Disassembler/ARM/neon-tests.txt

Modified: lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
===================================================================
--- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
@@ -2302,6 +2302,7 @@ static bool DisassembleNLdSt(MCInst &MI, unsigned Opcode, \
uint32_t insn,  
 // VMOV (immediate)
 //   Qd/Dd imm
+// VBIC (immediate)
 // VORR (immediate)
 //   Qd/Dd imm src(=Qd/Dd)
 static bool DisassembleN1RegModImmFrm(MCInst &MI, unsigned Opcode,
@@ -2330,6 +2331,8 @@ static bool DisassembleN1RegModImmFrm(MCInst &MI, unsigned \
Opcode,  case ARM::VMOVv8i16:
   case ARM::VMVNv4i16:
   case ARM::VMVNv8i16:
+  case ARM::VBICiv4i16:
+  case ARM::VBICiv8i16:
   case ARM::VORRiv4i16:
   case ARM::VORRiv8i16:
     esize = ESize16;
@@ -2338,6 +2341,8 @@ static bool DisassembleN1RegModImmFrm(MCInst &MI, unsigned \
Opcode,  case ARM::VMOVv4i32:
   case ARM::VMVNv2i32:
   case ARM::VMVNv4i32:
+  case ARM::VBICiv2i32:
+  case ARM::VBICiv4i32:
   case ARM::VORRiv2i32:
   case ARM::VORRiv4i32:
     esize = ESize32;
@@ -2347,7 +2352,7 @@ static bool DisassembleN1RegModImmFrm(MCInst &MI, unsigned \
Opcode,  esize = ESize64;
     break;
   default:
-    assert(0 && "Unreachable code!");
+    assert(0 && "Unexpected opcode!");
     return false;
   }
 
@@ -2357,7 +2362,7 @@ static bool DisassembleN1RegModImmFrm(MCInst &MI, unsigned \
Opcode,  
   NumOpsAdded = 2;
 
-  // VORRiv*i* variants have an extra $src = $Vd to be filled in.
+  // VBIC/VORRiv*i* variants have an extra $src = $Vd to be filled in.
   if (NumOps >= 3 &&
       (OpInfo[2].RegClass == ARM::DPRRegClassID ||
        OpInfo[2].RegClass == ARM::QPRRegClassID)) {
Modified: test/MC/Disassembler/ARM/neon-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/neon-tests.txt
+++ b/test/MC/Disassembler/ARM/neon-tests.txt
@@ -65,3 +65,6 @@
 
 # CHECK:	vorr.i32	q15, #0x4F0000
 0x5f 0xe5 0xc4 0xf2
+
+# CHECK:	vbic.i32	q2, #0xA900
+0x79 0x53 0x82 0xf3


   Commit: 2ce45b0699aac0ba7a8d2f429aef0b6340b09f82
   Author: Matt Beaumont-Gay <matthewbg@google.com>
     Date: 03/24/2011 18:05:48
      URL: https://github.com/mono/llvm/commit/2ce45b0699aac0ba7a8d2f429aef0b6340b09f82


Suppress an unused variable warning in -asserts builds

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

Changed paths:
 M lib/Target/ARM/AsmParser/ARMAsmParser.cpp

Modified: lib/Target/ARM/AsmParser/ARMAsmParser.cpp
===================================================================
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -460,6 +460,7 @@ public:
     Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
 
     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
+    (void)CE;
     assert((CE || CE->getValue() == 0) &&
            "No offset operand support in mode 7");
   }


   Commit: 97114f9672f7fc70213ed8418025bc54f5e6ff96
   Author: Devang Patel <dpatel@apple.com>
     Date: 03/24/2011 18:39:09
      URL: https://github.com/mono/llvm/commit/97114f9672f7fc70213ed8418025bc54f5e6ff96


Move test in x86 specific area.


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

Added paths:
 A test/CodeGen/X86/dbg-file-name.ll
Removed paths:
 D test/DebugInfo/dbg-file-name.ll

Added: test/CodeGen/X86/dbg-file-name.ll
===================================================================
--- /dev/null
+++ b/test/CodeGen/X86/dbg-file-name.ll
@@ -0,0 +1,70 @@
+; RUN: llc -O0 < %s | FileCheck %s
+target datalayout = \
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
 +target triple = "x86_64-apple-darwin10.0.0"
+
+; Radar 8884898
+; CHECK: file	1 "/Users/manav/one/two/simple.c"
+
+@.str = private unnamed_addr constant [8 x i8] c"i = %d\0A\00", align 4
+@.str1 = private unnamed_addr constant [12 x i8] c"i + 1 = %d\0A\00", align 4
+
+define void @foo(i32 %i) nounwind {
+entry:
+  %i_addr = alloca i32, align 4
+  %"alloca point" = bitcast i32 0 to i32
+  call void @llvm.dbg.declare(metadata !{i32* %i_addr}, metadata !9), !dbg !10
+  store i32 %i, i32* %i_addr
+  %0 = load i32* %i_addr, align 4, !dbg !11
+  %1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([8 x i8]* @.str, i32 \
0, i32 0), i32 %0) nounwind, !dbg !11 +  %2 = load i32* %i_addr, align 4, !dbg !13
+  %3 = add nsw i32 %2, 1, !dbg !13
+  %4 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str1, \
i32 0, i32 0), i32 %3) nounwind, !dbg !13 +  br label %return, !dbg !14
+
+return:                                           ; preds = %entry
+  ret void, !dbg !14
+}
+
+declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
+
+declare i32 @printf(i8*, ...) nounwind
+
+define i32 @main() nounwind {
+entry:
+  %retval = alloca i32
+  %0 = alloca i32
+  %"alloca point" = bitcast i32 0 to i32
+  call void @foo(i32 2) nounwind, !dbg !15
+  call void @foo(i32 4) nounwind, !dbg !17
+  store i32 0, i32* %0, align 4, !dbg !18
+  %1 = load i32* %0, align 4, !dbg !18
+  store i32 %1, i32* %retval, align 4, !dbg !18
+  br label %return, !dbg !18
+
+return:                                           ; preds = %entry
+  %retval1 = load i32* %retval, !dbg !18
+  ret i32 %retval1, !dbg !18
+}
+
+!llvm.dbg.sp = !{!0, !6}
+
+!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"foo", metadata !"foo", \
metadata !"foo", metadata !1, i32 4, metadata !3, i1 false, i1 true, i32 0, i32 0, \
null, i32 256, i1 false, void (i32)* @foo} ; [ DW_TAG_subprogram ] +!1 = metadata \
!{i32 589865, metadata !"simple.c", metadata !"/Users/manav/one/two", metadata !2} ; \
[ DW_TAG_file_type ] +!2 = metadata !{i32 589841, i32 0, i32 1, metadata !"simple.c", \
metadata !"/Users/manav/one/two", metadata !"LLVM build 00", i1 true, i1 false, \
metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 589845, metadata \
!1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, \
i32 0, null} ; [ DW_TAG_subroutine_type ] +!4 = metadata !{null, metadata !5}
+!5 = metadata !{i32 589860, metadata !1, metadata !"int", metadata !1, i32 0, i64 \
32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 589870, \
i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"main", metadata \
!1, i32 9, metadata !7, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 \
()* @main} ; [ DW_TAG_subprogram ] +!7 = metadata !{i32 589845, metadata !1, metadata \
!"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !8, i32 0, null} \
; [ DW_TAG_subroutine_type ] +!8 = metadata !{metadata !5}
+!9 = metadata !{i32 590081, metadata !0, metadata !"i", metadata !1, i32 4, metadata \
!5, i32 0} ; [ DW_TAG_arg_variable ] +!10 = metadata !{i32 4, i32 0, metadata !0, \
null} +!11 = metadata !{i32 5, i32 0, metadata !12, null}
+!12 = metadata !{i32 589835, metadata !0, i32 4, i32 0, metadata !1, i32 0} ; [ \
DW_TAG_lexical_block ] +!13 = metadata !{i32 6, i32 0, metadata !12, null}
+!14 = metadata !{i32 7, i32 0, metadata !12, null}
+!15 = metadata !{i32 10, i32 0, metadata !16, null}
+!16 = metadata !{i32 589835, metadata !6, i32 9, i32 0, metadata !1, i32 1} ; [ \
DW_TAG_lexical_block ] +!17 = metadata !{i32 11, i32 0, metadata !16, null}
+!18 = metadata !{i32 12, i32 0, metadata !16, null}
+



   Commit: 0888c27c028102b1ad9c84df4f4a588949182bdf
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/24/2011 19:21:14
      URL: https://github.com/mono/llvm/commit/0888c27c028102b1ad9c84df4f4a588949182bdf


The ARM disassembler was confused with the 16-bit tSTMIA instruction.
According to A8.6.189 STM/STMIA/STMEA (Encoding T1), there's only tSTMIA_UPD \
available. Ignore tSTMIA for the decoder emitter and add a test case for that.


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

Changed paths:
 M test/MC/Disassembler/ARM/thumb-tests.txt
 M utils/TableGen/ARMDecoderEmitter.cpp

Modified: test/MC/Disassembler/ARM/thumb-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/thumb-tests.txt
+++ b/test/MC/Disassembler/ARM/thumb-tests.txt
@@ -139,3 +139,6 @@
 
 # CHECK:	stmdb.w	sp, {r0, r2, r3, r8, r11, lr}
 0x0d 0xe9 0x0d 0x49
+
+# CHECK:	stmia	r5!, {r0, r1, r2, r3, r4}
+0x1f 0xc5
Modified: utils/TableGen/ARMDecoderEmitter.cpp
===================================================================
--- a/utils/TableGen/ARMDecoderEmitter.cpp
+++ b/utils/TableGen/ARMDecoderEmitter.cpp
@@ -1615,6 +1615,11 @@ ARMDEBackend::populateInstruction(const CodeGenInstruction \
&CGI,  if (!thumbInstruction(Form))
       return false;
 
+    // A8.6.189 STM / STMIA / STMEA -- Encoding T1
+    // There's only STMIA_UPD for Thumb1.
+    if (Name == "tSTMIA")
+      return false;
+
     // On Darwin R9 is call-clobbered.  Ignore the non-Darwin counterparts.
     if (Name == "tBL" || Name == "tBLXi" || Name == "tBLXr")
       return false;


   Commit: 156053b0033bea324d18b91240aabb4c6093c07f
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/24/2011 19:42:31
      URL: https://github.com/mono/llvm/commit/156053b0033bea324d18b91240aabb4c6093c07f


The opcode names ("tLDM", "tLDM_UPD") used for conflict resolution have been stale \
since the change to ("tLDMIA", "tLDMIA_UPD").  Update the conflict resolution code \
and add test cases for that.


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

Changed paths:
 M test/MC/Disassembler/ARM/thumb-tests.txt
 M utils/TableGen/ARMDecoderEmitter.cpp

Modified: test/MC/Disassembler/ARM/thumb-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/thumb-tests.txt
+++ b/test/MC/Disassembler/ARM/thumb-tests.txt
@@ -142,3 +142,9 @@
 
 # CHECK:	stmia	r5!, {r0, r1, r2, r3, r4}
 0x1f 0xc5
+
+# CHECK:	ldmia	r5, {r0, r1, r2, r3, r4, r5}
+0x3f 0xcd
+
+# CHECK:	ldmia	r5!, {r0, r1, r2, r3, r4}
+0x1f 0xcd
Modified: utils/TableGen/ARMDecoderEmitter.cpp
===================================================================
--- a/utils/TableGen/ARMDecoderEmitter.cpp
+++ b/utils/TableGen/ARMDecoderEmitter.cpp
@@ -1382,7 +1382,7 @@ bool ARMFilterChooser::emit(raw_ostream &o, unsigned \
&Indentation) {  // 2. source registers are identical => VMOVQ; otherwise => VORRq
     // 3. LDR, LDRcp => return LDR for now.
     // FIXME: How can we distinguish between LDR and LDRcp?  Do we need to?
-    // 4. tLDM, tLDM_UPD => Rn = Inst{10-8}, reglist = Inst{7-0},
+    // 4. tLDMIA, tLDMIA_UPD => Rn = Inst{10-8}, reglist = Inst{7-0},
     //    wback = registers<Rn> = 0
     // NOTE: (tLDM, tLDM_UPD) resolution must come before Advanced SIMD
     //       addressing mode resolution!!!
@@ -1423,7 +1423,7 @@ bool ARMFilterChooser::emit(raw_ostream &o, unsigned \
&Indentation) {  << "; // Returning LDR for {LDR, LDRcp}\n";
       return true;
     }
-    if (name1 == "tLDM" && name2 == "tLDM_UPD") {
+    if (name1 == "tLDMIA" && name2 == "tLDMIA_UPD") {
       // Inserting the opening curly brace for this case block.
       --Indentation; --Indentation;
       o.indent(Indentation) << "{\n";


   Commit: 08589b7f11a26660a47746c2edab76eb38722b72
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/24/2011 20:17:42
      URL: https://github.com/mono/llvm/commit/08589b7f11a26660a47746c2edab76eb38722b72


delegate the disassembly of t2ADR to the more generic t2ADDri12/t2SUBri12 \
instructions, and add a test case for that.


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

Changed paths:
 M test/MC/Disassembler/ARM/thumb-tests.txt
 M utils/TableGen/ARMDecoderEmitter.cpp

Modified: test/MC/Disassembler/ARM/thumb-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/thumb-tests.txt
+++ b/test/MC/Disassembler/ARM/thumb-tests.txt
@@ -148,3 +148,6 @@
 
 # CHECK:	ldmia	r5!, {r0, r1, r2, r3, r4}
 0x1f 0xcd
+
+# CHECK:	addw	r0, pc, #1050
+0x0f 0xf2 0x1a 0x40
Modified: utils/TableGen/ARMDecoderEmitter.cpp
===================================================================
--- a/utils/TableGen/ARMDecoderEmitter.cpp
+++ b/utils/TableGen/ARMDecoderEmitter.cpp
@@ -1632,6 +1632,11 @@ ARMDEBackend::populateInstruction(const CodeGenInstruction \
&CGI,  if (Name == "tADR")
       return false;
 
+    // Delegate t2ADR disassembly to the more generic t2ADDri12/t2SUBri12
+    // instructions.
+    if (Name == "t2ADR")
+      return false;
+
     // Ignore tADDrSP, tADDspr, and tPICADD, prefer the generic tADDhirr.
     // Ignore t2SUBrSPs, prefer the t2SUB[S]r[r|s].
     // Ignore t2ADDrSPs, prefer the t2ADD[S]r[r|s].


   Commit: 23a10beecc0346d54de5357ebce859be62b45761
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/24/2011 21:09:48
      URL: https://github.com/mono/llvm/commit/23a10beecc0346d54de5357ebce859be62b45761


Modify the wrong logic in the assert of DisassembleThumb2LdStDual() (the register \
classes were changed), modify the comment to be up-to-date, and add a test case for \
A8.6.66 LDRD (immediate) Encoding T1.


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

Changed paths:
 M lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
 M test/MC/Disassembler/ARM/thumb-tests.txt

Modified: lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
===================================================================
--- a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
+++ b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
@@ -1230,9 +1230,6 @@ static bool DisassembleThumb2LdStEx(MCInst &MI, unsigned \
Opcode, uint32_t insn,  return true;
 }
 
-// LLVM, as of Jan-05-2010, does not output <Rt2>, i.e., Rs, in the asm.
-// Whereas the ARM Arch. Manual does not require that t2 = t+1 like in ARM ISA.
-//
 // t2LDRDi8: Rd Rs Rn imm8s4 (offset mode)
 // t2LDRDpci: Rd Rs imm8s4 (Not decoded, prefer the generic t2LDRDi8 version)
 // t2STRDi8: Rd Rs Rn imm8s4 (offset mode)
@@ -1246,18 +1243,21 @@ static bool DisassembleThumb2LdStDual(MCInst &MI, unsigned \
Opcode,  if (!OpInfo) return false;
 
   assert(NumOps >= 4
-         && OpInfo[0].RegClass == ARM::GPRRegClassID
-         && OpInfo[1].RegClass == ARM::GPRRegClassID
-         && OpInfo[2].RegClass == ARM::GPRRegClassID
+         && OpInfo[0].RegClass > 0
+         && OpInfo[0].RegClass == OpInfo[1].RegClass
+         && OpInfo[2].RegClass > 0
          && OpInfo[3].RegClass < 0
          && "Expect >= 4 operands and first 3 as reg operands");
 
   // Add the <Rt> <Rt2> operands.
-  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+  unsigned RegClassPair = OpInfo[0].RegClass;
+  unsigned RegClassBase = OpInfo[2].RegClass;
+  
+  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassPair,
                                                      decodeRd(insn))));
-  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassPair,
                                                      decodeRs(insn))));
-  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassBase,
                                                      decodeRn(insn))));
 
   // Finally add (+/-)imm8*4, depending on the U bit.
Modified: test/MC/Disassembler/ARM/thumb-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/thumb-tests.txt
+++ b/test/MC/Disassembler/ARM/thumb-tests.txt
@@ -151,3 +151,6 @@
 
 # CHECK:	addw	r0, pc, #1050
 0x0f 0xf2 0x1a 0x40
+
+# CHECK:	ldrd	r3, r8, [r11, #-60]
+0x5b 0xe9 0x0f 0x38


   Commit: 90bebeae6f9c7c865907e1727586ecc73a5ca174
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/24/2011 21:48:18
      URL: https://github.com/mono/llvm/commit/90bebeae6f9c7c865907e1727586ecc73a5ca174


Ignore special ARM allocation hints for unexpected register classes.

Add an assertion to linear scan to prevent it from allocating registers outside
the register class.

<rdar://problem/9183021>

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

Changed paths:
 M lib/CodeGen/RegAllocLinearScan.cpp
 M lib/Target/ARM/ARMBaseRegisterInfo.cpp

Modified: lib/CodeGen/RegAllocLinearScan.cpp
===================================================================
--- a/lib/CodeGen/RegAllocLinearScan.cpp
+++ b/lib/CodeGen/RegAllocLinearScan.cpp
@@ -1110,6 +1110,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* \
cur) {  // list.
   if (physReg) {
     DEBUG(dbgs() <<  tri_->getName(physReg) << '\n');
+    assert(RC->contains(physReg) && "Invalid candidate");
     vrm_->assignVirt2Phys(cur->reg, physReg);
     addRegUse(physReg);
     active_.push_back(std::make_pair(cur, cur->begin()));
Modified: lib/Target/ARM/ARMBaseRegisterInfo.cpp
===================================================================
--- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -448,6 +448,10 @@ ARMBaseRegisterInfo::getAllocationOrder(const \
                TargetRegisterClass *RC,
     ARM::R0, ARM::R2, ARM::R10,ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8
   };
 
+  // We only support even/odd hints for GPR and rGPR.
+  if (RC != ARM::GPRRegisterClass && RC != ARM::rGPRRegisterClass)
+    return std::make_pair(RC->allocation_order_begin(MF),
+                          RC->allocation_order_end(MF));
 
   if (HintType == ARMRI::RegPairEven) {
     if (isPhysicalRegister(HintReg) && getRegisterPairEven(HintReg, MF) == 0)


   Commit: ce53de66045c8432e34396ddba6fc9246433b42f
   Author: Nick Lewycky <nicholas@mxc.ca>
     Date: 03/25/2011 02:04:26
      URL: https://github.com/mono/llvm/commit/ce53de66045c8432e34396ddba6fc9246433b42f


No functionality change. Fix up some whitespace and switch out "" for '' when
printing a single character.


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

Changed paths:
 M lib/CodeGen/RegAllocLinearScan.cpp

Modified: lib/CodeGen/RegAllocLinearScan.cpp
===================================================================
--- a/lib/CodeGen/RegAllocLinearScan.cpp
+++ b/lib/CodeGen/RegAllocLinearScan.cpp
@@ -375,7 +375,7 @@ namespace {
             dbgs() << str << " intervals:\n";
 
           for (; i != e; ++i) {
-            dbgs() << "\t" << *i->first << " -> ";
+            dbgs() << '\t' << *i->first << " -> ";
 
             unsigned reg = i->first->reg;
             if (TargetRegisterInfo::isVirtualRegister(reg))
@@ -390,7 +390,7 @@ namespace {
 }
 
 INITIALIZE_PASS_BEGIN(RALinScan, "linearscan-regalloc",
-                "Linear Scan Register Allocator", false, false)
+                      "Linear Scan Register Allocator", false, false)
 INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
 INITIALIZE_PASS_DEPENDENCY(StrongPHIElimination)
 INITIALIZE_PASS_DEPENDENCY(CalculateSpillWeights)
@@ -401,7 +401,7 @@ INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
 INITIALIZE_AG_DEPENDENCY(RegisterCoalescer)
 INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
 INITIALIZE_PASS_END(RALinScan, "linearscan-regalloc",
-                "Linear Scan Register Allocator", false, false)
+                    "Linear Scan Register Allocator", false, false)
 
 void RALinScan::ComputeRelatedRegClasses() {
   // First pass, add all reg classes to the union, and determine at least one


   Commit: 7ca02c65dc99ba700796e4846d8ad4be614b3f56
   Author: Nick Lewycky <nicholas@mxc.ca>
     Date: 03/25/2011 02:05:50
      URL: https://github.com/mono/llvm/commit/7ca02c65dc99ba700796e4846d8ad4be614b3f56


No functionality change, just adjust some whitespace for coding style compliance.


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

Changed paths:
 M lib/Transforms/IPO/MergeFunctions.cpp

Modified: lib/Transforms/IPO/MergeFunctions.cpp
===================================================================
--- a/lib/Transforms/IPO/MergeFunctions.cpp
+++ b/lib/Transforms/IPO/MergeFunctions.cpp
@@ -125,7 +125,7 @@ private:
 const ComparableFunction ComparableFunction::EmptyKey = ComparableFunction(0);
 const ComparableFunction ComparableFunction::TombstoneKey =
     ComparableFunction(1);
-TargetData * const ComparableFunction::LookupOnly = (TargetData*)(-1);
+TargetData *const ComparableFunction::LookupOnly = (TargetData*)(-1);
 
 }
 
@@ -212,7 +212,7 @@ bool FunctionComparator::isEquivalentType(const Type *Ty1,
     return false;
   }
 
-  switch(Ty1->getTypeID()) {
+  switch (Ty1->getTypeID()) {
   default:
     llvm_unreachable("Unknown type!");
     // Fall through in Release mode.


   Commit: 0e1587474ae60b45453067daa0d6ee02f36e2021
   Author: Andrew Trick <atrick@apple.com>
     Date: 03/25/2011 02:40:55
      URL: https://github.com/mono/llvm/commit/0e1587474ae60b45453067daa0d6ee02f36e2021


Fix for -pre-RA-sched=source.

Yet another case of unchecked NULL node (for physreg copy).
May fix PR9509.


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

Changed paths:
 M lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp

Modified: lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
===================================================================
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -1500,6 +1500,8 @@ public:
   unsigned getNodePriority(const SUnit *SU) const;
 
   unsigned getNodeOrdering(const SUnit *SU) const {
+    if (!SU->getNode()) return 0;
+
     return scheduleDAG->DAG->GetOrdering(SU->getNode());
   }
 


   Commit: c4754a6fab55c937e62371d9523be63783ab9ea2
   Author: Bill Wendling <isanbard@gmail.com>
     Date: 03/25/2011 02:43:59
      URL: https://github.com/mono/llvm/commit/c4754a6fab55c937e62371d9523be63783ab9ea2


Remove redundant compression option.


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

Changed paths:
 M docs/HowToReleaseLLVM.html

Modified: docs/HowToReleaseLLVM.html
===================================================================
--- a/docs/HowToReleaseLLVM.html
+++ b/docs/HowToReleaseLLVM.html
@@ -256,10 +256,10 @@ $ svn export \
https://llvm.org/svn/llvm-project/llvm-gcc-4.2/tags/RELEASE_<i>XY</  $ svn export \
https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_<i>XY</i>/rc1 \
llvm-test-<i>X.Y</i>rc1  $ svn export \
https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_<i>XY</i>/rc1 clang-<i>X.Y</i>rc1  \
                
-$ tar -czvf - llvm-<i>X.Y</i>rc1        | gzip &gt; llvm-<i>X.Y</i>rc1.src.tar.gz
-$ tar -czvf - llvm-test-<i>X.Y</i>rc1   | gzip &gt; \
                llvm-test-<i>X.Y</i>rc1.src.tar.gz
-$ tar -czvf - llvm-gcc4.2-<i>X.Y</i>rc1 | gzip &gt; \
                llvm-gcc-4.2-<i>X.Y</i>rc1.src.tar.gz
-$ tar -czvf - clang-<i>X.Y</i>rc1       | gzip &gt; clang-<i>X.Y</i>rc1.src.tar.gz
+$ tar -cvf - llvm-<i>X.Y</i>rc1        | gzip &gt; llvm-<i>X.Y</i>rc1.src.tar.gz
+$ tar -cvf - llvm-test-<i>X.Y</i>rc1   | gzip &gt; \
llvm-test-<i>X.Y</i>rc1.src.tar.gz +$ tar -cvf - llvm-gcc4.2-<i>X.Y</i>rc1 | gzip \
&gt; llvm-gcc-4.2-<i>X.Y</i>rc1.src.tar.gz +$ tar -cvf - clang-<i>X.Y</i>rc1       | \
gzip &gt; clang-<i>X.Y</i>rc1.src.tar.gz  </pre>
 </div>
 


   Commit: d4ea552d60e5b6555a4b7c68124d46c4e02f1196
   Author: Duncan Sands <baldrick@free.fr>
     Date: 03/25/2011 03:17:44
      URL: https://github.com/mono/llvm/commit/d4ea552d60e5b6555a4b7c68124d46c4e02f1196


Useful script for finding regressions in the nightly testsuite.
I think it was written by Pawel Worach.


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

Added paths:
 A utils/release/findRegressions.py

Added: utils/release/findRegressions.py
===================================================================
--- /dev/null
+++ b/utils/release/findRegressions.py
@@ -0,0 +1,131 @@
+#!/usr/bin/python
+import re, string, sys, os, time
+
+DEBUG = 0
+testDirName = 'llvm-test'
+test      = ['compile', 'llc', 'jit', 'cbe']
+exectime     = ['llc-time', 'jit-time', 'cbe-time',]
+comptime     = ['llc', 'jit-comptime', 'compile']
+
+(tp, exp) = ('compileTime_', 'executeTime_')
+
+def parse(file):
+  f=open(file, 'r')
+  d = f.read()
+  
+  #Cleanup weird stuff
+  d = re.sub(r',\d+:\d','', d)
+   
+  r = re.findall(r'TEST-(PASS|FAIL|RESULT.*?):\s+(.*?)\s+(.*?)\r*\n', d)
+   
+  test = {}
+  fname = ''
+  for t in r:
+    if DEBUG:
+      print t
+    if t[0] == 'PASS' or t[0] == 'FAIL' :
+      tmp = t[2].split(testDirName)
+      
+      if DEBUG:
+        print tmp
+      
+      if len(tmp) == 2:
+        fname = tmp[1].strip('\r\n')
+      else:
+        fname = tmp[0].strip('\r\n')
+      
+      if not test.has_key(fname) :
+        test[fname] = {}
+      
+      for k in test:
+        test[fname][k] = 'NA'
+        test[fname][t[1]] = t[0]
+        if DEBUG:
+          print test[fname][t[1]]
+    else :
+      try:
+        n = t[0].split('RESULT-')[1]
+        
+        if DEBUG:
+          print n;
+        
+        if n == 'llc' or n == 'jit-comptime' or n == 'compile':
+          test[fname][tp + n] = float(t[2].split(' ')[2])
+          if DEBUG:
+            print test[fname][tp + n]
+        
+        elif n.endswith('-time') :
+            test[fname][exp + n] = float(t[2].strip('\r\n'))
+            if DEBUG:
+              print test[fname][exp + n]
+        
+        else :
+          print "ERROR!"
+          sys.exit(1)
+      
+      except:
+          continue
+
+  return test
+
+# Diff results and look for regressions.
+def diffResults(d_old, d_new):
+
+  for t in sorted(d_old.keys()) :
+    if DEBUG:
+      print t
+        
+    if d_new.has_key(t) :
+    
+      # Check if the test passed or failed.
+      for x in test:
+        if d_old[t].has_key(x):
+          if d_new[t].has_key(x):
+            if d_old[t][x] == 'PASS':
+              if d_new[t][x] != 'PASS':
+                print t + " *** REGRESSION (" + x + ")\n"
+            else:
+              if d_new[t][x] == 'PASS':
+                print t + " * NEW PASS (" + x + ")\n"
+                
+          else :
+            print t + "*** REGRESSION (" + x + ")\n"
+        
+        # For execution time, if there is no result, its a fail.
+        for x in exectime:
+          if d_old[t].has_key(tp + x):
+            if not d_new[t].has_key(tp + x):
+              print t + " *** REGRESSION (" + tp + x + ")\n"
+                
+          else :
+            if d_new[t].has_key(tp + x):
+              print t + " * NEW PASS (" + tp + x + ")\n"
+
+       
+        for x in comptime:
+          if d_old[t].has_key(exp + x):
+            if not d_new[t].has_key(exp + x):
+              print t + " *** REGRESSION (" + exp + x + ")\n"
+                
+          else :
+            if d_new[t].has_key(exp + x):
+              print t + " * NEW PASS (" + exp + x + ")\n"
+              
+    else :
+      print t + ": Removed from test-suite.\n"
+    
+
+#Main
+if len(sys.argv) < 3 :
+    print 'Usage:', sys.argv[0], \
+          '<old log> <new log>'
+    sys.exit(-1)
+
+d_old = parse(sys.argv[1])
+d_new = parse(sys.argv[2])
+
+
+diffResults(d_old, d_new)
+
+
+



   Commit: 4f867cd5e77d1e69bd71eec9f7836fceb7fea833
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/25/2011 13:03:12
      URL: https://github.com/mono/llvm/commit/4f867cd5e77d1e69bd71eec9f7836fceb7fea833


Also need to handle invalid imod values for CPS2p.

rdar://problem/9186136


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

Changed paths:
 M lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
Added paths:
 A test/MC/Disassembler/ARM/invalid-CPS2p-arm.txt

Modified: lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
===================================================================
--- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
@@ -2965,8 +2965,10 @@ static bool DisassembleMiscFrm(MCInst &MI, unsigned Opcode, \
uint32_t insn,  // opcodes which match the same real instruction. This is needed \
since there's  // no current handling of optional arguments. Fix here when a better \
handling  // of optional arguments is implemented.
-  if (Opcode == ARM::CPS3p) {
-    // Let's reject impossible imod values by returning false.
+  if (Opcode == ARM::CPS3p) {   // M = 1
+    // Let's reject these impossible imod values by returning false:
+    // 1. (imod=0b01)
+    //
     // AsmPrinter cannot handle imod=0b00, plus (imod=0b00,M=1,iflags!=0) is an
     // invalid combination, so we just check for imod=0b00 here.
     if (slice(insn, 19, 18) == 0 || slice(insn, 19, 18) == 1)
@@ -2977,13 +2979,18 @@ static bool DisassembleMiscFrm(MCInst &MI, unsigned Opcode, \
uint32_t insn,  NumOpsAdded = 3;
     return true;
   }
-  if (Opcode == ARM::CPS2p) {
+  if (Opcode == ARM::CPS2p) { // mode = 0, M = 0
+    // Let's reject these impossible imod values by returning false:
+    // 1. (imod=0b00,M=0)
+    // 2. (imod=0b01)
+    if (slice(insn, 19, 18) == 0 || slice(insn, 19, 18) == 1)
+      return false;
     MI.addOperand(MCOperand::CreateImm(slice(insn, 19, 18))); // imod
     MI.addOperand(MCOperand::CreateImm(slice(insn, 8, 6)));   // iflags
     NumOpsAdded = 2;
     return true;
   }
-  if (Opcode == ARM::CPS1p) {
+  if (Opcode == ARM::CPS1p) { // imod = 0, iflags = 0, M = 1
     MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0))); // mode
     NumOpsAdded = 1;
     return true;

Added: test/MC/Disassembler/ARM/invalid-CPS2p-arm.txt
===================================================================
--- /dev/null
+++ b/test/MC/Disassembler/ARM/invalid-CPS2p-arm.txt
@@ -0,0 +1,5 @@
+# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid \
instruction encoding} +
+# invalid imod value (0b01)
+0xc0 0x67 0x4 0xf1
+



   Commit: 81b750795e26a6784a606317200c08d507afb49a
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/25/2011 13:20:59
      URL: https://github.com/mono/llvm/commit/81b750795e26a6784a606317200c08d507afb49a


Emit less labels for debug info and stop emitting .loc directives for DBG_VALUEs.

The .dot directives don't need labels, that is a leftover from when we created
line number info manually.

Instructions following a DBG_VALUE can share its label since the DBG_VALUE
doesn't produce any code.

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

Changed paths:
 M lib/CodeGen/AsmPrinter/DwarfDebug.cpp
 M lib/CodeGen/AsmPrinter/DwarfDebug.h
 M test/CodeGen/X86/2010-05-26-DotDebugLoc.ll
 M test/CodeGen/X86/dbg-value-range.ll
 M test/CodeGen/X86/unknown-location.ll

Modified: lib/CodeGen/AsmPrinter/DwarfDebug.cpp
===================================================================
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -2538,47 +2538,46 @@ const MCSymbol *DwarfDebug::getLabelAfterInsn(const \
MachineInstr *MI) {  
 /// beginInstruction - Process beginning of an instruction.
 void DwarfDebug::beginInstruction(const MachineInstr *MI) {
-  if (InsnNeedsLabel.count(MI) == 0) {
-    LabelsBeforeInsn[MI] = PrevLabel;
-    return;
+  // Check if source location changes, but ignore DBG_VALUE locations.
+  if (!MI->isDebugValue()) {
+    DebugLoc DL = MI->getDebugLoc();
+    if (DL != PrevInstLoc && (!DL.isUnknown() || UnknownLocations)) {
+      PrevInstLoc = DL;
+      if (!DL.isUnknown()) {
+        const MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext());
+        recordSourceLine(DL.getLine(), DL.getCol(), Scope);
+      } else
+        recordSourceLine(0, 0, 0);
+    }
   }
 
-  // Check location.
-  DebugLoc DL = MI->getDebugLoc();
-  if (!DL.isUnknown()) {
-    const MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext());
-    PrevLabel = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
-    PrevInstLoc = DL;
-    LabelsBeforeInsn[MI] = PrevLabel;
+  // Insert labels where requested.
+  if (!InsnNeedsLabel.count(MI))
     return;
-  }
 
-  // If location is unknown then use temp label for this DBG_VALUE
-  // instruction.
-  if (MI->isDebugValue()) {
+  if (!PrevLabel) {
     PrevLabel = MMI->getContext().CreateTempSymbol();
     Asm->OutStreamer.EmitLabel(PrevLabel);
-    LabelsBeforeInsn[MI] = PrevLabel;
-    return;
   }
-
-  if (UnknownLocations) {
-    PrevLabel = recordSourceLine(0, 0, 0);
-    LabelsBeforeInsn[MI] = PrevLabel;
-    return;
-  }
-
-  assert (0 && "Instruction is not processed!");
+  LabelsBeforeInsn[MI] = PrevLabel;
 }
 
 /// endInstruction - Process end of an instruction.
 void DwarfDebug::endInstruction(const MachineInstr *MI) {
-  if (InsnsNeedsLabelAfter.count(MI) != 0) {
-    // Emit a label if this instruction ends a scope.
-    MCSymbol *Label = MMI->getContext().CreateTempSymbol();
-    Asm->OutStreamer.EmitLabel(Label);
-    LabelsAfterInsn[MI] = Label;
+  // Don't create a new label after DBG_VALUE instructions.
+  // They don't generate code.
+  if (!MI->isDebugValue())
+    PrevLabel = 0;
+
+  if (!InsnsNeedsLabelAfter.count(MI))
+    return;
+
+  // We need a label after this instruction.
+  if (!PrevLabel) {
+    PrevLabel = MMI->getContext().CreateTempSymbol();
+    Asm->OutStreamer.EmitLabel(PrevLabel);
   }
+  LabelsAfterInsn[MI] = PrevLabel;
 }
 
 /// getOrCreateDbgScope - Create DbgScope for the scope.
@@ -2838,6 +2837,7 @@ void DwarfDebug::identifyScopeMarkers() {
            RE = Ranges.end(); RI != RE; ++RI) {
       assert(RI->first && "DbgRange does not have first instruction!");
       assert(RI->second && "DbgRange does not have second instruction!");
+      InsnNeedsLabel.insert(RI->first);
       InsnsNeedsLabelAfter.insert(RI->second);
     }
   }
@@ -2927,7 +2927,6 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
   /// LiveUserVar - Map physreg numbers to the MDNode they contain.
   std::vector<const MDNode*> LiveUserVar(TRI->getNumRegs());
 
-  DebugLoc PrevLoc;
   for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
        I != E; ++I)
     for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
@@ -2957,15 +2956,6 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
         else if (!ProcessedArgs.insert(DV))
           InsnNeedsLabel.insert(MI);
       } else {
-        // If location is unknown then instruction needs a location only if
-        // UnknownLocations flag is set.
-        if (DL.isUnknown()) {
-          if (UnknownLocations && !PrevLoc.isUnknown())
-            InsnNeedsLabel.insert(MI);
-        } else if (DL != PrevLoc)
-          // Otherwise, instruction needs a location only if it is new location.
-          InsnNeedsLabel.insert(MI);
-
         // Check if the instruction clobbers any registers with debug vars.
         for (MachineInstr::const_mop_iterator MOI = MI->operands_begin(),
                MOE = MI->operands_end(); MOI != MOE; ++MOI) {
@@ -2992,11 +2982,9 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
           }
         }
       }
-
-      if (!DL.isUnknown() || UnknownLocations)
-        PrevLoc = DL;
     }
 
+  PrevInstLoc = DebugLoc();
   PrevLabel = FunctionBeginSym;
 }
 
@@ -3112,8 +3100,7 @@ DbgScope *DwarfDebug::findDbgScope(const MachineInstr *MInsn) {
 /// recordSourceLine - Register a source line with debug info. Returns the
 /// unique label that was emitted and which provides correspondence to
 /// the source line list.
-MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col,
-                                       const MDNode *S) {
+void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S){
   StringRef Fn;
   StringRef Dir;
   unsigned Src = 1;
@@ -3144,10 +3131,6 @@ MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned \
Col,  
   Asm->OutStreamer.EmitDwarfLocDirective(Src, Line, Col, DWARF2_FLAG_IS_STMT,
                                          0, 0);
-
-  MCSymbol *Label = MMI->getContext().CreateTempSymbol();
-  Asm->OutStreamer.EmitLabel(Label);
-  return Label;
 }
 
 //===----------------------------------------------------------------------===//
Modified: lib/CodeGen/AsmPrinter/DwarfDebug.h
===================================================================
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -536,7 +536,7 @@ private:
   /// recordSourceLine - Register a source line with debug info. Returns the
   /// unique label that was emitted and which provides correspondence to
   /// the source line list.
-  MCSymbol *recordSourceLine(unsigned Line, unsigned Col, const MDNode *Scope);
+  void recordSourceLine(unsigned Line, unsigned Col, const MDNode *Scope);
   
   /// recordVariableFrameIndex - Record a variable's index.
   void recordVariableFrameIndex(const DbgVariable *V, int Index);
Modified: test/CodeGen/X86/2010-05-26-DotDebugLoc.ll
===================================================================
--- a/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll
+++ b/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll
@@ -55,12 +55,21 @@ declare void @llvm.dbg.value(metadata, i64, metadata) nounwind \
                readnone
 !29 = metadata !{i32 524299, metadata !9, i32 17, i32 0} ; [ DW_TAG_lexical_block ]
 !30 = metadata !{i32 19, i32 0, metadata !29, null}
 
+; The variable bar:myvar changes registers after the first movq.
+; It is cobbered by popq %rbx
+; CHECK: movq
+; CHECK-NEXT: [[LABEL:Ltmp[0-9]*]]
+; CHECK: .loc	1 19 0
+; CHECK: popq
+; CHECK-NEXT: [[CLOBBER:Ltmp[0-9]*]]
+
+
 ; CHECK: Ldebug_loc0:
 ; CHECK-NEXT: .quad   Lfunc_begin0
-; CHECK-NEXT: .quad   Ltmp3
+; CHECK-NEXT: .quad   [[LABEL]]
 ; CHECK-NEXT: .short  1
 ; CHECK-NEXT: .byte   85
-; CHECK-NEXT: .quad   Ltmp3
-; CHECK-NEXT: .quad   Ltmp6
+; CHECK-NEXT: .quad   [[LABEL]]
+; CHECK-NEXT: .quad   [[CLOBBER]]
 ; CHECK-NEXT: .short  1
 ; CHECK-NEXT: .byte   83
Modified: test/CodeGen/X86/dbg-value-range.ll
===================================================================
--- a/test/CodeGen/X86/dbg-value-range.ll
+++ b/test/CodeGen/X86/dbg-value-range.ll
@@ -45,13 +45,13 @@ declare void @llvm.dbg.value(metadata, i64, metadata) nounwind \
readnone  ; The variable is in %rdi which is clobbered by 'movl %ebx, %edi'
 ; Here Ltmp7 is the end of the location range.
 
-;CHECK:Ltmp6
-;CHECK-NEXT: movl
-;CHECK-NEXT: Ltmp7
+;CHECK: .loc	1 7 2
+;CHECK: movl
+;CHECK-NEXT: [[CLOBBER:Ltmp[0-9]*]]
 
 ;CHECK:Ldebug_loc0:
-;CHECK-NEXT:	.quad	Ltmp
-;CHECK-NEXT:	.quad	Ltmp7
+;CHECK-NEXT:	.quad
+;CHECK-NEXT:	.quad	[[CLOBBER]]
 ;CHECK-NEXT:	.short	1
 ;CHECK-NEXT:	.byte	85
 ;CHECK-NEXT:	.quad	0
Modified: test/CodeGen/X86/unknown-location.ll
===================================================================
--- a/test/CodeGen/X86/unknown-location.ll
+++ b/test/CodeGen/X86/unknown-location.ll
@@ -4,16 +4,11 @@
 ; represent this in the debug information. This is done by setting line
 ; and column to 0
 
-;      CHECK:         leal    (%rdi,%rsi), %eax
+;      CHECK:         leal
 ; CHECK-NEXT:         .loc 1 0 0
-; CHECK-NEXT: Ltmp
-; CHECK-NEXT:         cltd
-; CHECK-NEXT:         idivl   %r8d
+;      CHECK:         cltd
+; CHECK-NEXT:         idivl
 ; CHECK-NEXT:         .loc 2 4 3
-; CHECK-NEXT: Ltmp
-; CHECK-NEXT:         addl    %ecx, %eax
-; CHECK-NEXT:         ret
-; CHECK-NEXT: Ltmp
 
 define i32 @foo(i32 %w, i32 %x, i32 %y, i32 %z) nounwind {
 entry:


   Commit: 44343e7702eabd8aa8adfa38ac44e1fec473e2cf
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/25/2011 13:31:16
      URL: https://github.com/mono/llvm/commit/44343e7702eabd8aa8adfa38ac44e1fec473e2cf


Instruction formats of SWP/SWPB were changed from LdStExFrm to MiscFrm.  Modify the \
disassembler to handle that.

rdar://problem/9184053


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

Changed paths:
 M lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
 M test/MC/Disassembler/ARM/arm-tests.txt

Modified: lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
===================================================================
--- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
@@ -2951,6 +2951,11 @@ static bool DisassembleMiscFrm(MCInst &MI, unsigned Opcode, \
uint32_t insn,  case ARM::WFI:
   case ARM::SEV:
     return true;
+  case ARM::SWP:
+  case ARM::SWPB:
+    // SWP, SWPB: Rd Rm Rn
+    // Delegate to DisassembleLdStExFrm()....
+    return DisassembleLdStExFrm(MI, Opcode, insn, NumOps, NumOpsAdded, B);
   default:
     break;
   }
Modified: test/MC/Disassembler/ARM/arm-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/arm-tests.txt
+++ b/test/MC/Disassembler/ARM/arm-tests.txt
@@ -184,3 +184,6 @@
 
 # CHECK:	ldmdb	sp, {r0, r4, r8, r11, r12, pc}
 0x11 0x99 0x1d 0xe9
+
+# CHECK:	swpge	r3, r2, [r6]
+0x92 0x30 0x06 0xa1


   Commit: 63ef8fb752bb373a0e1e5f9a382a8692f85f3daf
   Author: Benjamin Kramer <benny.kra@googlemail.com>
     Date: 03/25/2011 13:32:40
      URL: https://github.com/mono/llvm/commit/63ef8fb752bb373a0e1e5f9a382a8692f85f3daf


Add a note.

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

Changed paths:
 M lib/Target/README.txt

Modified: lib/Target/README.txt
===================================================================
--- a/lib/Target/README.txt
+++ b/lib/Target/README.txt
@@ -2238,4 +2238,23 @@ missed cases:
 
 //===---------------------------------------------------------------------===//
 
+define i1 @test1(i32 %x) nounwind {
+  %and = and i32 %x, 3
+  %cmp = icmp ult i32 %and, 2
+  ret i1 %cmp
+}
+
+Can be folded to (x & 2) == 0.
+
+define i1 @test2(i32 %x) nounwind {
+  %and = and i32 %x, 3
+  %cmp = icmp ugt i32 %and, 1
+  ret i1 %cmp
+}
 
+Can be folded to (x & 2) != 0.
+
+SimplifyDemandedBits shrinks the "and" constant to 2 but instcombine misses the
+icmp transform.
+
+//===---------------------------------------------------------------------===//


   Commit: 5ce961a587d3c3fd10becd5e771ab938cc8210cf
   Author: Daniel Dunbar <daniel@zuster.org>
     Date: 03/25/2011 13:47:14
      URL: https://github.com/mono/llvm/commit/5ce961a587d3c3fd10becd5e771ab938cc8210cf


Tidyness.

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

Changed paths:
 M lib/MC/MCParser/AsmParser.cpp

Modified: lib/MC/MCParser/AsmParser.cpp
===================================================================
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -880,6 +880,7 @@ bool AsmParser::ParseStatement() {
     EatToEndOfStatement();
     return false;
   }
+
   // Allow an integer followed by a ':' as a directional local label.
   if (Lexer.is(AsmToken::Integer)) {
     LocalLabelVal = getTok().getIntVal();
@@ -896,8 +897,7 @@ bool AsmParser::ParseStatement() {
           return TokError("unexpected token at start of statement");
       }
     }
-  }
-  else if (ParseIdentifier(IDVal)) {
+  } else if (ParseIdentifier(IDVal)) {
     if (!TheCondState.Ignore)
       return TokError("unexpected token at start of statement");
     IDVal = "";


   Commit: c2d1546d62fca01da2f191733813d9dd37ac1263
   Author: Daniel Dunbar <daniel@zuster.org>
     Date: 03/25/2011 13:47:17
      URL: https://github.com/mono/llvm/commit/c2d1546d62fca01da2f191733813d9dd37ac1263


MC: Improve some diagnostics on uses of '.' pseudo-symbol.

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

Changed paths:
 M lib/MC/MCParser/AsmParser.cpp
Added paths:
 A test/MC/AsmParser/dot-symbol.s

Modified: lib/MC/MCParser/AsmParser.cpp
===================================================================
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -897,12 +897,19 @@ bool AsmParser::ParseStatement() {
           return TokError("unexpected token at start of statement");
       }
     }
+
+  } else if (Lexer.is(AsmToken::Dot)) {
+    // Treat '.' as a valid identifier in this context.
+    Lex();
+    IDVal = ".";
+
   } else if (ParseIdentifier(IDVal)) {
     if (!TheCondState.Ignore)
       return TokError("unexpected token at start of statement");
     IDVal = "";
   }
 
+
   // Handle conditional assembly here before checking for skipping.  We
   // have to do this so that .endif isn't skipped in a ".if 0" block for
   // example.
@@ -935,6 +942,10 @@ bool AsmParser::ParseStatement() {
     // identifier ':'   -> Label.
     Lex();
 
+    // Diagnose attempt to use '.' as a label.
+    if (IDVal == ".")
+      return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label");
+
     // Diagnose attempt to use a variable as a label.
     //
     // FIXME: Diagnostics. Note the location of the definition as a label.
@@ -978,7 +989,7 @@ bool AsmParser::ParseStatement() {
       return HandleMacroEntry(IDVal, IDLoc, M);
 
   // Otherwise, we have a normal instruction or directive.
-  if (IDVal[0] == '.') {
+  if (IDVal[0] == '.' && IDVal != ".") {
     // Assembler features
     if (IDVal == ".set" || IDVal == ".equ")
       return ParseDirectiveSet(IDVal, true);
@@ -1306,6 +1317,12 @@ bool AsmParser::ParseAssignment(StringRef Name, bool \
allow_redef) {  if (Lexer.isNot(AsmToken::EndOfStatement))
     return TokError("unexpected token in assignment");
 
+  // Error on assignment to '.'.
+  if (Name == ".") {
+    return Error(EqualLoc, ("assignment to pseudo-symbol '.' is unsupported "
+                            "(use '.space' or '.org').)"));
+  }
+
   // Eat the end of statement marker.
   Lex();
 

Added: test/MC/AsmParser/dot-symbol.s
===================================================================
--- /dev/null
+++ b/test/MC/AsmParser/dot-symbol.s
@@ -0,0 +1,13 @@
+# Historically 'as' treats '.' as a reference to the current location in
+# arbitrary contects. We don't support this in general.
+
+# RUN: not llvm-mc -triple i386-unknown-unknown %s 2> %t
+# RUN: FileCheck -input-file %t %s
+
+# CHECK: assignment to pseudo-symbol '.' is unsupported (use '.space' or '.org').
+. = . + 8
+
+# CHECK: invalid use of pseudo-symbol '.' as a label
+.:
+        .long 0
+



   Commit: 511b5f152fb622527fb681c99f8cfb1276a26a18
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/25/2011 14:29:49
      URL: https://github.com/mono/llvm/commit/511b5f152fb622527fb681c99f8cfb1276a26a18


Modify DisassembleThumb2LdStEx() to be more robust/correct in light of recent change \
to t2LDREX/t2STREX instructions.  Add two test cases.


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

Changed paths:
 M lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
 M test/MC/Disassembler/ARM/thumb-tests.txt

Modified: lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
===================================================================
--- a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
+++ b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
@@ -1194,8 +1194,8 @@ static bool DisassembleThumb2LdStEx(MCInst &MI, unsigned \
Opcode, uint32_t insn,  OpIdx = 0;
 
   assert(NumOps >= 2
-         && OpInfo[0].RegClass == ARM::GPRRegClassID
-         && OpInfo[1].RegClass == ARM::GPRRegClassID
+         && OpInfo[0].RegClass > 0
+         && OpInfo[1].RegClass > 0
          && "Expect >=2 operands and first two as reg operands");
 
   bool isStore = (ARM::t2STREX <= Opcode && Opcode <= ARM::t2STREXH);
@@ -1205,25 +1205,25 @@ static bool DisassembleThumb2LdStEx(MCInst &MI, unsigned \
Opcode, uint32_t insn,  // Add the destination operand for store.
   if (isStore) {
     MI.addOperand(MCOperand::CreateReg(
-                    getRegisterEnum(B, ARM::GPRRegClassID,
+                    getRegisterEnum(B, OpInfo[OpIdx].RegClass,
                                     isSW ? decodeRs(insn) : decodeRm(insn))));
     ++OpIdx;
   }
 
   // Source operand for store and destination operand for load.
-  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
                                                      decodeRd(insn))));
   ++OpIdx;
 
   // Thumb2 doubleword complication: with an extra source/destination operand.
   if (isDW) {
-    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
                                                        decodeRs(insn))));
     ++OpIdx;
   }
 
   // Finally add the pointer operand.
-  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
                                                      decodeRn(insn))));
   ++OpIdx;
 
Modified: test/MC/Disassembler/ARM/thumb-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/thumb-tests.txt
+++ b/test/MC/Disassembler/ARM/thumb-tests.txt
@@ -154,3 +154,9 @@
 
 # CHECK:	ldrd	r3, r8, [r11, #-60]
 0x5b 0xe9 0x0f 0x38
+
+# CHECK:	ldrex	r8, [r2]
+0x52 0xe8 0x00 0x8f
+
+# CHECK:	strexd	r1, r7, r8, [r2]
+0xc2 0xe8 0x71 0x78


   Commit: 1dc7472e2a3d487cf841db6671794db4bf2d31ca
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/25/2011 14:40:21
      URL: https://github.com/mono/llvm/commit/1dc7472e2a3d487cf841db6671794db4bf2d31ca


A8.6.226 TBB, TBH:

Add two test cases.


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

Changed paths:
 M test/MC/Disassembler/ARM/thumb-tests.txt

Modified: test/MC/Disassembler/ARM/thumb-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/thumb-tests.txt
+++ b/test/MC/Disassembler/ARM/thumb-tests.txt
@@ -160,3 +160,9 @@
 
 # CHECK:	strexd	r1, r7, r8, [r2]
 0xc2 0xe8 0x71 0x78
+
+# CHECK:	tbh	[r5, r4, lsl #1]
+0xd5 0xe8 0x14 0xf0
+
+# CHECK:	tbb	[r5, r4]
+0xd5 0xe8 0x04 0xf0


   Commit: 34f2801c899086d6cabe83e0b0549e2a5aaaffaa
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/25/2011 15:35:37
      URL: https://github.com/mono/llvm/commit/34f2801c899086d6cabe83e0b0549e2a5aaaffaa


DisassembleThumb2LdSt() did not handle t2LDRs correctly with respect to RegClass.  \
Add two test cases.

rdar://problem/9182892


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

Changed paths:
 M lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
 M test/MC/Disassembler/ARM/thumb-tests.txt

Modified: lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
===================================================================
--- a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
+++ b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
@@ -1868,7 +1868,7 @@ static bool DisassembleThumb2LdSt(bool Load, MCInst &MI, \
unsigned Opcode,  OpInfo[1].RegClass == ARM::GPRRegClassID &&
          "Expect >= 3 operands and first two as reg operands");
 
-  bool ThreeReg = (OpInfo[2].RegClass == ARM::GPRRegClassID);
+  bool ThreeReg = (OpInfo[2].RegClass > 0);
   bool TIED_TO = ThreeReg && TID.getOperandConstraint(2, TOI::TIED_TO) != -1;
   bool Imm12 = !ThreeReg && slice(insn, 23, 23) == 1; // ARMInstrThumb2.td
 
@@ -1912,7 +1912,8 @@ static bool DisassembleThumb2LdSt(bool Load, MCInst &MI, \
unsigned Opcode,  ++OpIdx;
 
   if (ThreeReg) {
-    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+    // This could be an offset register or a TIED_TO register.
+    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
                                                        R2)));
     ++OpIdx;
   }
Modified: test/MC/Disassembler/ARM/thumb-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/thumb-tests.txt
+++ b/test/MC/Disassembler/ARM/thumb-tests.txt
@@ -166,3 +166,9 @@
 
 # CHECK:	tbb	[r5, r4]
 0xd5 0xe8 0x04 0xf0
+
+# CHECK:	ldr.w	r4, [sp, r4, lsl #3]
+0x5d 0xf8 0x34 0x40
+
+# CHECK:	ldr.w	r5, [r6, #30]
+0x56 0xf8 0x1e 0x56


   Commit: 741743bcd4d9d785a1bcf2d03076e81a19c8d5c8
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/25/2011 18:19:07
      URL: https://github.com/mono/llvm/commit/741743bcd4d9d785a1bcf2d03076e81a19c8d5c8


Fix DisassembleThumb2DPReg()'s handling of RegClass.  Cannot hardcode GPRRegClassID.
Also add some test cases.

rdar://problem/9189829


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

Changed paths:
 M lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
 M test/MC/Disassembler/ARM/thumb-tests.txt

Modified: lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
===================================================================
--- a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
+++ b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
@@ -1947,25 +1947,25 @@ static bool DisassembleThumb2DPReg(MCInst &MI, unsigned \
Opcode, uint32_t insn,  OpIdx = 0;
 
   assert(NumOps >= 2 &&
-         OpInfo[0].RegClass == ARM::rGPRRegClassID &&
-         OpInfo[1].RegClass == ARM::rGPRRegClassID &&
+         OpInfo[0].RegClass > 0 &&
+         OpInfo[1].RegClass > 0 &&
          "Expect >= 2 operands and first two as reg operands");
 
   // Build the register operands, followed by the optional rotation amount.
 
-  bool ThreeReg = NumOps > 2 && OpInfo[2].RegClass == ARM::rGPRRegClassID;
+  bool ThreeReg = NumOps > 2 && OpInfo[2].RegClass > 0;
 
-  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
+  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
                                                      decodeRs(insn))));
   ++OpIdx;
 
   if (ThreeReg) {
-    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
+    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
                                                        decodeRn(insn))));
     ++OpIdx;
   }
 
-  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
+  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
                                                      decodeRm(insn))));
   ++OpIdx;
 
Modified: test/MC/Disassembler/ARM/thumb-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/thumb-tests.txt
+++ b/test/MC/Disassembler/ARM/thumb-tests.txt
@@ -172,3 +172,12 @@
 
 # CHECK:	ldr.w	r5, [r6, #30]
 0x56 0xf8 0x1e 0x56
+
+# CHECK:	sel	r7, r3, r5
+0xa3 0xfa 0x85 0xf7
+
+# CHECK:	lsl.w	r7, r3, r5
+0x03 0xfa 0x05 0xf7
+
+# CHECK:	adds.w	r7, r3, r5
+0x13 0xeb 0x05 0x07


   Commit: ffb44517a2f839a15c41117e548f89bc69a6b2a5
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/25/2011 18:43:28
      URL: https://github.com/mono/llvm/commit/ffb44517a2f839a15c41117e548f89bc69a6b2a5


Add two test cases t2SMLABT and t2SMMULR for DisassembleThumb2Mul().


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

Changed paths:
 M test/MC/Disassembler/ARM/thumb-tests.txt

Modified: test/MC/Disassembler/ARM/thumb-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/thumb-tests.txt
+++ b/test/MC/Disassembler/ARM/thumb-tests.txt
@@ -181,3 +181,9 @@
 
 # CHECK:	adds.w	r7, r3, r5
 0x13 0xeb 0x05 0x07
+
+# CHECK:	smlabt	r4, r3, r2, r1
+0x13 0xfb 0x12 0x14
+
+# CHECK:	smmulr	r7, r8, r9
+0x58 0xfb 0x19 0xf7


   Commit: 2fdf0bd336005c7db93ae08e4df14e307c5cf182
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/25/2011 19:02:58
      URL: https://github.com/mono/llvm/commit/2fdf0bd336005c7db93ae08e4df14e307c5cf182


Add test for A8.6.246 UMULL to both arm-tests.txt amd thumb-tests.txt.


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

Changed paths:
 M test/MC/Disassembler/ARM/arm-tests.txt
 M test/MC/Disassembler/ARM/thumb-tests.txt

Modified: test/MC/Disassembler/ARM/arm-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/arm-tests.txt
+++ b/test/MC/Disassembler/ARM/arm-tests.txt
@@ -187,3 +187,6 @@
 
 # CHECK:	swpge	r3, r2, [r6]
 0x92 0x30 0x06 0xa1
+
+# CHECK:	umull	r1, r2, r3, r4
+0x93 0x14 0x82 0xe0
Modified: test/MC/Disassembler/ARM/thumb-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/thumb-tests.txt
+++ b/test/MC/Disassembler/ARM/thumb-tests.txt
@@ -187,3 +187,6 @@
 
 # CHECK:	smmulr	r7, r8, r9
 0x58 0xfb 0x19 0xf7
+
+# CHECK:	umull	r1, r2, r3, r4
+0xa3 0xfb 0x04 0x12


   Commit: 747f8bcf76af4b79e374e08ae978b745b112cde4
   Author: Kevin Enderby <enderby@apple.com>
     Date: 03/25/2011 20:06:33
      URL: https://github.com/mono/llvm/commit/747f8bcf76af4b79e374e08ae978b745b112cde4


Adding a C API to the disassembler for use by such tools as Darwin's otool(1).
This is a work in progress as the interface for producing symbolic operands is
not done.  But a hacked prototype using information from the object file's
relocation entiries and replacing immediate operands with MCExpr's has been
shown to work with no changes to the instrucion printer.  These APIs will be
moved into a dynamic library at some point.


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

Added paths:
 A include/llvm-c/Disassembler.h
 A lib/MC/MCDisassembler/Disassembler.cpp
 A lib/MC/MCDisassembler/Disassembler.h

Added: include/llvm-c/Disassembler.h
===================================================================
--- /dev/null
+++ b/include/llvm-c/Disassembler.h
@@ -0,0 +1,107 @@
+/*===-- llvm-c/Disassembler.h - Disassembler Public C Interface ---*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides public interface to a disassembler library.           *|
+|* LLVM provides an implementation of this interface.                         *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_DISASSEMBLER_H
+#define LLVM_C_DISASSEMBLER_H  1
+
+#include <stdint.h>
+#include <stddef.h>
+
+/**
+ * An opaque reference to a disassembler context.
+ */
+typedef void *LLVMDisasmContextRef;
+
+/**
+ * The type for the operand information call back function.  This is called to
+ * get the symbolic information for an operand of an instruction.  Typically
+ * this is from the relocation information, symbol table, etc.  That block of
+ * information is saved when the disassembler context is created and passed to
+ * the call back in the DisInfo parameter.  The instruction containing operand
+ * is at the PC parameter.  For some instruction sets, there can be more than
+ * one operand with symbolic information.  To determine the symbolic operand
+ * infomation for each operand, the bytes for the specific operand in the
+ * instruction are specified by the Offset parameter and its byte widith is the
+ * size parameter.  For instructions sets with fixed widths and one symbolic
+ * operand per instruction, the Offset parameter will be zero and Size parameter
+ * will be the instruction width.  The information is returned in TagBuf and is 
+ * Triple specific with its specific information defined by the value of
+ * TagType for that Triple.  If symbolic information is returned the function
+ * returns 1 else it returns 0.
+ */
+typedef int (*LLVMOpInfoCallback)(void *DisInfo,
+                                  uint64_t PC,
+                                  uint64_t Offset,
+                                  uint64_t Size,
+                                  int TagType,
+                                  void *TagBuf);
+
+/**
+ * The type for the symbol lookup function.  This may be called by the
+ * disassembler for such things like adding a comment for a PC plus a constant
+ * offset load instruction to use a symbol name instead of a load address value.
+ * It is passed the block information is saved when the disassembler context is
+ * created and a value of a symbol to look up.  If no symbol is found NULL is
+ * to be returned.
+ */
+typedef const char *(*LLVMSymbolLookupCallback)(void *DisInfo,
+                                                uint64_t SymbolValue);
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* !defined(__cplusplus) */
+
+/**
+ * Create a disassembler for the TripleName.  Symbolic disassembly is supported
+ * by passing a block of information in the DisInfo parameter and specifing the
+ * TagType and call back functions as described above.  These can all be passed
+ * as NULL.  If successfull this returns a disassembler context if not it
+ * returns NULL.
+ */
+extern LLVMDisasmContextRef
+LLVMCreateDisasm(const char *TripleName,
+                 void *DisInfo,
+                 int TagType,
+                 LLVMOpInfoCallback GetOpInfo,
+                 LLVMSymbolLookupCallback SymbolLookUp);
+
+/**
+ * Dispose of a disassembler context.
+ */
+extern void
+LLVMDisasmDispose(LLVMDisasmContextRef DC);
+
+/**
+ * Disassmble a single instruction using the disassembler context specified in
+ * the parameter DC.  The bytes of the instuction are specified in the parameter
+ * Bytes, and contains at least BytesSize number of bytes.  The instruction is
+ * at the address specified by the PC parameter.  If a valid instruction can be
+ * disassembled its string is returned indirectly in OutString which whos size
+ * is specified in the parameter OutStringSize.  This function returns the
+ * number of bytes in the instruction or zero if there was no valid instruction.
+ */
+extern size_t
+LLVMDisasmInstruction(LLVMDisasmContextRef DC,
+                      uint8_t *Bytes,
+                      uint64_t BytesSize,
+                      uint64_t PC,
+                      char *OutString,
+                      size_t OutStringSize);
+
+#ifdef __cplusplus
+}
+#endif /* !defined(__cplusplus) */
+
+#endif /* !defined(LLVM_C_DISASSEMBLER_H) */
+

Added: lib/MC/MCDisassembler/Disassembler.cpp
===================================================================
--- /dev/null
+++ b/lib/MC/MCDisassembler/Disassembler.cpp
@@ -0,0 +1,170 @@
+//===-- lib/MC/Disassembler.cpp - Disassembler Public C Interface -*- C -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "Disassembler.h"
+#include <stdio.h>
+#include "llvm-c/Disassembler.h"
+
+#include <string>
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/Target/TargetRegistry.h"
+#include "llvm/Target/TargetAsmInfo.h"  // FIXME.
+#include "llvm/Target/TargetMachine.h"  // FIXME.
+#include "llvm/Target/targetSelect.h"
+#include "llvm/Support/MemoryObject.h"
+
+namespace llvm {
+class Target;
+} // namespace llvm
+using namespace llvm;
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+//
+// LLVMCreateDisasm() creates a disassembler for the TripleName.  Symbolic
+// disassembly is supported by passing a block of information in the DisInfo
+// parameter and specifing the TagType and call back functions as described in
+// the header llvm-c/Disassembler.h .  The pointer to the block and the 
+// functions can all be passed as NULL.  If successfull this returns a
+// disassembler context if not it returns NULL.
+//
+LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo,
+                                      int TagType, LLVMOpInfoCallback GetOpInfo,
+                                      LLVMSymbolLookupCallback SymbolLookUp) {
+  // Initialize targets and assembly printers/parsers.
+  llvm::InitializeAllTargetInfos();
+  // FIXME: We shouldn't need to initialize the Target(Machine)s.
+  llvm::InitializeAllTargets();
+  llvm::InitializeAllAsmPrinters();
+  llvm::InitializeAllAsmParsers();
+  llvm::InitializeAllDisassemblers();
+
+  // Get the target.
+  std::string Error;
+  const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
+  assert(TheTarget && "Unable to create target!");
+
+  // Get the assembler info needed to setup the MCContext.
+  const MCAsmInfo *MAI = TheTarget->createAsmInfo(TripleName);
+  assert(MAI && "Unable to create target asm info!");
+
+  // Package up features to be passed to target/subtarget
+  std::string FeaturesStr;
+
+  // FIXME: We shouldn't need to do this (and link in codegen).
+  //        When we split this out, we should do it in a way that makes
+  //        it straightforward to switch subtargets on the fly.
+  TargetMachine *TM = TheTarget->createTargetMachine(TripleName, FeaturesStr);
+  assert(TM && "Unable to create target machine!");
+
+  // Get the target assembler info needed to setup the context.
+  const TargetAsmInfo *tai = new TargetAsmInfo(*TM);
+  assert(tai && "Unable to create target assembler!");
+
+  // Set up the MCContext for creating symbols and MCExpr's.
+  MCContext *Ctx = new MCContext(*MAI, tai);
+  assert(Ctx && "Unable to create MCContext!");
+
+  // Set up disassembler.
+  const MCDisassembler *DisAsm = TheTarget->createMCDisassembler();
+  assert(DisAsm && "Unable to create disassembler!");
+
+  // Set up the instruction printer.
+  int AsmPrinterVariant = MAI->getAssemblerDialect();
+  MCInstPrinter *IP = TheTarget->createMCInstPrinter(*TM, AsmPrinterVariant,
+                                                     *MAI);
+  assert(IP && "Unable to create instruction printer!");
+
+  LLVMDisasmContext *DC = new LLVMDisasmContext(TripleName, DisInfo, TagType,
+                                                GetOpInfo, SymbolLookUp,
+                                                TheTarget, MAI, TM, tai, Ctx,
+                                                DisAsm, IP);
+  assert(DC && "Allocation failure!");
+  return DC;
+}
+
+//
+// LLVMDisasmDispose() disposes of the disassembler specified by the context.
+//
+void LLVMDisasmDispose(LLVMDisasmContextRef DCR){
+  LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
+  delete DC;
+}
+
+namespace {
+//
+// The memory object created by LLVMDisasmInstruction().
+//
+class DisasmMemoryObject : public MemoryObject {
+private:
+  uint8_t *Bytes;
+  uint64_t Size;
+  uint64_t BasePC;
+public:
+  DisasmMemoryObject(uint8_t *bytes, uint64_t size, uint64_t basePC) :
+                     Bytes(bytes), Size(size), BasePC(basePC) {}
+ 
+  uint64_t getBase() const { return BasePC; }
+  uint64_t getExtent() const { return Size; }
+
+  int readByte(uint64_t Addr, uint8_t *Byte) const {
+    if (Addr - BasePC >= Size)
+      return -1;
+    *Byte = Bytes[Addr - BasePC];
+    return 0;
+  }
+};
+} // namespace
+
+//
+// LLVMDisasmInstruction() disassmbles a single instruction using the
+// disassembler context specified in the parameter DC.  The bytes of the
+// instuction are specified in the parameter Bytes, and contains at least
+// BytesSize number of bytes.  The instruction is at the address specified by
+// the PC parameter.  If a valid instruction can be disassembled its string is
+// returned indirectly in OutString which whos size is specified in the
+// parameter OutStringSize.  This function returns the number of bytes in the
+// instruction or zero if there was no valid instruction.  If this function
+// returns zero the caller will have to pick how many bytes they want to step
+// over by printing a .byte, .long etc. to continue.
+//
+size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes,
+                             uint64_t BytesSize, uint64_t PC, char *OutString,
+                             size_t OutStringSize){
+  LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
+  // Wrap the pointer to the Bytes, BytesSize and PC in a MemoryObject.
+  DisasmMemoryObject MemoryObject(Bytes, BytesSize, PC);
+
+  uint64_t Size;
+  MCInst Inst;
+  const MCDisassembler *DisAsm = DC->getDisAsm();
+  MCInstPrinter *IP = DC->getIP();
+  if (!DisAsm->getInstruction(Inst, Size, MemoryObject, PC, /*REMOVE*/ nulls()))
+    return 0;
+
+  std::string InsnStr;
+  raw_string_ostream OS(InsnStr);
+  raw_ostream &Out = OS;
+  IP->printInst(&Inst, Out);
+
+  std::string p;
+  p = OS.str();
+  snprintf(OutString, OutStringSize, "%s", p.c_str());
+  return Size;
+}
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+

Added: lib/MC/MCDisassembler/Disassembler.h
===================================================================
--- /dev/null
+++ b/lib/MC/MCDisassembler/Disassembler.h
@@ -0,0 +1,91 @@
+//===------------- Disassembler.h - LLVM Disassembler -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file defines the interface for the Disassembly library's disassembler 
+// context.  The disassembler is responsible for producing strings for
+// individual instructions according to a given architecture and disassembly
+// syntax.
+//
+//===----------------------------------------------------------------------===//
+#include "llvm-c/Disassembler.h"
+#include <string>
+#include "llvm/ADT/OwningPtr.h"
+
+namespace llvm {
+class TargetAsmInfo;
+class MCContext;
+class MCAsmInfo;
+class MCDisassembler;
+class MCInstPrinter; 
+class Target;
+class TargetMachine;
+
+//
+// This is the disassembler context returned by LLVMCreateDisasm().
+//
+class LLVMDisasmContext {
+private:
+  //
+  // The passed parameters when the disassembler context is created.
+  //
+  // The TripleName for this disassembler.
+  std::string TripleName;
+  // The pointer to the caller's block of symbolic information.
+  void *DisInfo;
+  // The Triple specific symbolic information type returned by GetOpInfo.
+  int TagType;
+  // The function to get the symbolic information for operands.
+  LLVMOpInfoCallback GetOpInfo;
+  // The function to look up a symbol name.
+  LLVMSymbolLookupCallback SymbolLookUp;
+  //
+  // The objects created and saved by LLVMCreateDisasm() then used by
+  // LLVMDisasmInstruction().
+  //
+  // The LLVM target corresponding to the disassembler.
+  // FIXME: using llvm::OwningPtr<const llvm::Target> causes a malloc error
+  //        when this LLVMDisasmContext is deleted.
+  const Target *TheTarget;
+  // The assembly information for the target architecture.
+  llvm::OwningPtr<const llvm::MCAsmInfo> MAI;
+  // The target machine instance.
+  llvm::OwningPtr<llvm::TargetMachine> TM;
+  // The disassembler for the target architecture.
+  // FIXME: using llvm::OwningPtr<const llvm::TargetAsmInfo> causes a malloc
+  //        error when this LLVMDisasmContext is deleted.
+  const TargetAsmInfo *Tai;
+  // The assembly context for creating symbols and MCExprs.
+  llvm::OwningPtr<const llvm::MCContext> Ctx;
+  // The disassembler for the target architecture.
+  llvm::OwningPtr<const llvm::MCDisassembler> DisAsm;
+  // The instruction printer for the target architecture.
+  llvm::OwningPtr<llvm::MCInstPrinter> IP;
+
+public:
+  LLVMDisasmContext(std::string tripleName, void *disInfo, int tagType,
+	  LLVMOpInfoCallback getOpInfo,
+                    LLVMSymbolLookupCallback symbolLookUp,
+                    const Target *theTarget, const MCAsmInfo *mAI,
+                    llvm::TargetMachine *tM, const TargetAsmInfo *tai,
+                    llvm::MCContext *ctx, const MCDisassembler *disAsm,
+                    MCInstPrinter *iP) : TripleName(tripleName),
+                    DisInfo(disInfo), TagType(tagType), GetOpInfo(getOpInfo),
+                    SymbolLookUp(symbolLookUp), TheTarget(theTarget), Tai(tai) {
+    TM.reset(tM);
+    MAI.reset(mAI);
+    Ctx.reset(ctx);
+    DisAsm.reset(disAsm);
+    IP.reset(iP);
+  }
+  const MCDisassembler *getDisAsm() const { return DisAsm.get(); }
+  MCInstPrinter *getIP() { return IP.get(); }
+};
+
+} // namespace llvm
+



   Commit: 139c34196e6d532afdf8a01bb8fa0dc8795b3128
   Author: Kevin Enderby <enderby@apple.com>
     Date: 03/25/2011 20:23:05
      URL: https://github.com/mono/llvm/commit/139c34196e6d532afdf8a01bb8fa0dc8795b3128


Remove the files for r128308 as it is causing a buildbot failure.


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

Removed paths:
 D include/llvm-c/Disassembler.h
 D lib/MC/MCDisassembler/Disassembler.cpp
 D lib/MC/MCDisassembler/Disassembler.h

   Commit: 0a57d2aabf96894e264da61211143848394ce234
   Author: Bill Wendling <isanbard@gmail.com>
     Date: 03/25/2011 21:20:37
      URL: https://github.com/mono/llvm/commit/0a57d2aabf96894e264da61211143848394ce234


PR9561: A store with a negative offset (via GEP) could erroniously say that it
completely overlaps a previous store, thus mistakenly deleting that store. Check
for this condition.


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

Changed paths:
 M lib/Transforms/Scalar/DeadStoreElimination.cpp
Added paths:
 A test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll

Modified: lib/Transforms/Scalar/DeadStoreElimination.cpp
===================================================================
--- a/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -354,8 +354,10 @@ static bool isCompleteOverwrite(const AliasAnalysis::Location \
&Later,  // In this case, we see if the later store completely overlaps all bytes
   // stored by the previous store.
   if (Off1 < Off2 ||                       // Earlier starts before Later.
+      Off2 < 0 ||                          // Later is -.
       Off1+Earlier.Size > Off2+Later.Size) // Earlier goes beyond Later.
     return false;
+
   // Otherwise, we have complete overlap.
   return true;
 }

Added: test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll
===================================================================
--- /dev/null
+++ b/test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll
@@ -0,0 +1,23 @@
+; RUN: opt < %s -basicaa -dse -S | FileCheck %s
+; PR9561
+target triple = "i386-apple-darwin9.8"
+
+@A = external global [0 x i32]
+
+declare cc10 void @Func2(i32*, i32*, i32*, i32)
+
+define cc10 void @Func1(i32* noalias %Arg1, i32* noalias %Arg2, i32* %Arg3, i32 \
%Arg4) { +entry:
+  store i32 add (i32 ptrtoint ([0 x i32]* @A to i32), i32 1), i32* %Arg2
+; CHECK: store i32 add (i32 ptrtoint ([0 x i32]* @A to i32), i32 1), i32* %Arg2
+  %ln2gz = getelementptr i32* %Arg1, i32 14
+  %ln2gA = bitcast i32* %ln2gz to double*
+  %ln2gB = load double* %ln2gA
+  %ln2gD = getelementptr i32* %Arg2, i32 -3
+  %ln2gE = bitcast i32* %ln2gD to double*
+  store double %ln2gB, double* %ln2gE
+; CHECK: store double %ln2gB, double* %ln2gE
+  tail call cc10 void @Func2(i32* %Arg1, i32* %Arg2, i32* %Arg3, i32 %Arg4) nounwind
+  ret void
+}
+



   Commit: 308c25191f0d57099b88ce2adda12bc72ac5176a
   Author: Eric Christopher <echristo@apple.com>
     Date: 03/25/2011 21:21:03
      URL: https://github.com/mono/llvm/commit/308c25191f0d57099b88ce2adda12bc72ac5176a


Fix the bfi handling for or (and a mask) (and b mask). We need the two
masks to match inversely for the code as is to work. For the example given
we actually want:

bfi r0, r2, #1, #1

not #0, however, given the way the pattern is written it's not possible
at the moment.

Fixes rdar://9177502


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

Changed paths:
 M lib/Target/ARM/ARMISelLowering.cpp
 M test/CodeGen/Thumb2/bfi.ll

Modified: lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -5168,6 +5168,7 @@ static SDValue PerformMULCombine(SDNode *N,
 
 static SDValue PerformANDCombine(SDNode *N,
                                 TargetLowering::DAGCombinerInfo &DCI) {
+  
   // Attempt to use immediate-form VBIC
   BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
   DebugLoc dl = N->getDebugLoc();
@@ -5241,9 +5242,9 @@ static SDValue PerformORCombine(SDNode *N,
   //
   // 2) or (and A, mask), (and B, mask2) => ARMbfi A, (lsr B, amt), mask
   //  2a) iff isBitFieldInvertedMask(mask) && isBitFieldInvertedMask(~mask2)
-  //          && CountPopulation_32(mask) == CountPopulation_32(~mask2)
+  //          && mask == ~mask2
   //  2b) iff isBitFieldInvertedMask(~mask) && isBitFieldInvertedMask(mask2)
-  //          && CountPopulation_32(mask) == CountPopulation_32(~mask2)
+  //          && ~mask == mask2
   //  (i.e., copy a bitfield value into another bitfield of the same width)
   if (N0.getOpcode() != ISD::AND)
     return SDValue();
@@ -5289,26 +5290,26 @@ static SDValue PerformORCombine(SDNode *N,
       return SDValue();
     unsigned Mask2 = N11C->getZExtValue();
 
+    // Mask and ~Mask2 (or reverse) must be equivalent for the BFI pattern
+    // as is to match.
     if (ARM::isBitFieldInvertedMask(Mask) &&
-        ARM::isBitFieldInvertedMask(~Mask2) &&
-        (CountPopulation_32(Mask) == CountPopulation_32(~Mask2))) {
+        (Mask == ~Mask2)) {
       // The pack halfword instruction works better for masks that fit it,
       // so use that when it's available.
       if (Subtarget->hasT2ExtractPack() &&
           (Mask == 0xffff || Mask == 0xffff0000))
         return SDValue();
       // 2a
-      unsigned lsb = CountTrailingZeros_32(Mask2);
+      unsigned amt = CountTrailingZeros_32(Mask2);
       Res = DAG.getNode(ISD::SRL, DL, VT, N1.getOperand(0),
-                        DAG.getConstant(lsb, MVT::i32));
+                        DAG.getConstant(amt, MVT::i32));
       Res = DAG.getNode(ARMISD::BFI, DL, VT, N00, Res,
                         DAG.getConstant(Mask, MVT::i32));
       // Do not add new nodes to DAG combiner worklist.
       DCI.CombineTo(N, Res, false);
       return SDValue();
     } else if (ARM::isBitFieldInvertedMask(~Mask) &&
-               ARM::isBitFieldInvertedMask(Mask2) &&
-               (CountPopulation_32(~Mask) == CountPopulation_32(Mask2))) {
+               (~Mask == Mask2)) {
       // The pack halfword instruction works better for masks that fit it,
       // so use that when it's available.
       if (Subtarget->hasT2ExtractPack() &&
@@ -5319,7 +5320,7 @@ static SDValue PerformORCombine(SDNode *N,
       Res = DAG.getNode(ISD::SRL, DL, VT, N00,
                         DAG.getConstant(lsb, MVT::i32));
       Res = DAG.getNode(ARMISD::BFI, DL, VT, N1.getOperand(0), Res,
-                                DAG.getConstant(Mask2, MVT::i32));
+                        DAG.getConstant(Mask2, MVT::i32));
       // Do not add new nodes to DAG combiner worklist.
       DCI.CombineTo(N, Res, false);
       return SDValue();
Modified: test/CodeGen/Thumb2/bfi.ll
===================================================================
--- a/test/CodeGen/Thumb2/bfi.ll
+++ b/test/CodeGen/Thumb2/bfi.ll
@@ -49,3 +49,14 @@ define i32 @f4(i32 %a) nounwind {
   %ins12 = or i32 %ins7, 3137
   ret i32 %ins12
 }
+
+; rdar://9177502
+define i32 @f5(i32 %a, i32 %b) nounwind readnone {
+entry:
+; CHECK f5
+; CHECK-NOT: bfi r0, r2, #0, #1
+%and = and i32 %a, 2
+%b.masked = and i32 %b, -2
+%and3 = or i32 %b.masked, %and
+ret i32 %and3
+}


   Commit: f2b9319893e0b750826bc5d3804758e494590dd9
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/25/2011 21:32:48
      URL: https://github.com/mono/llvm/commit/f2b9319893e0b750826bc5d3804758e494590dd9


Fixed the t2PLD and friends disassembly and add two test cases.


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

Changed paths:
 M lib/Target/ARM/Disassembler/ARMDisassembler.cpp
 M lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
 M test/MC/Disassembler/ARM/thumb-tests.txt

Modified: lib/Target/ARM/Disassembler/ARMDisassembler.cpp
===================================================================
--- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -284,6 +284,24 @@ static unsigned T2Morph2LoadLiteral(unsigned Opcode) {
   }
 }
 
+// Helper function for special case handling of PLD (literal) and friends.
+// See A8.6.117 T1 & T2 and friends for why we morphed the opcode
+// before returning it.
+static unsigned T2Morph2PLDLiteral(unsigned Opcode) {
+  switch (Opcode) {
+  default:
+    return Opcode; // Return unmorphed opcode.
+
+  case ARM::t2PLDi8:   case ARM::t2PLDs:
+  case ARM::t2PLDWi12: case ARM::t2PLDWi8:
+  case ARM::t2PLDWs:
+    return ARM::t2PLDi12;
+
+  case ARM::t2PLIi8:   case ARM::t2PLIs:
+    return ARM::t2PLIi12;
+  }
+}
+
 /// decodeThumbSideEffect is a decorator function which can potentially twiddle
 /// the instruction or morph the returned opcode under Thumb2.
 ///
@@ -334,12 +352,27 @@ static unsigned decodeThumbSideEffect(bool IsThumb2, unsigned \
&insn) {  }
     // --------- Transform End Marker ---------
 
+    unsigned unmorphed = decodeThumbInstruction(insn);
+
     // See, for example, A6.3.7 Load word: Table A6-18 Load word.
     // See A8.6.57 T3, T4 & A8.6.60 T2 and friends for why we morphed the opcode
     // before returning it to our caller.
     if (op1 == 3 && slice(op2, 6, 5) == 0 && slice(op2, 0, 0) == 1
-        && slice(insn, 19, 16) == 15)
-      return T2Morph2LoadLiteral(decodeThumbInstruction(insn));
+        && slice(insn, 19, 16) == 15) {
+      unsigned morphed = T2Morph2LoadLiteral(unmorphed);
+      if (morphed != unmorphed)
+        return morphed;
+    }
+
+    // See, for example, A8.6.117 PLD,PLDW (immediate) T1 & T2, and friends for
+    // why we morphed the opcode before returning it to our caller.
+    if (slice(insn, 31, 25) == 0x7C && slice(insn, 15, 12) == 0xF
+        && slice(insn, 22, 22) == 0 && slice(insn, 20, 20) == 1
+        && slice(insn, 19, 16) == 15) {
+      unsigned morphed = T2Morph2PLDLiteral(unmorphed);
+      if (morphed != unmorphed)
+        return morphed;
+    }
 
     // One last check for NEON/VFP instructions.
     if ((op1 == 1 || op1 == 3) && slice(op2, 6, 6) == 1)
Modified: lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
===================================================================
--- a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
+++ b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
@@ -1786,7 +1786,7 @@ static bool DisassembleThumb2PreLoad(MCInst &MI, unsigned \
Opcode, uint32_t insn,  decodeRn(insn))));
   ++OpIdx;
 
-  if (OpInfo[OpIdx].RegClass == ARM::GPRRegClassID) {
+  if (OpInfo[OpIdx].RegClass == ARM::rGPRRegClassID) {
     MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
                                                        decodeRm(insn))));
   } else {
@@ -1794,15 +1794,11 @@ static bool DisassembleThumb2PreLoad(MCInst &MI, unsigned \
Opcode, uint32_t insn,  && !OpInfo[OpIdx].isOptionalDef()
            && "Pure imm operand expected");
     int Offset = 0;
-    if (slice(insn, 19, 16) == 0xFF) {
-      bool Negative = slice(insn, 23, 23) == 0;
-      unsigned Imm12 = getImm12(insn);
-      Offset = Negative ? -1 - Imm12 : 1 * Imm12;
-    } else if (Opcode == ARM::t2PLDi8 || Opcode == ARM::t2PLDWi8 ||
-               Opcode == ARM::t2PLIi8) {
+    if (Opcode == ARM::t2PLDi8 || Opcode == ARM::t2PLDWi8 ||
+        Opcode == ARM::t2PLIi8) {
       // A8.6.117 Encoding T2: add = FALSE
       unsigned Imm8 = getImm8(insn);
-      Offset = -1 - Imm8;
+      Offset = -1 * Imm8;
     } else // The i12 forms.  See, for example, A8.6.117 Encoding T1.
       Offset = decodeImm12(insn);
     MI.addOperand(MCOperand::CreateImm(Offset));
Modified: test/MC/Disassembler/ARM/thumb-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/thumb-tests.txt
+++ b/test/MC/Disassembler/ARM/thumb-tests.txt
@@ -190,3 +190,9 @@
 
 # CHECK:	umull	r1, r2, r3, r4
 0xa3 0xfb 0x04 0x12
+
+# CHECK:	pld	[r5, r0, lsl #1]
+0x15 0xf8 0x10 0xf0
+
+# CHECK:	pld	[pc, #-16]
+0x1f 0xf8 0x10 0xf0


   Commit: bbc3e633f8a73b229e9ba8c179055c7af09016c6
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/25/2011 22:19:36
      URL: https://github.com/mono/llvm/commit/bbc3e633f8a73b229e9ba8c179055c7af09016c6


Collect and coalesce DBG_VALUE instructions before emitting the function.

Correctly terminate the range of register DBG_VALUEs when the register is
clobbered or when the basic block ends.

The code is now ready to deal with variables that are sometimes in a register
and sometimes on the stack. We just need to teach emitDebugLoc to say 'stack
slot'.

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

Changed paths:
 M include/llvm/CodeGen/MachineBasicBlock.h
 M lib/CodeGen/AsmPrinter/DwarfDebug.cpp
 M lib/CodeGen/AsmPrinter/DwarfDebug.h
 M test/CodeGen/X86/dbg-merge-loc-entry.ll

Modified: include/llvm/CodeGen/MachineBasicBlock.h
===================================================================
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -309,6 +309,10 @@ public:
   /// instruction in the basic block, or end()
   iterator getLastNonDebugInstr();
 
+  const_iterator getLastNonDebugInstr() const {
+    return const_cast<MachineBasicBlock*>(this)->getLastNonDebugInstr();
+  }
+
   /// SplitCriticalEdge - Split the critical edge from this block to the
   /// given successor block, and return the newly created block, or null
   /// if splitting is not possible.
Modified: lib/CodeGen/AsmPrinter/DwarfDebug.cpp
===================================================================
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -2408,38 +2408,21 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
   /// collection info from MMI table.
   collectVariableInfoFromMMITable(MF, Processed);
 
-  SmallVector<const MachineInstr *, 8> DbgValues;
-  // Collect variable information from DBG_VALUE machine instructions;
-  for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
-       I != E; ++I)
-    for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
-         II != IE; ++II) {
-      const MachineInstr *MInsn = II;
-      if (!MInsn->isDebugValue())
-        continue;
-      DbgValues.push_back(MInsn);
-    }
-
-  // This is a collection of DBG_VALUE instructions describing same variable.
-  SmallVector<const MachineInstr *, 4> MultipleValues;
-  for(SmallVector<const MachineInstr *, 8>::iterator I = DbgValues.begin(),
-        E = DbgValues.end(); I != E; ++I) {
-    const MachineInstr *MInsn = *I;
-    MultipleValues.clear();
-    if (isDbgValueInDefinedReg(MInsn))
-      MultipleValues.push_back(MInsn);
-    DIVariable DV(MInsn->getOperand(MInsn->getNumOperands() - 1).getMetadata());
-    if (Processed.count(DV) != 0)
+  for (SmallVectorImpl<const MDNode*>::const_iterator
+         UVI = UserVariables.begin(), UVE = UserVariables.end(); UVI != UVE;
+         ++UVI) {
+    const MDNode *Var = *UVI;
+    if (Processed.count(Var))
       continue;
 
-    for (SmallVector<const MachineInstr *, 8>::iterator MI = I+1,
-           ME = DbgValues.end(); MI != ME; ++MI) {
-      const MDNode *Var =
-        (*MI)->getOperand((*MI)->getNumOperands()-1).getMetadata();
-      if (Var == DV)
-        MultipleValues.push_back(*MI);
-    }
+    // History contains relevant DBG_VALUE instructions for Var and instructions
+    // clobbering it.
+    SmallVectorImpl<const MachineInstr*> &History = DbgValues[Var];
+    if (History.empty())
+      continue;
+    const MachineInstr *MInsn = History.front();
 
+    DIVariable DV(Var);
     DbgScope *Scope = NULL;
     if (DV.getTag() == dwarf::DW_TAG_arg_variable &&
         DISubprogram(DV.getContext()).describes(MF->getFunction()))
@@ -2451,6 +2434,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
       continue;
 
     Processed.insert(DV);
+    assert(MInsn->isDebugValue() && "History must begin with debug value");
     DbgVariable *RegVar = new DbgVariable(DV);
     if (!addCurrentFnArgument(MF, RegVar, Scope))
       Scope->addVariable(RegVar);
@@ -2458,21 +2442,21 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
       DbgVariableToDbgInstMap[AbsVar] = MInsn;
       VarToAbstractVarMap[RegVar] = AbsVar;
     }
-    if (MultipleValues.size() <= 1 && !RegClobberInsn.count(MInsn)) {
+
+    // Simple ranges that are fully coalesced.
+    if (History.size() <= 1 || (History.size() == 2 &&
+                                MInsn->isIdenticalTo(History.back()))) {
       DbgVariableToDbgInstMap[RegVar] = MInsn;
       continue;
     }
 
     // handle multiple DBG_VALUE instructions describing one variable.
-    if (DotDebugLocEntries.empty())
-      RegVar->setDotDebugLocOffset(0);
-    else
-      RegVar->setDotDebugLocOffset(DotDebugLocEntries.size());
+    RegVar->setDotDebugLocOffset(DotDebugLocEntries.size());
 
-    for (SmallVector<const MachineInstr *, 4>::iterator
-           MVI = MultipleValues.begin(), MVE = MultipleValues.end();
-         MVI != MVE; ++MVI) {
-      const MachineInstr *Begin = *MVI;
+    for (SmallVectorImpl<const MachineInstr*>::const_iterator
+           HI = History.begin(), HE = History.end(); HI != HE; ++HI) {
+      const MachineInstr *Begin = *HI;
+      assert(Begin->isDebugValue() && "Invalid History entry");
       MachineLocation MLoc;
       if (Begin->getNumOperands() == 3) {
         if (Begin->getOperand(0).isReg() && Begin->getOperand(1).isImm())
@@ -2480,6 +2464,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
       } else
         MLoc = Asm->getDebugValueLocation(Begin);
 
+      // FIXME: emitDebugLoc only understands registers.
       if (!MLoc.getReg())
         continue;
 
@@ -2487,17 +2472,23 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
       const MCSymbol *FLabel = getLabelBeforeInsn(Begin);
       const MCSymbol *SLabel = 0;
 
-      if (const MachineInstr *ClobberMI = RegClobberInsn.lookup(Begin))
-        // The register range starting at Begin may be clobbered.
-        SLabel = getLabelAfterInsn(ClobberMI);
-      else if (MVI + 1 == MVE)
-        // If Begin is the last instruction then its value is valid
+      if (HI + 1 == HE)
+        // If Begin is the last instruction in History then its value is valid
         // until the end of the funtion.
         SLabel = FunctionEndSym;
-      else
-        // The value is valid until the next DBG_VALUE.
-        SLabel = getLabelBeforeInsn(MVI[1]);
+      else {
+        const MachineInstr *End = HI[1];
+        if (End->isDebugValue())
+          SLabel = getLabelBeforeInsn(End);
+        else {
+          // End is a normal instruction clobbering the range.
+          SLabel = getLabelAfterInsn(End);
+          assert(SLabel && "Forgot label after clobber instruction");
+          ++HI;
+        }
+      }
 
+      // The value is valid until the next DBG_VALUE or clobber.
       DotDebugLocEntries.push_back(DotDebugLocEntry(FLabel, SLabel, MLoc));
     }
     DotDebugLocEntries.push_back(DotDebugLocEntry());
@@ -2519,21 +2510,14 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
 
 /// getLabelBeforeInsn - Return Label preceding the instruction.
 const MCSymbol *DwarfDebug::getLabelBeforeInsn(const MachineInstr *MI) {
-  DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
-    LabelsBeforeInsn.find(MI);
-  if (I == LabelsBeforeInsn.end())
-    // FunctionBeginSym always preceeds all the instruction in current function.
-    return FunctionBeginSym;
-  return I->second;
+  MCSymbol *Label = LabelsBeforeInsn.lookup(MI);
+  assert(Label && "Didn't insert label before instruction");
+  return Label;
 }
 
 /// getLabelAfterInsn - Return Label immediately following the instruction.
 const MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr *MI) {
-  DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
-    LabelsAfterInsn.find(MI);
-  if (I == LabelsAfterInsn.end())
-    return NULL;
-  return I->second;
+  return LabelsAfterInsn.lookup(MI);
 }
 
 /// beginInstruction - Process beginning of an instruction.
@@ -2552,14 +2536,22 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
   }
 
   // Insert labels where requested.
-  if (!InsnNeedsLabel.count(MI))
+  DenseMap<const MachineInstr*, MCSymbol*>::iterator I =
+    LabelsBeforeInsn.find(MI);
+
+  // No label needed.
+  if (I == LabelsBeforeInsn.end())
+    return;
+
+  // Label already assigned.
+  if (I->second)
     return;
 
   if (!PrevLabel) {
     PrevLabel = MMI->getContext().CreateTempSymbol();
     Asm->OutStreamer.EmitLabel(PrevLabel);
   }
-  LabelsBeforeInsn[MI] = PrevLabel;
+  I->second = PrevLabel;
 }
 
 /// endInstruction - Process end of an instruction.
@@ -2569,7 +2561,15 @@ void DwarfDebug::endInstruction(const MachineInstr *MI) {
   if (!MI->isDebugValue())
     PrevLabel = 0;
 
-  if (!InsnsNeedsLabelAfter.count(MI))
+  DenseMap<const MachineInstr*, MCSymbol*>::iterator I =
+    LabelsAfterInsn.find(MI);
+
+  // No label needed.
+  if (I == LabelsAfterInsn.end())
+    return;
+
+  // Label already assigned.
+  if (I->second)
     return;
 
   // We need a label after this instruction.
@@ -2577,7 +2577,7 @@ void DwarfDebug::endInstruction(const MachineInstr *MI) {
     PrevLabel = MMI->getContext().CreateTempSymbol();
     Asm->OutStreamer.EmitLabel(PrevLabel);
   }
-  LabelsAfterInsn[MI] = PrevLabel;
+  I->second = PrevLabel;
 }
 
 /// getOrCreateDbgScope - Create DbgScope for the scope.
@@ -2837,8 +2837,8 @@ void DwarfDebug::identifyScopeMarkers() {
            RE = Ranges.end(); RI != RE; ++RI) {
       assert(RI->first && "DbgRange does not have first instruction!");
       assert(RI->second && "DbgRange does not have second instruction!");
-      InsnNeedsLabel.insert(RI->first);
-      InsnsNeedsLabelAfter.insert(RI->second);
+      requestLabelBeforeInsn(RI->first);
+      requestLabelAfterInsn(RI->second);
     }
   }
 }
@@ -2916,46 +2916,78 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
 
   recordSourceLine(Line, Col, TheScope);
 
+  assert(UserVariables.empty() && DbgValues.empty() && "Maps weren't cleaned");
+
   /// ProcessedArgs - Collection of arguments already processed.
   SmallPtrSet<const MDNode *, 8> ProcessedArgs;
 
-  /// LastDbgValue - Refer back to the last DBG_VALUE instruction to mention MD.
-  DenseMap<const MDNode*, const MachineInstr*> LastDbgValue;
-
   const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
 
   /// LiveUserVar - Map physreg numbers to the MDNode they contain.
   std::vector<const MDNode*> LiveUserVar(TRI->getNumRegs());
 
   for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
-       I != E; ++I)
+       I != E; ++I) {
+    bool AtBlockEntry = true;
     for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
          II != IE; ++II) {
       const MachineInstr *MI = II;
-      DebugLoc DL = MI->getDebugLoc();
+
       if (MI->isDebugValue()) {
         assert (MI->getNumOperands() > 1 && "Invalid machine instruction!");
 
-        // Keep track of variables in registers.
+        // Keep track of user variables.
         const MDNode *Var =
           MI->getOperand(MI->getNumOperands() - 1).getMetadata();
-        LastDbgValue[Var] = MI;
+
+        // Variable is in a register, we need to check for clobbers.
         if (isDbgValueInDefinedReg(MI))
           LiveUserVar[MI->getOperand(0).getReg()] = Var;
 
-        DIVariable DV(Var);
-        if (!DV.Verify()) continue;
-        // If DBG_VALUE is for a local variable then it needs a label.
-        if (DV.getTag() != dwarf::DW_TAG_arg_variable)
-          InsnNeedsLabel.insert(MI);
-        // DBG_VALUE for inlined functions argument needs a label.
-        else if (!DISubprogram(getDISubprogram(DV.getContext())).
-                 describes(MF->getFunction()))
-          InsnNeedsLabel.insert(MI);
-        // DBG_VALUE indicating argument location change needs a label.
-        else if (!ProcessedArgs.insert(DV))
-          InsnNeedsLabel.insert(MI);
+        // Check the history of this variable.
+        SmallVectorImpl<const MachineInstr*> &History = DbgValues[Var];
+        if (History.empty()) {
+          UserVariables.push_back(Var);
+          // The first mention of a function argument gets the FunctionBeginSym
+          // label, so arguments are visible when breaking at function entry.
+          DIVariable DV(Var);
+          if (DV.Verify() && DV.getTag() == dwarf::DW_TAG_arg_variable &&
+              DISubprogram(getDISubprogram(DV.getContext()))
+                .describes(MF->getFunction()))
+            LabelsBeforeInsn[MI] = FunctionBeginSym;
+        } else {
+          // We have seen this variable before. Try to coalesce DBG_VALUEs.
+          const MachineInstr *Prev = History.back();
+          if (Prev->isDebugValue()) {
+            // Coalesce identical entries at the end of History.
+            if (History.size() >= 2 &&
+                Prev->isIdenticalTo(History[History.size() - 2]))
+              History.pop_back();
+
+            // Terminate old register assignments that don't reach MI;
+            MachineFunction::const_iterator PrevMBB = Prev->getParent();
+            if (PrevMBB != I && (!AtBlockEntry || llvm::next(PrevMBB) != I) &&
+                isDbgValueInDefinedReg(Prev)) {
+              // Previous register assignment needs to terminate at the end of
+              // its basic block.
+              MachineBasicBlock::const_iterator LastMI =
+                PrevMBB->getLastNonDebugInstr();
+              if (LastMI == PrevMBB->end())
+                // Drop DBG_VALUE for empty range.
+                History.pop_back();
+              else {
+                // Terminate after LastMI.
+                History.push_back(LastMI);
+              }
+            }
+          }
+        }
+        History.push_back(MI);
       } else {
+        // Not a DBG_VALUE instruction.
+        if (!MI->isLabel())
+          AtBlockEntry = false;
+
         // Check if the instruction clobbers any registers with debug vars.
         for (MachineInstr::const_mop_iterator MOI = MI->operands_begin(),
                MOE = MI->operands_end(); MOI != MOE; ++MOI) {
@@ -2970,19 +3002,57 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
             LiveUserVar[Reg] = 0;
 
             // Was MD last defined by a DBG_VALUE referring to Reg?
-            const MachineInstr *Last = LastDbgValue.lookup(Var);
-            if (!Last || Last->getParent() != MI->getParent())
+            DbgValueHistoryMap::iterator HistI = DbgValues.find(Var);
+            if (HistI == DbgValues.end())
+              continue;
+            SmallVectorImpl<const MachineInstr*> &History = HistI->second;
+            if (History.empty())
+              continue;
+            const MachineInstr *Prev = History.back();
+            // Sanity-check: Register assignments are terminated at the end of
+            // their block.
+            if (!Prev->isDebugValue() || Prev->getParent() != MI->getParent())
               continue;
-            if (!isDbgValueInDefinedReg(Last) ||
-                Last->getOperand(0).getReg() != Reg)
+            // Is the variable still in Reg?
+            if (!isDbgValueInDefinedReg(Prev) ||
+                Prev->getOperand(0).getReg() != Reg)
               continue;
-            // MD is clobbered. Make sure the next instruction gets a label.
-            InsnsNeedsLabelAfter.insert(MI);
-            RegClobberInsn[Last] = MI;
+            // Var is clobbered. Make sure the next instruction gets a label.
+            History.push_back(MI);
           }
         }
       }
     }
+  }
+
+  for (DbgValueHistoryMap::iterator I = DbgValues.begin(), E = DbgValues.end();
+       I != E; ++I) {
+    SmallVectorImpl<const MachineInstr*> &History = I->second;
+    if (History.empty())
+      continue;
+
+    // Make sure the final register assignments are terminated.
+    const MachineInstr *Prev = History.back();
+    if (Prev->isDebugValue() && isDbgValueInDefinedReg(Prev)) {
+      const MachineBasicBlock *PrevMBB = Prev->getParent();
+      MachineBasicBlock::const_iterator LastMI = PrevMBB->getLastNonDebugInstr();
+      if (LastMI == PrevMBB->end())
+        // Drop DBG_VALUE for empty range.
+        History.pop_back();
+      else {
+        // Terminate after LastMI.
+        History.push_back(LastMI);
+      }
+    }
+    // Request labels for the full history.
+    for (unsigned i = 0, e = History.size(); i != e; ++i) {
+      const MachineInstr *MI = History[i];
+      if (MI->isDebugValue())
+        requestLabelBeforeInsn(MI);
+      else
+        requestLabelAfterInsn(MI);
+    }
+  }
 
   PrevInstLoc = DebugLoc();
   PrevLabel = FunctionBeginSym;
@@ -3043,13 +3113,12 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
   // Clear debug info
   CurrentFnDbgScope = NULL;
   CurrentFnArguments.clear();
-  InsnNeedsLabel.clear();
   DbgVariableToFrameIndexMap.clear();
   VarToAbstractVarMap.clear();
   DbgVariableToDbgInstMap.clear();
   DeleteContainerSeconds(DbgScopeMap);
-  InsnsNeedsLabelAfter.clear();
-  RegClobberInsn.clear();
+  UserVariables.clear();
+  DbgValues.clear();
   ConcreteScopes.clear();
   DeleteContainerSeconds(AbstractScopes);
   AbstractScopesList.clear();
Modified: lib/CodeGen/AsmPrinter/DwarfDebug.h
===================================================================
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -218,19 +218,16 @@ class DwarfDebug {
   /// instruction.
   DenseMap<const MachineInstr *, MCSymbol *> LabelsAfterInsn;
 
-  /// insnNeedsLabel - Collection of instructions that need a label to mark
-  /// a debuggging information entity.
-  SmallPtrSet<const MachineInstr *, 8> InsnNeedsLabel;
+  /// UserVariables - Every user variable mentioned by a DBG_VALUE instruction
+  /// in order of appearance.
+  SmallVector<const MDNode*, 8> UserVariables;
 
-  /// InsnsNeedsLabelAfter - Collection of instructions that need a label after
-  /// the instruction because they end a scope of clobber a register.
-  SmallPtrSet<const MachineInstr *, 8> InsnsNeedsLabelAfter;
-
-  /// RegClobberInsn - For each DBG_VALUE instruction referring to a register
-  /// that is clobbered before the variable gets a new DBG_VALUE, map the
-  /// instruction that clobbered the register. This instruction will also be in
-  /// InsnsNeedsLabelAfter.
-  DenseMap<const MachineInstr *, const MachineInstr *> RegClobberInsn;
+  /// DbgValues - For each user variable, keep a list of DBG_VALUE
+  /// instructions in order. The list can also contain normal instructions that
+  /// clobber the previous DBG_VALUE.
+  typedef DenseMap<const MDNode*, SmallVector<const MachineInstr*, 4> >
+    DbgValueHistoryMap;
+  DbgValueHistoryMap DbgValues;
 
   SmallVector<const MCSymbol *, 8> DebugRangeSymbols;
 
@@ -570,6 +567,23 @@ private:
   /// side table maintained by MMI.
   void collectVariableInfoFromMMITable(const MachineFunction * MF,
                                        SmallPtrSet<const MDNode *, 16> &P);
+
+  /// requestLabelBeforeInsn - Ensure that a label will be emitted before MI.
+  void requestLabelBeforeInsn(const MachineInstr *MI) {
+    LabelsBeforeInsn.insert(std::make_pair(MI, (MCSymbol*)0));
+  }
+
+  /// getLabelBeforeInsn - Return Label preceding the instruction.
+  const MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
+
+  /// requestLabelAfterInsn - Ensure that a label will be emitted after MI.
+  void requestLabelAfterInsn(const MachineInstr *MI) {
+    LabelsAfterInsn.insert(std::make_pair(MI, (MCSymbol*)0));
+  }
+
+  /// getLabelAfterInsn - Return Label immediately following the instruction.
+  const MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
+
 public:
   //===--------------------------------------------------------------------===//
   // Main entry points.
@@ -593,12 +607,6 @@ public:
   ///
   void endFunction(const MachineFunction *MF);
 
-  /// getLabelBeforeInsn - Return Label preceding the instruction.
-  const MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
-
-  /// getLabelAfterInsn - Return Label immediately following the instruction.
-  const MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
-
   /// beginInstruction - Process beginning of an instruction.
   void beginInstruction(const MachineInstr *MI);
 
Modified: test/CodeGen/X86/dbg-merge-loc-entry.ll
===================================================================
--- a/test/CodeGen/X86/dbg-merge-loc-entry.ll
+++ b/test/CodeGen/X86/dbg-merge-loc-entry.ll
@@ -4,7 +4,7 @@ target triple = "x86_64-apple-darwin8"
 
 ;CHECK: Ldebug_loc0:
 ;CHECK-NEXT:	.quad	Lfunc_begin0
-;CHECK-NEXT:	.quad	Lfunc_end0
+;CHECK-NEXT:	.quad	L
 ;CHECK-NEXT:	.short	1                       ## Loc expr size
 ;CHECK-NEXT:	.byte	85                      ## DW_OP_reg5
 ;CHECK-NEXT:	.quad	0


   Commit: 61734fcc0840fad74e62bfa8dfbc8b1772f1fcac
   Author: Douglas Gregor <doug.gregor@gmail.com>
     Date: 03/25/2011 23:40:01
      URL: https://github.com/mono/llvm/commit/61734fcc0840fad74e62bfa8dfbc8b1772f1fcac


Extend Clang's TableGen emitter for attributes to support bool arguments.


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

Changed paths:
 M utils/TableGen/ClangAttrEmitter.cpp

Modified: utils/TableGen/ClangAttrEmitter.cpp
===================================================================
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -477,6 +477,8 @@ static Argument *createArgument(Record &Arg, StringRef Attr,
     Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *");
   else if (ArgName == "IdentifierArgument")
     Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *");
+  else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr, 
+                                                               "bool");
   else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int");
   else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr);
   else if (ArgName == "TypeArgument")


   Commit: abb2a6f8a360c4af9773e4b02cd4d6f75cfed478
   Author: Cameron Zwarich <zwarich@apple.com>
     Date: 03/26/2011 00:58:50
      URL: https://github.com/mono/llvm/commit/abb2a6f8a360c4af9773e4b02cd4d6f75cfed478


Fix a typo and add a test.

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

Changed paths:
 M lib/Transforms/Scalar/ScalarReplAggregates.cpp
 M test/Transforms/ScalarRepl/vector_promote.ll

Modified: lib/Transforms/Scalar/ScalarReplAggregates.cpp
===================================================================
--- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp
+++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
@@ -380,7 +380,7 @@ bool ConvertToScalarInfo::MergeInVectorType(const VectorType \
*VInTy,  return true;
 
   const Type *ElementTy = cast<VectorType>(VectorTy)->getElementType();
-  const Type *InElementTy = cast<VectorType>(VectorTy)->getElementType();
+  const Type *InElementTy = cast<VectorType>(VInTy)->getElementType();
 
   // Do not allow mixed integer and floating-point accesses from vectors of
   // different sizes.
Modified: test/Transforms/ScalarRepl/vector_promote.ll
===================================================================
--- a/test/Transforms/ScalarRepl/vector_promote.ll
+++ b/test/Transforms/ScalarRepl/vector_promote.ll
@@ -187,3 +187,18 @@ entry:
 ; CHECK: extractelement <4 x i128>
 ; CHECK: insertelement <4 x i128>
 }
+
+define float @test13(<4 x float> %x, <2 x i32> %y) {
+	%a = alloca <4 x float>
+	store <4 x float> %x, <4 x float>* %a
+	%p = bitcast <4 x float>* %a to <2 x float>*
+	%b = load <2 x float>* %p
+	%q = getelementptr <4 x float>* %a, i32 0, i32 2
+	%c = load float* %q
+	%r = bitcast <4 x float>* %a to <2 x i32>*
+	store <2 x i32> %y, <2 x i32>* %r
+	ret float %c
+; CHECK: @test13
+; CHECK-NOT: alloca
+; CHECK: bitcast <4 x float> %x to i128
+}


   Commit: 5c0fc3461bc4b7453471a4e30fa6552438b1fb92
   Author: Bill Wendling <isanbard@gmail.com>
     Date: 03/26/2011 04:02:59
      URL: https://github.com/mono/llvm/commit/5c0fc3461bc4b7453471a4e30fa6552438b1fb92


Rework the logic that determines if a store completely overlaps an ealier store.

There are two ways that a later store can comletely overlap a previous store:

1. They both start at the same offset, but the earlier store's size is <= the
   later's size, or
2. The earlier store's offset is > the later's offset, but it's offset + size
   doesn't extend past the later's offset + size.


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

Changed paths:
 M lib/Transforms/Scalar/DeadStoreElimination.cpp

Modified: lib/Transforms/Scalar/DeadStoreElimination.cpp
===================================================================
--- a/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -340,26 +340,34 @@ static bool isCompleteOverwrite(const AliasAnalysis::Location \
&Later,  // Okay, we have stores to two completely different pointers.  Try to
   // decompose the pointer into a "base + constant_offset" form.  If the base
   // pointers are equal, then we can reason about the two stores.
-  int64_t Off1 = 0, Off2 = 0;
-  const Value *BP1 = GetPointerBaseWithConstantOffset(P1, Off1, TD);
-  const Value *BP2 = GetPointerBaseWithConstantOffset(P2, Off2, TD);
+  int64_t EarlierOff = 0, LaterOff = 0;
+  const Value *BP1 = GetPointerBaseWithConstantOffset(P1, EarlierOff, TD);
+  const Value *BP2 = GetPointerBaseWithConstantOffset(P2, LaterOff, TD);
   
   // If the base pointers still differ, we have two completely different stores.
   if (BP1 != BP2)
     return false;
-  
-  // Otherwise, we might have a situation like:
-  //  store i16 -> P + 1 Byte
-  //  store i32 -> P
-  // In this case, we see if the later store completely overlaps all bytes
-  // stored by the previous store.
-  if (Off1 < Off2 ||                       // Earlier starts before Later.
-      Off2 < 0 ||                          // Later is -.
-      Off1+Earlier.Size > Off2+Later.Size) // Earlier goes beyond Later.
-    return false;
 
-  // Otherwise, we have complete overlap.
-  return true;
+  // The later store completely overlaps the earlier store if:
+  // 
+  // 1. Both start at the same offset and the later one's size is greater than
+  //    or equal to the earlier one's, or
+  //
+  //      |--earlier--|
+  //      |--   later   --|
+  //      
+  // 2. The earlier store has an offset greater than the later offset, but which
+  //    still lies completely within the later store.
+  //
+  //        |--earlier--|
+  //    |-----  later  ------|
+  if ((EarlierOff == LaterOff && Earlier.Size <= Later.Size) ||
+      (EarlierOff > LaterOff &&
+       EarlierOff + Earlier.Size <= LaterOff + Later.Size))
+    return true;
+
+  // Otherwise, they don't completely overlap.
+  return false;
 }
 
 /// isPossibleSelfRead - If 'Inst' might be a self read (i.e. a noop copy of a


   Commit: 10931122d8dee6ef1afe0a952c5901bd0c0671c8
   Author: Bill Wendling <isanbard@gmail.com>
     Date: 03/26/2011 05:32:07
      URL: https://github.com/mono/llvm/commit/10931122d8dee6ef1afe0a952c5901bd0c0671c8


Simplification noticed by Frits.

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

Changed paths:
 M lib/Transforms/Scalar/DeadStoreElimination.cpp

Modified: lib/Transforms/Scalar/DeadStoreElimination.cpp
===================================================================
--- a/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -361,9 +361,8 @@ static bool isCompleteOverwrite(const AliasAnalysis::Location \
&Later,  //
   //        |--earlier--|
   //    |-----  later  ------|
-  if ((EarlierOff == LaterOff && Earlier.Size <= Later.Size) ||
-      (EarlierOff > LaterOff &&
-       EarlierOff + Earlier.Size <= LaterOff + Later.Size))
+  if (EarlierOff >= LaterOff &&
+      EarlierOff + Earlier.Size <= LaterOff + Later.Size)
     return true;
 
   // Otherwise, they don't completely overlap.


   Commit: 2ef1b8217ca2a7f45dc64e6ef8129926da60bf44
   Author: Benjamin Kramer <benny.kra@googlemail.com>
     Date: 03/26/2011 08:38:19
      URL: https://github.com/mono/llvm/commit/2ef1b8217ca2a7f45dc64e6ef8129926da60bf44


Make helper static.

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

Changed paths:
 M lib/Target/X86/X86ISelLowering.cpp

Modified: lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -3891,8 +3891,8 @@ static SDValue getShuffleVectorZeroOrUndef(SDValue V2, unsigned \
Idx,  
 /// getShuffleScalarElt - Returns the scalar element that will make up the ith
 /// element of the result of the vector shuffle.
-SDValue getShuffleScalarElt(SDNode *N, int Index, SelectionDAG &DAG,
-                            unsigned Depth) {
+static SDValue getShuffleScalarElt(SDNode *N, int Index, SelectionDAG &DAG,
+                                   unsigned Depth) {
   if (Depth == 6)
     return SDValue();  // Limit search depth.
 


   Commit: a763705c28b67c5f7f9f0494a909905ce9aa44b3
   Author: Benjamin Kramer <benny.kra@googlemail.com>
     Date: 03/26/2011 12:35:10
      URL: https://github.com/mono/llvm/commit/a763705c28b67c5f7f9f0494a909905ce9aa44b3


Turn SelectionDAGBuilder::GetRegistersForValue into a local function.

It couldn't be used outside of the file because SDISelAsmOperandInfo
is local to SelectionDAGBuilder.cpp. Making it a static function avoids
a weird linkage dance.

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

Changed paths:
 M lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
 M lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h

Modified: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===================================================================
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -50,7 +50,6 @@
 #include "llvm/Target/TargetIntrinsicInfo.h"
 #include "llvm/Target/TargetLowering.h"
 #include "llvm/Target/TargetOptions.h"
-#include "llvm/Support/Compiler.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -5202,12 +5201,11 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
   LowerCallTo(&I, Callee, I.isTailCall());
 }
 
-namespace llvm {
+namespace {
 
 /// AsmOperandInfo - This contains information for each constraint that we are
 /// lowering.
-class LLVM_LIBRARY_VISIBILITY SDISelAsmOperandInfo :
-    public TargetLowering::AsmOperandInfo {
+class SDISelAsmOperandInfo : public TargetLowering::AsmOperandInfo {
 public:
   /// CallOperand - If this is the result output operand or a clobber
   /// this is null, otherwise it is the incoming operand to the CallInst.
@@ -5295,7 +5293,7 @@ private:
 
 typedef SmallVector<SDISelAsmOperandInfo,16> SDISelAsmOperandInfoVector;
 
-} // end llvm namespace.
+} // end anonymous namespace
 
 /// isAllocatableRegister - If the specified register is safe to allocate,
 /// i.e. it isn't a stack pointer or some other special register, return the
@@ -5354,11 +5352,13 @@ isAllocatableRegister(unsigned Reg, MachineFunction &MF,
 ///   OpInfo describes the operand.
 ///   Input and OutputRegs are the set of already allocated physical registers.
 ///
-void SelectionDAGBuilder::
-GetRegistersForValue(SDISelAsmOperandInfo &OpInfo,
-                     std::set<unsigned> &OutputRegs,
-                     std::set<unsigned> &InputRegs) {
-  LLVMContext &Context = FuncInfo.Fn->getContext();
+static void GetRegistersForValue(SelectionDAG &DAG,
+                                 const TargetLowering &TLI,
+                                 DebugLoc DL,
+                                 SDISelAsmOperandInfo &OpInfo,
+                                 std::set<unsigned> &OutputRegs,
+                                 std::set<unsigned> &InputRegs) {
+  LLVMContext &Context = *DAG.getContext();
 
   // Compute whether this value requires an input register, an output register,
   // or both.
@@ -5404,7 +5404,7 @@ GetRegistersForValue(SDISelAsmOperandInfo &OpInfo,
       // vector types).
       EVT RegVT = *PhysReg.second->vt_begin();
       if (RegVT.getSizeInBits() == OpInfo.ConstraintVT.getSizeInBits()) {
-        OpInfo.CallOperand = DAG.getNode(ISD::BITCAST, getCurDebugLoc(),
+        OpInfo.CallOperand = DAG.getNode(ISD::BITCAST, DL,
                                          RegVT, OpInfo.CallOperand);
         OpInfo.ConstraintVT = RegVT;
       } else if (RegVT.isInteger() && OpInfo.ConstraintVT.isFloatingPoint()) {
@@ -5414,7 +5414,7 @@ GetRegistersForValue(SDISelAsmOperandInfo &OpInfo,
         // machine.
         RegVT = EVT::getIntegerVT(Context,
                                   OpInfo.ConstraintVT.getSizeInBits());
-        OpInfo.CallOperand = DAG.getNode(ISD::BITCAST, getCurDebugLoc(),
+        OpInfo.CallOperand = DAG.getNode(ISD::BITCAST, DL,
                                          RegVT, OpInfo.CallOperand);
         OpInfo.ConstraintVT = RegVT;
       }
@@ -5685,7 +5685,8 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) \
{  // If this constraint is for a specific register, allocate it before
     // anything else.
     if (OpInfo.ConstraintType == TargetLowering::C_Register)
-      GetRegistersForValue(OpInfo, OutputRegs, InputRegs);
+      GetRegistersForValue(DAG, TLI, getCurDebugLoc(), OpInfo, OutputRegs,
+                           InputRegs);
   }
 
   // Second pass - Loop over all of the operands, assigning virtual or physregs
@@ -5696,7 +5697,8 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) \
                {
     // C_Register operands have already been allocated, Other/Memory don't need
     // to be.
     if (OpInfo.ConstraintType == TargetLowering::C_RegisterClass)
-      GetRegistersForValue(OpInfo, OutputRegs, InputRegs);
+      GetRegistersForValue(DAG, TLI, getCurDebugLoc(), OpInfo, OutputRegs,
+                           InputRegs);
   }
 
   // AsmNodeOperands - The operands for the ISD::INLINEASM node.
Modified: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
===================================================================
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -60,7 +60,6 @@ class MDNode;
 class PHINode;
 class PtrToIntInst;
 class ReturnInst;
-class SDISelAsmOperandInfo;
 class SDDbgValue;
 class SExtInst;
 class SelectInst;
@@ -380,10 +379,6 @@ public:
     assert(N.getNode() == 0 && "Already set a value for this node!");
     N = NewN;
   }
-  
-  void GetRegistersForValue(SDISelAsmOperandInfo &OpInfo,
-                            std::set<unsigned> &OutputRegs, 
-                            std::set<unsigned> &InputRegs);
 
   void FindMergedConditions(const Value *Cond, MachineBasicBlock *TBB,
                             MachineBasicBlock *FBB, MachineBasicBlock *CurBB,


   Commit: 1cfe06ed31911d76998d8dbfad7867d9e065da9c
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/26/2011 18:16:41
      URL: https://github.com/mono/llvm/commit/1cfe06ed31911d76998d8dbfad7867d9e065da9c


Use individual register classes when spilling snippets.

The main register class may have been inflated by live range splitting, so that
register class is not necessarily valid for the snippet instructions.

Use the original register class for the stack slot interval.

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

Changed paths:
 M lib/CodeGen/InlineSpiller.cpp
 M lib/CodeGen/LiveRangeEdit.h

Modified: lib/CodeGen/InlineSpiller.cpp
===================================================================
--- a/lib/CodeGen/InlineSpiller.cpp
+++ b/lib/CodeGen/InlineSpiller.cpp
@@ -48,7 +48,7 @@ class InlineSpiller : public Spiller {
 
   // Variables that are valid during spill(), but used by multiple methods.
   LiveRangeEdit *Edit;
-  const TargetRegisterClass *RC;
+  LiveInterval *StackInt;
   int StackSlot;
   unsigned Original;
 
@@ -431,12 +431,12 @@ bool InlineSpiller::hoistSpill(LiveInterval &SpillLI, \
MachineInstr *CopyMI) {  // Conservatively extend the stack slot range to the range \
of the original  // value. We may be able to do better with stack slot coloring by \
being more  // careful here.
-  LiveInterval &StackInt = LSS.getInterval(StackSlot);
+  assert(StackInt && "No stack slot assigned yet.");
   LiveInterval &OrigLI = LIS.getInterval(Original);
   VNInfo *OrigVNI = OrigLI.getVNInfoAt(Idx);
-  StackInt.MergeValueInAsValue(OrigLI, OrigVNI, StackInt.getValNumInfo(0));
+  StackInt->MergeValueInAsValue(OrigLI, OrigVNI, StackInt->getValNumInfo(0));
   DEBUG(dbgs() << "\tmerged orig valno " << OrigVNI->id << ": "
-               << StackInt << '\n');
+               << *StackInt << '\n');
 
   // Already spilled everywhere.
   if (SVI.AllDefsAreReloads)
@@ -455,7 +455,8 @@ bool InlineSpiller::hoistSpill(LiveInterval &SpillLI, \
MachineInstr *CopyMI) {  ++MII;
   }
   // Insert spill without kill flag immediately after def.
-  TII.storeRegToStackSlot(*MBB, MII, SVI.SpillReg, false, StackSlot, RC, &TRI);
+  TII.storeRegToStackSlot(*MBB, MII, SVI.SpillReg, false, StackSlot,
+                          MRI.getRegClass(SVI.SpillReg), &TRI);
   --MII; // Point to store instruction.
   LIS.InsertMachineInstrInMaps(MII);
   VRM.addSpillSlotUse(StackSlot, MII);
@@ -469,7 +470,7 @@ void InlineSpiller::eliminateRedundantSpills(LiveInterval &SLI, \
VNInfo *VNI) {  assert(VNI && "Missing value");
   SmallVector<std::pair<LiveInterval*, VNInfo*>, 8> WorkList;
   WorkList.push_back(std::make_pair(&SLI, VNI));
-  LiveInterval &StackInt = LSS.getInterval(StackSlot);
+  assert(StackInt && "No stack slot assigned yet.");
 
   do {
     LiveInterval *LI;
@@ -483,8 +484,8 @@ void InlineSpiller::eliminateRedundantSpills(LiveInterval &SLI, \
VNInfo *VNI) {  continue;
 
     // Add all of VNI's live range to StackInt.
-    StackInt.MergeValueInAsValue(*LI, VNI, StackInt.getValNumInfo(0));
-    DEBUG(dbgs() << "Merged to stack int: " << StackInt << '\n');
+    StackInt->MergeValueInAsValue(*LI, VNI, StackInt->getValNumInfo(0));
+    DEBUG(dbgs() << "Merged to stack int: " << *StackInt << '\n');
 
     // Find all spills and copies of VNI.
     for (MachineRegisterInfo::use_nodbg_iterator UI = MRI.use_nodbg_begin(Reg);
@@ -723,7 +724,8 @@ void InlineSpiller::insertReload(LiveInterval &NewLI,
                                  MachineBasicBlock::iterator MI) {
   MachineBasicBlock &MBB = *MI->getParent();
   SlotIndex Idx = LIS.getInstructionIndex(MI).getDefIndex();
-  TII.loadRegFromStackSlot(MBB, MI, NewLI.reg, StackSlot, RC, &TRI);
+  TII.loadRegFromStackSlot(MBB, MI, NewLI.reg, StackSlot,
+                           MRI.getRegClass(NewLI.reg), &TRI);
   --MI; // Point to load instruction.
   SlotIndex LoadIdx = LIS.InsertMachineInstrInMaps(MI).getDefIndex();
   VRM.addSpillSlotUse(StackSlot, MI);
@@ -744,7 +746,8 @@ void InlineSpiller::insertSpill(LiveInterval &NewLI, const \
LiveInterval &OldLI,  assert(VNI && VNI->def.getDefIndex() == Idx && "Inconsistent \
VNInfo");  Idx = VNI->def;
 
-  TII.storeRegToStackSlot(MBB, ++MI, NewLI.reg, true, StackSlot, RC, &TRI);
+  TII.storeRegToStackSlot(MBB, ++MI, NewLI.reg, true, StackSlot,
+                          MRI.getRegClass(NewLI.reg), &TRI);
   --MI; // Point to store instruction.
   SlotIndex StoreIdx = LIS.InsertMachineInstrInMaps(MI).getDefIndex();
   VRM.addSpillSlotUse(StackSlot, MI);
@@ -818,7 +821,7 @@ void InlineSpiller::spillAroundUses(unsigned Reg) {
 
     // Allocate interval around instruction.
     // FIXME: Infer regclass from instruction alone.
-    LiveInterval &NewLI = Edit->create(LIS, VRM);
+    LiveInterval &NewLI = Edit->createFrom(Reg, LIS, VRM);
     NewLI.markNotSpillable();
 
     if (Reads)
@@ -853,6 +856,7 @@ void InlineSpiller::spill(LiveRangeEdit &edit) {
   // Share a stack slot among all descendants of Original.
   Original = VRM.getOriginal(edit.getReg());
   StackSlot = VRM.getStackSlot(Original);
+  StackInt = 0;
 
   DEBUG(dbgs() << "Inline spilling "
                << MRI.getRegClass(edit.getReg())->getName()
@@ -870,22 +874,22 @@ void InlineSpiller::spill(LiveRangeEdit &edit) {
   if (Edit->getParent().empty())
     return;
 
-  RC = MRI.getRegClass(edit.getReg());
-
-  if (StackSlot == VirtRegMap::NO_STACK_SLOT)
+  // Update LiveStacks now that we are committed to spilling.
+  if (StackSlot == VirtRegMap::NO_STACK_SLOT) {
     StackSlot = VRM.assignVirt2StackSlot(Original);
+    StackInt = &LSS.getOrCreateInterval(StackSlot, MRI.getRegClass(Original));
+    StackInt->getNextValue(SlotIndex(), 0, LSS.getVNInfoAllocator());
+  } else
+    StackInt = &LSS.getInterval(StackSlot);
 
   if (Original != edit.getReg())
     VRM.assignVirt2StackSlot(edit.getReg(), StackSlot);
 
-  // Update LiveStacks now that we are committed to spilling.
-  LiveInterval &stacklvr = LSS.getOrCreateInterval(StackSlot, RC);
-  if (!stacklvr.hasAtLeastOneValue())
-    stacklvr.getNextValue(SlotIndex(), 0, LSS.getVNInfoAllocator());
+  assert(StackInt->getNumValNums() == 1 && "Bad stack interval values");
   for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i)
-    stacklvr.MergeRangesInAsValue(LIS.getInterval(RegsToSpill[i]),
-                                  stacklvr.getValNumInfo(0));
-  DEBUG(dbgs() << "Merged spilled regs: " << stacklvr << '\n');
+    StackInt->MergeRangesInAsValue(LIS.getInterval(RegsToSpill[i]),
+                                   StackInt->getValNumInfo(0));
+  DEBUG(dbgs() << "Merged spilled regs: " << *StackInt << '\n');
 
   // Spill around uses of all RegsToSpill.
   for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i)
Modified: lib/CodeGen/LiveRangeEdit.h
===================================================================
--- a/lib/CodeGen/LiveRangeEdit.h
+++ b/lib/CodeGen/LiveRangeEdit.h
@@ -65,9 +65,6 @@ private:
   /// live range trimmed or entirely removed.
   SmallPtrSet<const VNInfo*,4> rematted_;
 
-  /// createFrom - Create a new virtual register based on OldReg.
-  LiveInterval &createFrom(unsigned, LiveIntervals&, VirtRegMap &);
-
   /// scanRemattable - Identify the parent_ values that may rematerialize.
   void scanRemattable(LiveIntervals &lis,
                       const TargetInstrInfo &tii,
@@ -113,6 +110,9 @@ public:
     return uselessRegs_;
   }
 
+  /// createFrom - Create a new virtual register based on OldReg.
+  LiveInterval &createFrom(unsigned OldReg, LiveIntervals&, VirtRegMap&);
+
   /// create - Create a new register with the same class and original slot as
   /// parent.
   LiveInterval &create(LiveIntervals &LIS, VirtRegMap &VRM) {


   Commit: e0f37558d4a3aa4e25d74b253efea6d6b93ed806
   Author: NAKAMURA Takumi <geek4civic@gmail.com>
     Date: 03/26/2011 21:44:40
      URL: https://github.com/mono/llvm/commit/e0f37558d4a3aa4e25d74b253efea6d6b93ed806


Fix whitespace.

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

Changed paths:
 M lib/MC/MCAsmStreamer.cpp

Modified: lib/MC/MCAsmStreamer.cpp
===================================================================
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -844,13 +844,13 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
       OS << "0b";
       for (unsigned j = 8; j--;) {
         unsigned Bit = (Code[i] >> j) & 1;
-        
+
         unsigned FixupBit;
         if (getContext().getTargetAsmInfo().isLittleEndian())
           FixupBit = i * 8 + j;
         else
           FixupBit = i * 8 + (7-j);
-        
+
         if (uint8_t MapEntry = FixupMap[FixupBit]) {
           assert(Bit == 0 && "Encoder wrote into fixed up bit!");
           OS << char('A' + MapEntry - 1);


   Commit: 36d5d905ddd1f3c3f48a90e342e6fca7444280ad
   Author: Nick Lewycky <nicholas@mxc.ca>
     Date: 03/27/2011 03:30:57
      URL: https://github.com/mono/llvm/commit/36d5d905ddd1f3c3f48a90e342e6fca7444280ad


Add a small missed optimization: turn X == C ? X : Y into X == C ? C : Y. This
removes one use of X which helps it pass the many hasOneUse() checks.

In my analysis, this turns up very often where X = A >>exact B and that can't be
simplified unless X has one use (except by increasing the lifetime of A which is
generally a performance loss).


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

Changed paths:
 M lib/Transforms/InstCombine/InstCombineSelect.cpp
 M test/Transforms/InstCombine/select.ll

Modified: lib/Transforms/InstCombine/InstCombineSelect.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -424,6 +424,19 @@ Instruction *InstCombiner::visitSelectInstWithICmp(SelectInst \
&SI,  return ReplaceInstUsesWith(SI, TrueVal);
     /// NOTE: if we wanted to, this is where to detect integer MIN/MAX
   }
+
+  if (isa<Constant>(CmpRHS)) {
+    if (CmpLHS == TrueVal && Pred == ICmpInst::ICMP_EQ) {
+      // Transform (X == C) ? X : Y -> (X == C) ? C : Y
+      SI.setOperand(1, CmpRHS);
+      Changed = true;
+    } else if (CmpLHS == FalseVal && Pred == ICmpInst::ICMP_NE) {
+      // Transform (X != C) ? Y : X -> (X != C) ? Y : C
+      SI.setOperand(2, CmpRHS);
+      Changed = true;
+    }
+  }
+
   return Changed ? &SI : 0;
 }
 
Modified: test/Transforms/InstCombine/select.ll
===================================================================
--- a/test/Transforms/InstCombine/select.ll
+++ b/test/Transforms/InstCombine/select.ll
@@ -724,3 +724,16 @@ define i32 @test53(i32 %x) nounwind {
 ; CHECK: select i1 %cmp
 ; CHECK: ret
 }
+
+define i32 @test54(i32 %X, i32 %Y) {
+  %A = ashr exact i32 %X, %Y
+  %B = icmp eq i32 %A, 0
+  %C = select i1 %B, i32 %A, i32 1
+  ret i32 %C
+; CHECK: @test54
+; CHECK-NOT: ashr
+; CHECK-NOT: select
+; CHECK: icmp ne i32 %X, 0
+; CHECK: zext 
+; CHECK: ret
+}


   Commit: 264220ed3c18d125f1ac90e9880524a5c3709d39
   Author: Duncan Sands <baldrick@free.fr>
     Date: 03/27/2011 09:52:32
      URL: https://github.com/mono/llvm/commit/264220ed3c18d125f1ac90e9880524a5c3709d39


Partially revert commit 127155: I think it is much more convenient
to have structured log files rather than one big file produced by
piping output.


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

Changed paths:
 M utils/release/test-release.sh

Modified: utils/release/test-release.sh
===================================================================
--- a/utils/release/test-release.sh
+++ b/utils/release/test-release.sh
@@ -118,6 +118,11 @@ fi
 llvmCore_srcdir=$BuildDir/llvmCore-$Release-rc$RC.src
 llvmgcc42_srcdir=$BuildDir/llvmgcc42-$Release-rc$RC.src
 
+# Location of log files.
+LogDirName="$Release-rc$RC.logs"
+LogDir=$BuildDir/$LogDirName
+mkdir -p $LogDir
+
 # SVN URLs for the sources.
 Base_url="http://llvm.org/svn/llvm-project"
 llvmCore_RC_url="$Base_url/llvm/tags/RELEASE_$Release_no_dot/rc$RC"
@@ -196,7 +201,8 @@ function configure_llvmCore() {
     $llvmCore_srcdir/configure --prefix=$InstallDir \
         --enable-optimized=$Optimized \
         --enable-assertions=$Assertions \
-        --with-llvmgccdir=$llvmgccDir
+        --with-llvmgccdir=$llvmgccDir \
+        > $LogDir/llvm.configure.$Release-rc$RC-Phase$Phase-$Flavor.log 2>&1
     cd -
 }
 
@@ -217,11 +223,13 @@ function build_llvmCore() {
     cd $ObjDir
     echo "# Compiling llvm $Release-rc$RC $Flavor"
     echo "# make -j $NumJobs VERBOSE=1 $ExtraOpts"
-    make -j $NumJobs VERBOSE=1 $ExtraOpts $CompilerFlags
+    make -j $NumJobs VERBOSE=1 $ExtraOpts $CompilerFlags \
+        > $LogDir/llvm.make.$Release-rc$RC-Phase$Phase-$Flavor.log 2>&1
 
     echo "# Installing llvm $Release-rc$RC $Flavor"
     echo "# make install"
-    make install
+    make install \
+        > $LogDir/llvm.install.$Release-rc$RC-Phase$Phase-$Flavor.log 2>&1
     cd -
 }
 
@@ -231,9 +239,12 @@ function test_llvmCore() {
     ObjDir="$3"
 
     cd $ObjDir
-    make check
-    make -C tools/clang test
-    make unittests
+    make check \
+        > $LogDir/llvm.check.$Release-rc$RC-Phase$Phase-$Flavor.log 2>&1
+    make -C tools/clang test \
+        > $LogDir/clang.check.$Release-rc$RC-Phase$Phase-$Flavor.log 2>&1
+    make unittests \
+        > $LogDir/llvm.unittests.$Release-rc$RC-Phase$Phase-$Flavor.log 2>&1
     cd -
 }
 
@@ -262,7 +273,8 @@ function configure_llvm_gcc() {
         --enable-languages=$languages"
     $llvmgcc42_srcdir/configure --prefix=$InstallDir \
         --program-prefix=llvm- --enable-llvm=$llvmObjDir \
-        --enable-languages=$languages
+        --enable-languages=$languages \
+        > $LogDir/llvm-gcc.configure.$Release-rc$RC-Phase$Phase-$Flavor.log 2>&1
     cd -
 }
 
@@ -280,11 +292,13 @@ function build_llvm_gcc() {
     cd $ObjDir
     echo "# Compiling llvm-gcc $Release-rc$RC $Flavor"
     echo "# make -j $NumJobs bootstrap LLVM_VERSION_INFO=$Release"
-    make -j $NumJobs bootstrap LLVM_VERSION_INFO=$Release $CompilerFlags
+    make -j $NumJobs bootstrap LLVM_VERSION_INFO=$Release $CompilerFlags \
+        > $LogDir/llvm-gcc.make.$Release-rc$RC-Phase$Phase-$Flavor.log 2>&1
 
     echo "# Installing llvm-gcc $Release-rc$RC $Flavor"
     echo "# make install"
-    make install
+    make install \
+        > $LogDir/llvm-gcc.install.$Release-rc$RC-Phase$Phase-$Flavor.log 2>&1
     cd -
 }
 
@@ -292,6 +306,7 @@ if [ "$do_checkout" = "yes" ]; then
     export_sources
 fi
 
+(
 Flavors="Debug Release Release+Asserts"
 if [ "$do_64bit" = "yes" ]; then
     Flavors="$Flavors Release-64"
@@ -375,7 +390,9 @@ for Flavor in $Flavors ; do
     echo "# Testing - built with llvmgcc42"
     test_llvmCore 2 $Flavor $llvmCore_phase2_objdir
 done
+) 2>&1 | tee $LogDir/testing.$Release-rc$RC.log
 
 # Woo hoo!
 echo "### Testing Finished ###"
+echo "### Logs: $LogDir"
 exit 0


   Commit: 6e26264df4a45d77ba349ca786d798bf184387c1
   Author: Frits van Bommel <fvbommel@gmail.com>
     Date: 03/27/2011 10:26:13
      URL: https://github.com/mono/llvm/commit/6e26264df4a45d77ba349ca786d798bf184387c1


Constant folding support for calls to umul.with.overflow(), basically identical to \
the smul.with.overflow() code.


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

Changed paths:
 M include/llvm/ADT/APInt.h
 M lib/Analysis/ConstantFolding.cpp
 M lib/Support/APInt.cpp
 M test/Transforms/ConstProp/overflow-ops.ll

Modified: include/llvm/ADT/APInt.h
===================================================================
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -818,6 +818,7 @@ public:
   APInt usub_ov(const APInt &RHS, bool &Overflow) const;
   APInt sdiv_ov(const APInt &RHS, bool &Overflow) const;
   APInt smul_ov(const APInt &RHS, bool &Overflow) const;
+  APInt umul_ov(const APInt &RHS, bool &Overflow) const;
   APInt sshl_ov(unsigned Amt, bool &Overflow) const;
 
   /// @returns the bit value at bitPosition
Modified: lib/Analysis/ConstantFolding.cpp
===================================================================
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -1048,11 +1048,12 @@ llvm::canConstantFoldCallTo(const Function *F) {
   case Intrinsic::ctpop:
   case Intrinsic::ctlz:
   case Intrinsic::cttz:
-  case Intrinsic::uadd_with_overflow:
-  case Intrinsic::usub_with_overflow:
   case Intrinsic::sadd_with_overflow:
+  case Intrinsic::uadd_with_overflow:
   case Intrinsic::ssub_with_overflow:
+  case Intrinsic::usub_with_overflow:
   case Intrinsic::smul_with_overflow:
+  case Intrinsic::umul_with_overflow:
   case Intrinsic::convert_from_fp16:
   case Intrinsic::convert_to_fp16:
   case Intrinsic::x86_sse_cvtss2si:
@@ -1362,7 +1363,8 @@ llvm::ConstantFoldCall(Function *F,
         case Intrinsic::uadd_with_overflow:
         case Intrinsic::ssub_with_overflow:
         case Intrinsic::usub_with_overflow:
-        case Intrinsic::smul_with_overflow: {
+        case Intrinsic::smul_with_overflow:
+        case Intrinsic::umul_with_overflow: {
           APInt Res;
           bool Overflow;
           switch (F->getIntrinsicID()) {
@@ -1382,6 +1384,9 @@ llvm::ConstantFoldCall(Function *F,
           case Intrinsic::smul_with_overflow:
             Res = Op1->getValue().smul_ov(Op2->getValue(), Overflow);
             break;
+          case Intrinsic::umul_with_overflow:
+            Res = Op1->getValue().umul_ov(Op2->getValue(), Overflow);
+            break;
           }
           Constant *Ops[] = {
             ConstantInt::get(F->getContext(), Res),
Modified: lib/Support/APInt.cpp
===================================================================
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -2078,6 +2078,16 @@ APInt APInt::smul_ov(const APInt &RHS, bool &Overflow) const {
   return Res;
 }
 
+APInt APInt::umul_ov(const APInt &RHS, bool &Overflow) const {
+  APInt Res = *this * RHS;
+
+  if (*this != 0 && RHS != 0)
+    Overflow = Res.udiv(RHS) != *this || Res.udiv(*this) != RHS;
+  else
+    Overflow = false;
+  return Res;
+}
+
 APInt APInt::sshl_ov(unsigned ShAmt, bool &Overflow) const {
   Overflow = ShAmt >= getBitWidth();
   if (Overflow)
Modified: test/Transforms/ConstProp/overflow-ops.ll
===================================================================
--- a/test/Transforms/ConstProp/overflow-ops.ll
+++ b/test/Transforms/ConstProp/overflow-ops.ll
@@ -2,6 +2,14 @@
 
 %i8i1 = type {i8, i1}
 
+declare {i8, i1} @llvm.uadd.with.overflow.i8(i8, i8)
+declare {i8, i1} @llvm.usub.with.overflow.i8(i8, i8)
+declare {i8, i1} @llvm.umul.with.overflow.i8(i8, i8)
+
+declare {i8, i1} @llvm.sadd.with.overflow.i8(i8, i8)
+declare {i8, i1} @llvm.ssub.with.overflow.i8(i8, i8)
+declare {i8, i1} @llvm.smul.with.overflow.i8(i8, i8)
+
 ;;-----------------------------
 ;; uadd
 ;;-----------------------------
@@ -47,6 +55,28 @@ entry:
 }
 
 ;;-----------------------------
+;; umul
+;;-----------------------------
+
+define {i8, i1} @umul_1() nounwind {
+entry:
+  %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 100, i8 3)
+  ret {i8, i1} %t
+
+; CHECK: @umul_1
+; CHECK: ret %i8i1 { i8 44, i1 true }
+}
+
+define {i8, i1} @umul_2() nounwind {
+entry:
+  %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 100, i8 2)
+  ret {i8, i1} %t
+
+; CHECK: @umul_2
+; CHECK: ret %i8i1 { i8 -56, i1 false }
+}
+
+;;-----------------------------
 ;; sadd
 ;;-----------------------------
 
@@ -163,14 +193,9 @@ entry:
 ; CHECK: ret %i8i1 { i8 -10, i1 false }
 }
 
-
-
-declare {i8, i1} @llvm.uadd.with.overflow.i8(i8, i8)
-declare {i8, i1} @llvm.usub.with.overflow.i8(i8, i8)
-
-declare {i8, i1} @llvm.sadd.with.overflow.i8(i8, i8)
-declare {i8, i1} @llvm.ssub.with.overflow.i8(i8, i8)
-declare {i8, i1} @llvm.smul.with.overflow.i8(i8, i8)
+;;-----------------------------
+;; smul
+;;-----------------------------
 
 ; rdar://8501501
 define {i8, i1} @smul_1() nounwind {


   Commit: cab385b035480a95ff4791b181545d238eaf8e89
   Author: Benjamin Kramer <benny.kra@googlemail.com>
     Date: 03/27/2011 11:04:38
      URL: https://github.com/mono/llvm/commit/cab385b035480a95ff4791b181545d238eaf8e89


Use APInt's umul_ov instead of rolling our own overflow detection.

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

Changed paths:
 M lib/Transforms/InstCombine/InstCombineCalls.cpp

Modified: lib/Transforms/InstCombine/InstCombineCalls.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -487,14 +487,15 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
     APInt RHSKnownOne(BitWidth, 0);
     ComputeMaskedBits(RHS, Mask, RHSKnownZero, RHSKnownOne);
 
-    // Get the largest possible values for each operand, extended to be large
-    // enough so that every possible product of two BitWidth-sized ints fits.
-    APInt LHSMax = (~LHSKnownZero).zext(BitWidth*2);
-    APInt RHSMax = (~RHSKnownZero).zext(BitWidth*2);
+    // Get the largest possible values for each operand.
+    APInt LHSMax = ~LHSKnownZero;
+    APInt RHSMax = ~RHSKnownZero;
 
     // If multiplying the maximum values does not overflow then we can turn
     // this into a plain NUW mul.
-    if ((LHSMax * RHSMax).getActiveBits() <= BitWidth) {
+    bool Overflow;
+    LHSMax.umul_ov(RHSMax, Overflow);
+    if (!Overflow) {
       Value *Mul = Builder->CreateNUWMul(LHS, RHS, "umul_with_overflow");
       Constant *V[] = {
         UndefValue::get(LHS->getType()),


   Commit: a0179421d10e999f4fc98f6f3c2433cb2fede050
   Author: Nick Lewycky <nicholas@mxc.ca>
     Date: 03/27/2011 15:51:23
      URL: https://github.com/mono/llvm/commit/a0179421d10e999f4fc98f6f3c2433cb2fede050


Teach the transformation that moves binary operators around selects to preserve
the subclass optional data.


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

Changed paths:
 M lib/Transforms/InstCombine/InstCombineSelect.cpp
 M test/Transforms/InstCombine/select.ll

Modified: lib/Transforms/InstCombine/InstCombineSelect.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -214,7 +214,7 @@ Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, Value \
*TrueVal,  unsigned OpToFold = 0;
         if ((SFO & 1) && FalseVal == TVI->getOperand(0)) {
           OpToFold = 1;
-        } else  if ((SFO & 2) && FalseVal == TVI->getOperand(1)) {
+        } else if ((SFO & 2) && FalseVal == TVI->getOperand(1)) {
           OpToFold = 2;
         }
 
@@ -227,9 +227,16 @@ Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, \
                Value *TrueVal,
             Instruction *NewSel = SelectInst::Create(SI.getCondition(), OOp, C);
             InsertNewInstBefore(NewSel, SI);
             NewSel->takeName(TVI);
-            if (BinaryOperator *BO = dyn_cast<BinaryOperator>(TVI))
-              return BinaryOperator::Create(BO->getOpcode(), FalseVal, NewSel);
-            llvm_unreachable("Unknown instruction!!");
+	    BinaryOperator *TVI_BO = cast<BinaryOperator>(TVI);
+            BinaryOperator *BO = BinaryOperator::Create(TVI_BO->getOpcode(),
+                                                        FalseVal, NewSel);
+	    if (isa<PossiblyExactOperator>(BO))
+	      BO->setIsExact(TVI_BO->isExact());
+	    if (isa<OverflowingBinaryOperator>(BO)) {
+	      BO->setHasNoUnsignedWrap(TVI_BO->hasNoUnsignedWrap());
+	      BO->setHasNoSignedWrap(TVI_BO->hasNoSignedWrap());
+	    }
+	    return BO;
           }
         }
       }
@@ -243,7 +250,7 @@ Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, Value \
*TrueVal,  unsigned OpToFold = 0;
         if ((SFO & 1) && TrueVal == FVI->getOperand(0)) {
           OpToFold = 1;
-        } else  if ((SFO & 2) && TrueVal == FVI->getOperand(1)) {
+        } else if ((SFO & 2) && TrueVal == FVI->getOperand(1)) {
           OpToFold = 2;
         }
 
@@ -256,9 +263,16 @@ Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, \
                Value *TrueVal,
             Instruction *NewSel = SelectInst::Create(SI.getCondition(), C, OOp);
             InsertNewInstBefore(NewSel, SI);
             NewSel->takeName(FVI);
-            if (BinaryOperator *BO = dyn_cast<BinaryOperator>(FVI))
-              return BinaryOperator::Create(BO->getOpcode(), TrueVal, NewSel);
-            llvm_unreachable("Unknown instruction!!");
+            BinaryOperator *FVI_BO = cast<BinaryOperator>(FVI);
+            BinaryOperator *BO = BinaryOperator::Create(FVI_BO->getOpcode(),
+                                                        TrueVal, NewSel);
+	    if (isa<PossiblyExactOperator>(BO))
+	      BO->setIsExact(FVI_BO->isExact());
+	    if (isa<OverflowingBinaryOperator>(BO)) {
+	      BO->setHasNoUnsignedWrap(FVI_BO->hasNoUnsignedWrap());
+	      BO->setHasNoSignedWrap(FVI_BO->hasNoSignedWrap());
+	    }
+	    return BO;
           }
         }
       }
Modified: test/Transforms/InstCombine/select.ll
===================================================================
--- a/test/Transforms/InstCombine/select.ll
+++ b/test/Transforms/InstCombine/select.ll
@@ -737,3 +737,15 @@ define i32 @test54(i32 %X, i32 %Y) {
 ; CHECK: zext 
 ; CHECK: ret
 }
+
+define i1 @test55(i1 %X, i32 %Y, i32 %Z) {
+  %A = ashr exact i32 %Y, %Z
+  %B = select i1 %X, i32 %Y, i32 %A
+  %C = icmp eq i32 %B, 0
+  ret i1 %C
+; CHECK: @test55
+; CHECK-NOT: ashr
+; CHECK-NOT: select
+; CHECK: icmp eq
+; CHECK: ret i1
+}


   Commit: a86ed7c198660f7b03924ad75b355c4ebdcbdf31
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/27/2011 18:49:21
      URL: https://github.com/mono/llvm/commit/a86ed7c198660f7b03924ad75b355c4ebdcbdf31


Drop interference reassignment in favor of eviction.

The reassignment phase was able to move interference with a higher spill weight,
but it didn't happen very often and it was fairly expensive.

The existing interference eviction picks up the slack.

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

Changed paths:
 M lib/CodeGen/RegAllocGreedy.cpp

Modified: lib/CodeGen/RegAllocGreedy.cpp
===================================================================
--- a/lib/CodeGen/RegAllocGreedy.cpp
+++ b/lib/CodeGen/RegAllocGreedy.cpp
@@ -49,7 +49,6 @@ using namespace llvm;
 
 STATISTIC(NumGlobalSplits, "Number of split global live ranges");
 STATISTIC(NumLocalSplits,  "Number of split local live ranges");
-STATISTIC(NumReassigned,   "Number of interferences reassigned");
 STATISTIC(NumEvicted,      "Number of interferences evicted");
 
 static RegisterRegAlloc greedyRegAlloc("greedy", "greedy register allocator",
@@ -164,10 +163,6 @@ private:
   bool LRE_CanEraseVirtReg(unsigned);
   void LRE_WillShrinkVirtReg(unsigned);
 
-  bool checkUncachedInterference(LiveInterval&, unsigned);
-  LiveInterval *getSingleInterference(LiveInterval&, unsigned);
-  bool reassignVReg(LiveInterval &InterferingVReg, unsigned OldPhysReg);
-
   void mapGlobalInterference(unsigned, SmallVectorImpl<IndexPair>&);
   float calcSplitConstraints(const SmallVectorImpl<IndexPair>&);
 
@@ -180,8 +175,6 @@ private:
   unsigned nextSplitPoint(unsigned);
   bool canEvictInterference(LiveInterval&, unsigned, float&);
 
-  unsigned tryReassign(LiveInterval&, AllocationOrder&,
-                              SmallVectorImpl<LiveInterval*>&);
   unsigned tryEvict(LiveInterval&, AllocationOrder&,
                     SmallVectorImpl<LiveInterval*>&);
   unsigned tryRegionSplit(LiveInterval&, AllocationOrder&,
@@ -288,17 +281,20 @@ void RAGreedy::enqueue(LiveInterval *LI) {
   unsigned Prio;
 
   LRStage.grow(Reg);
-  if (LRStage[Reg] == RS_Original)
-    // 1st generation ranges are handled first, long -> short.
+  if (LRStage[Reg] == RS_Second)
+    // Unsplit ranges that couldn't be allocated immediately are deferred until
+    // everything else has been allocated. Long ranges are allocated last so
+    // they are split against realistic interference.
+    Prio = (1u << 31) - Size;
+  else {
+    // Everything else is allocated in long->short order. Long ranges that don't
+    // fit should be spilled ASAP so they don't create interference.
     Prio = (1u << 31) + Size;
-  else
-    // Repeat offenders are handled second, short -> long
-    Prio = (1u << 30) - Size;
 
-  // Boost ranges that have a physical register hint.
-  const unsigned Hint = VRM->getRegAllocPref(Reg);
-  if (TargetRegisterInfo::isPhysicalRegister(Hint))
-    Prio |= (1u << 30);
+    // Boost ranges that have a physical register hint.
+    if (TargetRegisterInfo::isPhysicalRegister(VRM->getRegAllocPref(Reg)))
+      Prio |= (1u << 30);
+  }
 
   Queue.push(std::make_pair(Prio, Reg));
 }
@@ -312,100 +308,6 @@ LiveInterval *RAGreedy::dequeue() {
 }
 
 //===----------------------------------------------------------------------===//
-//                         Register Reassignment
-//===----------------------------------------------------------------------===//
-
-// Check interference without using the cache.
-bool RAGreedy::checkUncachedInterference(LiveInterval &VirtReg,
-                                         unsigned PhysReg) {
-  for (const unsigned *AliasI = TRI->getOverlaps(PhysReg); *AliasI; ++AliasI) {
-    LiveIntervalUnion::Query subQ(&VirtReg, &PhysReg2LiveUnion[*AliasI]);
-    if (subQ.checkInterference())
-      return true;
-  }
-  return false;
-}
-
-/// getSingleInterference - Return the single interfering virtual register
-/// assigned to PhysReg. Return 0 if more than one virtual register is
-/// interfering.
-LiveInterval *RAGreedy::getSingleInterference(LiveInterval &VirtReg,
-                                              unsigned PhysReg) {
-  // Check physreg and aliases.
-  LiveInterval *Interference = 0;
-  for (const unsigned *AliasI = TRI->getOverlaps(PhysReg); *AliasI; ++AliasI) {
-    LiveIntervalUnion::Query &Q = query(VirtReg, *AliasI);
-    if (Q.checkInterference()) {
-      if (Interference)
-        return 0;
-      if (Q.collectInterferingVRegs(2) > 1)
-        return 0;
-      Interference = Q.interferingVRegs().front();
-    }
-  }
-  return Interference;
-}
-
-// Attempt to reassign this virtual register to a different physical register.
-//
-// FIXME: we are not yet caching these "second-level" interferences discovered
-// in the sub-queries. These interferences can change with each call to
-// selectOrSplit. However, we could implement a "may-interfere" cache that
-// could be conservatively dirtied when we reassign or split.
-//
-// FIXME: This may result in a lot of alias queries. We could summarize alias
-// live intervals in their parent register's live union, but it's messy.
-bool RAGreedy::reassignVReg(LiveInterval &InterferingVReg,
-                            unsigned WantedPhysReg) {
-  assert(TargetRegisterInfo::isVirtualRegister(InterferingVReg.reg) &&
-         "Can only reassign virtual registers");
-  assert(TRI->regsOverlap(WantedPhysReg, VRM->getPhys(InterferingVReg.reg)) &&
-         "inconsistent phys reg assigment");
-
-  AllocationOrder Order(InterferingVReg.reg, *VRM, ReservedRegs);
-  while (unsigned PhysReg = Order.next()) {
-    // Don't reassign to a WantedPhysReg alias.
-    if (TRI->regsOverlap(PhysReg, WantedPhysReg))
-      continue;
-
-    if (checkUncachedInterference(InterferingVReg, PhysReg))
-      continue;
-
-    // Reassign the interfering virtual reg to this physical reg.
-    unsigned OldAssign = VRM->getPhys(InterferingVReg.reg);
-    DEBUG(dbgs() << "reassigning: " << InterferingVReg << " from " <<
-          TRI->getName(OldAssign) << " to " << TRI->getName(PhysReg) << '\n');
-    unassign(InterferingVReg, OldAssign);
-    assign(InterferingVReg, PhysReg);
-    ++NumReassigned;
-    return true;
-  }
-  return false;
-}
-
-/// tryReassign - Try to reassign a single interference to a different physreg.
-/// @param  VirtReg Currently unassigned virtual register.
-/// @param  Order   Physregs to try.
-/// @return         Physreg to assign VirtReg, or 0.
-unsigned RAGreedy::tryReassign(LiveInterval &VirtReg, AllocationOrder &Order,
-                               SmallVectorImpl<LiveInterval*> &NewVRegs){
-  NamedRegionTimer T("Reassign", TimerGroupName, TimePassesIsEnabled);
-
-  Order.rewind();
-  while (unsigned PhysReg = Order.next()) {
-    LiveInterval *InterferingVReg = getSingleInterference(VirtReg, PhysReg);
-    if (!InterferingVReg)
-      continue;
-    if (TargetRegisterInfo::isPhysicalRegister(InterferingVReg->reg))
-      continue;
-    if (reassignVReg(*InterferingVReg, PhysReg))
-      return PhysReg;
-  }
-  return 0;
-}
-
-
-//===----------------------------------------------------------------------===//
 //                         Interference eviction
 //===----------------------------------------------------------------------===//
 
@@ -851,22 +753,8 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned \
PhysReg,  SE->finish();
   ++NumGlobalSplits;
 
-  if (VerifyEnabled) {
+  if (VerifyEnabled)
     MF->verify(this, "After splitting live range around region");
-
-#ifndef NDEBUG
-    // Make sure that at least one of the new intervals can allocate to PhysReg.
-    // That was the whole point of splitting the live range.
-    bool found = false;
-    for (LiveRangeEdit::iterator I = LREdit.begin(), E = LREdit.end(); I != E;
-         ++I)
-      if (!checkUncachedInterference(**I, PhysReg)) {
-        found = true;
-        break;
-      }
-    assert(found && "No allocatable intervals after pointless splitting");
-#endif
-  }
 }
 
 unsigned RAGreedy::tryRegionSplit(LiveInterval &VirtReg, AllocationOrder &Order,
@@ -1242,10 +1130,6 @@ unsigned RAGreedy::trySplit(LiveInterval &VirtReg, \
AllocationOrder &Order,  
 unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg,
                                  SmallVectorImpl<LiveInterval*> &NewVRegs) {
-  LiveRangeStage Stage = getStage(VirtReg);
-  if (Stage == RS_Original)
-    LRStage[VirtReg.reg] = RS_Second;
-
   // First try assigning a free register.
   AllocationOrder Order(VirtReg.reg, *VRM, ReservedRegs);
   while (unsigned PhysReg = Order.next()) {
@@ -1253,9 +1137,6 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg,
       return PhysReg;
   }
 
-  if (unsigned PhysReg = tryReassign(VirtReg, Order, NewVRegs))
-    return PhysReg;
-
   if (unsigned PhysReg = tryEvict(VirtReg, Order, NewVRegs))
     return PhysReg;
 
@@ -1264,7 +1145,9 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg,
   // The first time we see a live range, don't try to split or spill.
   // Wait until the second time, when all smaller ranges have been allocated.
   // This gives a better picture of the interference to split around.
+  LiveRangeStage Stage = getStage(VirtReg);
   if (Stage == RS_Original) {
+    LRStage[VirtReg.reg] = RS_Second;
     DEBUG(dbgs() << "wait for second round\n");
     NewVRegs.push_back(&VirtReg);
     return 0;


   Commit: 60c8ee08cfc6a80ef4c2197ea1279831bb5b5887
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/27/2011 18:49:23
      URL: https://github.com/mono/llvm/commit/60c8ee08cfc6a80ef4c2197ea1279831bb5b5887


Amend debug output.

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

Changed paths:
 M lib/CodeGen/SplitKit.cpp

Modified: lib/CodeGen/SplitKit.cpp
===================================================================
--- a/lib/CodeGen/SplitKit.cpp
+++ b/lib/CodeGen/SplitKit.cpp
@@ -95,9 +95,10 @@ void SplitAnalysis::analyzeUses() {
     assert(fixed && "Couldn't fix broken live interval");
   }
 
-  DEBUG(dbgs() << "  counted "
+  DEBUG(dbgs() << "Analyze counted "
                << UsingInstrs.size() << " instrs, "
-               << UsingBlocks.size() << " blocks.\n");
+               << UsingBlocks.size() << " blocks, "
+               << LiveBlocks.size() << " spanned.\n");
 }
 
 /// calcLiveBlockInfo - Fill the LiveBlocks array with information about blocks


   Commit: f132f89e83942f879e1a4d7456d4bd90015b5c4d
   Author: Frits van Bommel <fvbommel@gmail.com>
     Date: 03/27/2011 19:32:31
      URL: https://github.com/mono/llvm/commit/f132f89e83942f879e1a4d7456d4bd90015b5c4d


Add some debug output when -instcombine uses RAUW. This can make debug output for \
those cases much clearer since without this it only showed that the original \
instruction was removed, not what it was replaced with.


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

Changed paths:
 M lib/Transforms/InstCombine/InstCombine.h

Modified: lib/Transforms/InstCombine/InstCombine.h
===================================================================
--- a/lib/Transforms/InstCombine/InstCombine.h
+++ b/lib/Transforms/InstCombine/InstCombine.h
@@ -246,7 +246,10 @@ public:
     // segment of unreachable code, so just clobber the instruction.
     if (&I == V) 
       V = UndefValue::get(I.getType());
-      
+
+    DEBUG(errs() << "IC: Replacing " << I << "\n"
+                    "    with " << *V << '\n');
+
     I.replaceAllUsesWith(V);
     return &I;
   }


   Commit: 3f298b25a8c46a69383d211c2698c1deb7098766
   Author: NAKAMURA Takumi <geek4civic@gmail.com>
     Date: 03/28/2011 02:27:06
      URL: https://github.com/mono/llvm/commit/3f298b25a8c46a69383d211c2698c1deb7098766


docs/GettingStarted.html: Add blurb "--enable-shared" on cygming.

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

Changed paths:
 M docs/GettingStarted.html

Modified: docs/GettingStarted.html
===================================================================
--- a/docs/GettingStarted.html
+++ b/docs/GettingStarted.html
@@ -268,7 +268,8 @@ software you will need.</p>
 <tr>
   <td>MinGW/Win32</td>
   <td>x86<sup><a href="#pf_1">1</a>,<a href="#pf_6">6</a>,
-     <a href="#pf_8">8</a>, <a href="#pf_10">10</a></sup></td>
+     <a href="#pf_8">8</a>, <a href="#pf_10">10</a>,
+     <a href="#pf_11">11</a></sup></td>
   <td>GCC 3.4.X, binutils 2.20</td>
 </tr>
 </table>
@@ -337,9 +338,8 @@ up</a></li>
     before any Windows-based versions such as Strawberry Perl and
     ActivePerl, as these have Windows-specifics that will cause the
     build to fail.</a></li>
-<li><a name="pf_11">In general, LLVM modules requiring dynamic linking can
-    not be built on Windows. However, you can build LLVM tools using
-    <i>"make tools-only"</i>.</li>
+<li><a name="pf_11">To use LLVM modules on Win32-based system,
+    you may configure LLVM with <i>&quot;--enable-shared&quot;</i>.</li>
 </ol>
 </div>
 


   Commit: 78b24f1d0508791ac742d6cf48c9b4695865d4b0
   Author: NAKAMURA Takumi <geek4civic@gmail.com>
     Date: 03/28/2011 02:27:12
      URL: https://github.com/mono/llvm/commit/78b24f1d0508791ac742d6cf48c9b4695865d4b0


docs/GettingStarted.html: [PR8850] Add a note for x86_64-w64-mingw32.

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

Changed paths:
 M docs/GettingStarted.html

Modified: docs/GettingStarted.html
===================================================================
--- a/docs/GettingStarted.html
+++ b/docs/GettingStarted.html
@@ -312,6 +312,11 @@ software you will need.</p>
   <td>Itanium (IA-64)</td>
   <td>HP aCC</td>
 </tr>
+<tr>
+  <td>Windows x64</td>
+  <td>x86-64</td>
+  <td>mingw-w64's GCC-4.5.x<sup><a href="#pf_12">12</a></sup></td>
+</tr>
 </table>
 
 <p><b>Notes:</b></p>
@@ -340,6 +345,8 @@ up</a></li>
     build to fail.</a></li>
 <li><a name="pf_11">To use LLVM modules on Win32-based system,
     you may configure LLVM with <i>&quot;--enable-shared&quot;</i>.</li>
+<li><a name="pf_12">To compile SPU backend, you need to add
+    <tt>&quot;LDFLAGS=-Wl,--stack,16777216&quot;</tt> to configure.</li>
 </ol>
 </div>
 


   Commit: f820344e3eb736c7309aff3b10094968f71ef1f9
   Author: Che-Liang Chiou <clchiou@gmail.com>
     Date: 03/28/2011 06:23:13
      URL: https://github.com/mono/llvm/commit/f820344e3eb736c7309aff3b10094968f71ef1f9


ptx: clean up branch code a bit

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

Changed paths:
 M lib/Target/PTX/PTXISelLowering.cpp
 M lib/Target/PTX/PTXInstrInfo.cpp
 M lib/Target/PTX/PTXInstrInfo.td

Modified: lib/Target/PTX/PTXISelLowering.cpp
===================================================================
--- a/lib/Target/PTX/PTXISelLowering.cpp
+++ b/lib/Target/PTX/PTXISelLowering.cpp
@@ -56,8 +56,6 @@ SDValue PTXTargetLowering::LowerOperation(SDValue Op, SelectionDAG \
&DAG) const {  llvm_unreachable("Unimplemented operand");
     case ISD::GlobalAddress:
       return LowerGlobalAddress(Op, DAG);
-    case ISD::BRCOND:
-      return LowerGlobalAddress(Op, DAG);
   }
 }
 
Modified: lib/Target/PTX/PTXInstrInfo.cpp
===================================================================
--- a/lib/Target/PTX/PTXInstrInfo.cpp
+++ b/lib/Target/PTX/PTXInstrInfo.cpp
@@ -247,11 +247,15 @@ AnalyzeBranch(MachineBasicBlock &MBB,
 }
 
 unsigned PTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
-  unsigned count;
-  for (count = 0; IsAnyKindOfBranch(MBB.back()); ++count)
-    MBB.pop_back();
+  unsigned count = 0;
+  while (!MBB.empty())
+    if (IsAnyKindOfBranch(MBB.back())) {
+      MBB.pop_back();
+      ++count;
+    } else
+      break;
   DEBUG(dbgs() << "RemoveBranch: MBB:   " << MBB.getName().str() << "\n");
-  DEBUG(dbgs() << "RemoveBranch: count: " << count << "\n");
+  DEBUG(dbgs() << "RemoveBranch: remove " << count << " branch inst\n");
   return count;
 }
 
@@ -262,12 +266,12 @@ InsertBranch(MachineBasicBlock &MBB,
              const SmallVectorImpl<MachineOperand> &Cond,
              DebugLoc DL) const {
   DEBUG(dbgs() << "InsertBranch: MBB: " << MBB.getName().str() << "\n");
-  DEBUG(if (TBB) dbgs() << "InsertBranch: TBB: "
-                        << TBB->getName().str() << "\n";
-      else dbgs() << "InsertBranch: TBB: (NULL)\n");
-  DEBUG(if (FBB) dbgs() << "InsertBranch: FBB: "
-                        << FBB->getName().str() << "\n";
-      else dbgs() << "InsertBranch: FBB: (NULL)\n");
+  DEBUG(if (TBB) dbgs() << "InsertBranch: TBB: " << TBB->getName().str()
+                        << "\n";
+        else     dbgs() << "InsertBranch: TBB: (NULL)\n");
+  DEBUG(if (FBB) dbgs() << "InsertBranch: FBB: " << FBB->getName().str()
+                        << "\n";
+        else     dbgs() << "InsertBranch: FBB: (NULL)\n");
   DEBUG(dbgs() << "InsertBranch: Cond size: " << Cond.size() << "\n");
 
   assert(TBB && "TBB is NULL");
Modified: lib/Target/PTX/PTXInstrInfo.td
===================================================================
--- a/lib/Target/PTX/PTXInstrInfo.td
+++ b/lib/Target/PTX/PTXInstrInfo.td
@@ -618,12 +618,11 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
 }
 
 let isBranch = 1, isTerminator = 1 in {
-  // FIXME: should be able to write a pattern for brcond, but can't use
-  //        a two-value operand where a dag node expects two operands. :(
-  // NOTE: ARM & PowerPC backend also report the same problem
+  // FIXME: The pattern part is blank because I cannot (or do not yet know
+  // how to) use the first operand of PredicateOperand (a Preds register) here
   def BRAdp
     : InstPTX<(outs), (ins brtarget:$d), "bra\t$d",
-              [/*(brcond bb:$d, Preds:$p, i32imm:$c)*/]>;
+              [/*(brcond pred:$_p, bb:$d)*/]>;
 }
 
 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {


   Commit: cdf35dc62a82bfbafbf1b7bc3626b6b87af2cf52
   Author: Jay Foad <jay.foad@gmail.com>
     Date: 03/28/2011 09:03:10
      URL: https://github.com/mono/llvm/commit/cdf35dc62a82bfbafbf1b7bc3626b6b87af2cf52


Make more use of PHINode::getNumIncomingValues().

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

Changed paths:
 M lib/Transforms/InstCombine/InstCombinePHI.cpp
 M lib/Transforms/InstCombine/InstructionCombining.cpp

Modified: lib/Transforms/InstCombine/InstCombinePHI.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ b/lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -82,7 +82,7 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
   if (LHSVal == 0) {
     NewLHS = PHINode::Create(LHSType,
                              FirstInst->getOperand(0)->getName() + ".pn");
-    NewLHS->reserveOperandSpace(PN.getNumOperands()/2);
+    NewLHS->reserveOperandSpace(PN.getNumIncomingValues());
     NewLHS->addIncoming(InLHS, PN.getIncomingBlock(0));
     InsertNewInstBefore(NewLHS, PN);
     LHSVal = NewLHS;
@@ -91,7 +91,7 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
   if (RHSVal == 0) {
     NewRHS = PHINode::Create(RHSType,
                              FirstInst->getOperand(1)->getName() + ".pn");
-    NewRHS->reserveOperandSpace(PN.getNumOperands()/2);
+    NewRHS->reserveOperandSpace(PN.getNumIncomingValues());
     NewRHS->addIncoming(InRHS, PN.getIncomingBlock(0));
     InsertNewInstBefore(NewRHS, PN);
     RHSVal = NewRHS;
@@ -341,7 +341,7 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) {
   // correct type, and PHI together all of the LHS's of the instructions.
   PHINode *NewPN = PHINode::Create(FirstLI->getOperand(0)->getType(),
                                    PN.getName()+".in");
-  NewPN->reserveOperandSpace(PN.getNumOperands()/2);
+  NewPN->reserveOperandSpace(PN.getNumIncomingValues());
   
   Value *InVal = FirstLI->getOperand(0);
   NewPN->addIncoming(InVal, PN.getIncomingBlock(0));
@@ -447,7 +447,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
   // correct type, and PHI together all of the LHS's of the instructions.
   PHINode *NewPN = PHINode::Create(FirstInst->getOperand(0)->getType(),
                                    PN.getName()+".in");
-  NewPN->reserveOperandSpace(PN.getNumOperands()/2);
+  NewPN->reserveOperandSpace(PN.getNumIncomingValues());
 
   Value *InVal = FirstInst->getOperand(0);
   NewPN->addIncoming(InVal, PN.getIncomingBlock(0));
Modified: lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -601,7 +601,7 @@ Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) {
 
   // Okay, we can do the transformation: create the new PHI node.
   PHINode *NewPN = PHINode::Create(I.getType(), "");
-  NewPN->reserveOperandSpace(PN->getNumOperands()/2);
+  NewPN->reserveOperandSpace(PN->getNumIncomingValues());
   InsertNewInstBefore(NewPN, *PN);
   NewPN->takeName(PN);
   


   Commit: 773688330ea6eeb844d23804b43bb119d5aaae29
   Author: Nick Lewycky <nicholas@mxc.ca>
     Date: 03/28/2011 13:48:26
      URL: https://github.com/mono/llvm/commit/773688330ea6eeb844d23804b43bb119d5aaae29


Remove tabs I accidentally added.


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

Changed paths:
 M lib/Transforms/InstCombine/InstCombineSelect.cpp

Modified: lib/Transforms/InstCombine/InstCombineSelect.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -227,16 +227,16 @@ Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, \
                Value *TrueVal,
             Instruction *NewSel = SelectInst::Create(SI.getCondition(), OOp, C);
             InsertNewInstBefore(NewSel, SI);
             NewSel->takeName(TVI);
-	    BinaryOperator *TVI_BO = cast<BinaryOperator>(TVI);
+            BinaryOperator *TVI_BO = cast<BinaryOperator>(TVI);
             BinaryOperator *BO = BinaryOperator::Create(TVI_BO->getOpcode(),
                                                         FalseVal, NewSel);
-	    if (isa<PossiblyExactOperator>(BO))
-	      BO->setIsExact(TVI_BO->isExact());
-	    if (isa<OverflowingBinaryOperator>(BO)) {
-	      BO->setHasNoUnsignedWrap(TVI_BO->hasNoUnsignedWrap());
-	      BO->setHasNoSignedWrap(TVI_BO->hasNoSignedWrap());
-	    }
-	    return BO;
+            if (isa<PossiblyExactOperator>(BO))
+              BO->setIsExact(TVI_BO->isExact());
+            if (isa<OverflowingBinaryOperator>(BO)) {
+              BO->setHasNoUnsignedWrap(TVI_BO->hasNoUnsignedWrap());
+              BO->setHasNoSignedWrap(TVI_BO->hasNoSignedWrap());
+            }
+            return BO;
           }
         }
       }
@@ -266,13 +266,13 @@ Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, \
Value *TrueVal,  BinaryOperator *FVI_BO = cast<BinaryOperator>(FVI);
             BinaryOperator *BO = BinaryOperator::Create(FVI_BO->getOpcode(),
                                                         TrueVal, NewSel);
-	    if (isa<PossiblyExactOperator>(BO))
-	      BO->setIsExact(FVI_BO->isExact());
-	    if (isa<OverflowingBinaryOperator>(BO)) {
-	      BO->setHasNoUnsignedWrap(FVI_BO->hasNoUnsignedWrap());
-	      BO->setHasNoSignedWrap(FVI_BO->hasNoSignedWrap());
-	    }
-	    return BO;
+            if (isa<PossiblyExactOperator>(BO))
+              BO->setIsExact(FVI_BO->isExact());
+            if (isa<OverflowingBinaryOperator>(BO)) {
+              BO->setHasNoUnsignedWrap(FVI_BO->hasNoUnsignedWrap());
+              BO->setHasNoSignedWrap(FVI_BO->hasNoSignedWrap());
+            }
+            return BO;
           }
         }
       }


   Commit: 70cde55a3cb8b269489243beb00fce84ee198f7c
   Author: Kevin Enderby <enderby@apple.com>
     Date: 03/28/2011 14:25:07
      URL: https://github.com/mono/llvm/commit/70cde55a3cb8b269489243beb00fce84ee198f7c


Again adding a C API to the disassembler for use by such tools as Darwin's
otool(1), this time with the needed fix for case sensitive file systems :) .
This is a work in progress as the interface for producing symbolic operands is
not done.  But a hacked prototype using information from the object file's
relocation entiries and replacing immediate operands with MCExpr's has been
shown to work with no changes to the instrucion printer.  These APIs will be
moved into a dynamic library at some point.


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

Added paths:
 A include/llvm-c/Disassembler.h
 A lib/MC/MCDisassembler/Disassembler.cpp
 A lib/MC/MCDisassembler/Disassembler.h

Added: include/llvm-c/Disassembler.h
===================================================================
--- /dev/null
+++ b/include/llvm-c/Disassembler.h
@@ -0,0 +1,107 @@
+/*===-- llvm-c/Disassembler.h - Disassembler Public C Interface ---*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides public interface to a disassembler library.           *|
+|* LLVM provides an implementation of this interface.                         *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_DISASSEMBLER_H
+#define LLVM_C_DISASSEMBLER_H  1
+
+#include <stdint.h>
+#include <stddef.h>
+
+/**
+ * An opaque reference to a disassembler context.
+ */
+typedef void *LLVMDisasmContextRef;
+
+/**
+ * The type for the operand information call back function.  This is called to
+ * get the symbolic information for an operand of an instruction.  Typically
+ * this is from the relocation information, symbol table, etc.  That block of
+ * information is saved when the disassembler context is created and passed to
+ * the call back in the DisInfo parameter.  The instruction containing operand
+ * is at the PC parameter.  For some instruction sets, there can be more than
+ * one operand with symbolic information.  To determine the symbolic operand
+ * infomation for each operand, the bytes for the specific operand in the
+ * instruction are specified by the Offset parameter and its byte widith is the
+ * size parameter.  For instructions sets with fixed widths and one symbolic
+ * operand per instruction, the Offset parameter will be zero and Size parameter
+ * will be the instruction width.  The information is returned in TagBuf and is 
+ * Triple specific with its specific information defined by the value of
+ * TagType for that Triple.  If symbolic information is returned the function
+ * returns 1 else it returns 0.
+ */
+typedef int (*LLVMOpInfoCallback)(void *DisInfo,
+                                  uint64_t PC,
+                                  uint64_t Offset,
+                                  uint64_t Size,
+                                  int TagType,
+                                  void *TagBuf);
+
+/**
+ * The type for the symbol lookup function.  This may be called by the
+ * disassembler for such things like adding a comment for a PC plus a constant
+ * offset load instruction to use a symbol name instead of a load address value.
+ * It is passed the block information is saved when the disassembler context is
+ * created and a value of a symbol to look up.  If no symbol is found NULL is
+ * to be returned.
+ */
+typedef const char *(*LLVMSymbolLookupCallback)(void *DisInfo,
+                                                uint64_t SymbolValue);
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* !defined(__cplusplus) */
+
+/**
+ * Create a disassembler for the TripleName.  Symbolic disassembly is supported
+ * by passing a block of information in the DisInfo parameter and specifing the
+ * TagType and call back functions as described above.  These can all be passed
+ * as NULL.  If successfull this returns a disassembler context if not it
+ * returns NULL.
+ */
+extern LLVMDisasmContextRef
+LLVMCreateDisasm(const char *TripleName,
+                 void *DisInfo,
+                 int TagType,
+                 LLVMOpInfoCallback GetOpInfo,
+                 LLVMSymbolLookupCallback SymbolLookUp);
+
+/**
+ * Dispose of a disassembler context.
+ */
+extern void
+LLVMDisasmDispose(LLVMDisasmContextRef DC);
+
+/**
+ * Disassmble a single instruction using the disassembler context specified in
+ * the parameter DC.  The bytes of the instuction are specified in the parameter
+ * Bytes, and contains at least BytesSize number of bytes.  The instruction is
+ * at the address specified by the PC parameter.  If a valid instruction can be
+ * disassembled its string is returned indirectly in OutString which whos size
+ * is specified in the parameter OutStringSize.  This function returns the
+ * number of bytes in the instruction or zero if there was no valid instruction.
+ */
+extern size_t
+LLVMDisasmInstruction(LLVMDisasmContextRef DC,
+                      uint8_t *Bytes,
+                      uint64_t BytesSize,
+                      uint64_t PC,
+                      char *OutString,
+                      size_t OutStringSize);
+
+#ifdef __cplusplus
+}
+#endif /* !defined(__cplusplus) */
+
+#endif /* !defined(LLVM_C_DISASSEMBLER_H) */
+

Added: lib/MC/MCDisassembler/Disassembler.cpp
===================================================================
--- /dev/null
+++ b/lib/MC/MCDisassembler/Disassembler.cpp
@@ -0,0 +1,170 @@
+//===-- lib/MC/Disassembler.cpp - Disassembler Public C Interface -*- C -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "Disassembler.h"
+#include <stdio.h>
+#include "llvm-c/Disassembler.h"
+
+#include <string>
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/Target/TargetRegistry.h"
+#include "llvm/Target/TargetAsmInfo.h"  // FIXME.
+#include "llvm/Target/TargetMachine.h"  // FIXME.
+#include "llvm/Target/TargetSelect.h"
+#include "llvm/Support/MemoryObject.h"
+
+namespace llvm {
+class Target;
+} // namespace llvm
+using namespace llvm;
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+//
+// LLVMCreateDisasm() creates a disassembler for the TripleName.  Symbolic
+// disassembly is supported by passing a block of information in the DisInfo
+// parameter and specifing the TagType and call back functions as described in
+// the header llvm-c/Disassembler.h .  The pointer to the block and the 
+// functions can all be passed as NULL.  If successfull this returns a
+// disassembler context if not it returns NULL.
+//
+LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo,
+                                      int TagType, LLVMOpInfoCallback GetOpInfo,
+                                      LLVMSymbolLookupCallback SymbolLookUp) {
+  // Initialize targets and assembly printers/parsers.
+  llvm::InitializeAllTargetInfos();
+  // FIXME: We shouldn't need to initialize the Target(Machine)s.
+  llvm::InitializeAllTargets();
+  llvm::InitializeAllAsmPrinters();
+  llvm::InitializeAllAsmParsers();
+  llvm::InitializeAllDisassemblers();
+
+  // Get the target.
+  std::string Error;
+  const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
+  assert(TheTarget && "Unable to create target!");
+
+  // Get the assembler info needed to setup the MCContext.
+  const MCAsmInfo *MAI = TheTarget->createAsmInfo(TripleName);
+  assert(MAI && "Unable to create target asm info!");
+
+  // Package up features to be passed to target/subtarget
+  std::string FeaturesStr;
+
+  // FIXME: We shouldn't need to do this (and link in codegen).
+  //        When we split this out, we should do it in a way that makes
+  //        it straightforward to switch subtargets on the fly.
+  TargetMachine *TM = TheTarget->createTargetMachine(TripleName, FeaturesStr);
+  assert(TM && "Unable to create target machine!");
+
+  // Get the target assembler info needed to setup the context.
+  const TargetAsmInfo *tai = new TargetAsmInfo(*TM);
+  assert(tai && "Unable to create target assembler!");
+
+  // Set up the MCContext for creating symbols and MCExpr's.
+  MCContext *Ctx = new MCContext(*MAI, tai);
+  assert(Ctx && "Unable to create MCContext!");
+
+  // Set up disassembler.
+  const MCDisassembler *DisAsm = TheTarget->createMCDisassembler();
+  assert(DisAsm && "Unable to create disassembler!");
+
+  // Set up the instruction printer.
+  int AsmPrinterVariant = MAI->getAssemblerDialect();
+  MCInstPrinter *IP = TheTarget->createMCInstPrinter(*TM, AsmPrinterVariant,
+                                                     *MAI);
+  assert(IP && "Unable to create instruction printer!");
+
+  LLVMDisasmContext *DC = new LLVMDisasmContext(TripleName, DisInfo, TagType,
+                                                GetOpInfo, SymbolLookUp,
+                                                TheTarget, MAI, TM, tai, Ctx,
+                                                DisAsm, IP);
+  assert(DC && "Allocation failure!");
+  return DC;
+}
+
+//
+// LLVMDisasmDispose() disposes of the disassembler specified by the context.
+//
+void LLVMDisasmDispose(LLVMDisasmContextRef DCR){
+  LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
+  delete DC;
+}
+
+namespace {
+//
+// The memory object created by LLVMDisasmInstruction().
+//
+class DisasmMemoryObject : public MemoryObject {
+private:
+  uint8_t *Bytes;
+  uint64_t Size;
+  uint64_t BasePC;
+public:
+  DisasmMemoryObject(uint8_t *bytes, uint64_t size, uint64_t basePC) :
+                     Bytes(bytes), Size(size), BasePC(basePC) {}
+ 
+  uint64_t getBase() const { return BasePC; }
+  uint64_t getExtent() const { return Size; }
+
+  int readByte(uint64_t Addr, uint8_t *Byte) const {
+    if (Addr - BasePC >= Size)
+      return -1;
+    *Byte = Bytes[Addr - BasePC];
+    return 0;
+  }
+};
+} // namespace
+
+//
+// LLVMDisasmInstruction() disassmbles a single instruction using the
+// disassembler context specified in the parameter DC.  The bytes of the
+// instuction are specified in the parameter Bytes, and contains at least
+// BytesSize number of bytes.  The instruction is at the address specified by
+// the PC parameter.  If a valid instruction can be disassembled its string is
+// returned indirectly in OutString which whos size is specified in the
+// parameter OutStringSize.  This function returns the number of bytes in the
+// instruction or zero if there was no valid instruction.  If this function
+// returns zero the caller will have to pick how many bytes they want to step
+// over by printing a .byte, .long etc. to continue.
+//
+size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes,
+                             uint64_t BytesSize, uint64_t PC, char *OutString,
+                             size_t OutStringSize){
+  LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
+  // Wrap the pointer to the Bytes, BytesSize and PC in a MemoryObject.
+  DisasmMemoryObject MemoryObject(Bytes, BytesSize, PC);
+
+  uint64_t Size;
+  MCInst Inst;
+  const MCDisassembler *DisAsm = DC->getDisAsm();
+  MCInstPrinter *IP = DC->getIP();
+  if (!DisAsm->getInstruction(Inst, Size, MemoryObject, PC, /*REMOVE*/ nulls()))
+    return 0;
+
+  std::string InsnStr;
+  raw_string_ostream OS(InsnStr);
+  raw_ostream &Out = OS;
+  IP->printInst(&Inst, Out);
+
+  std::string p;
+  p = OS.str();
+  snprintf(OutString, OutStringSize, "%s", p.c_str());
+  return Size;
+}
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+

Added: lib/MC/MCDisassembler/Disassembler.h
===================================================================
--- /dev/null
+++ b/lib/MC/MCDisassembler/Disassembler.h
@@ -0,0 +1,91 @@
+//===------------- Disassembler.h - LLVM Disassembler -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file defines the interface for the Disassembly library's disassembler 
+// context.  The disassembler is responsible for producing strings for
+// individual instructions according to a given architecture and disassembly
+// syntax.
+//
+//===----------------------------------------------------------------------===//
+#include "llvm-c/Disassembler.h"
+#include <string>
+#include "llvm/ADT/OwningPtr.h"
+
+namespace llvm {
+class TargetAsmInfo;
+class MCContext;
+class MCAsmInfo;
+class MCDisassembler;
+class MCInstPrinter; 
+class Target;
+class TargetMachine;
+
+//
+// This is the disassembler context returned by LLVMCreateDisasm().
+//
+class LLVMDisasmContext {
+private:
+  //
+  // The passed parameters when the disassembler context is created.
+  //
+  // The TripleName for this disassembler.
+  std::string TripleName;
+  // The pointer to the caller's block of symbolic information.
+  void *DisInfo;
+  // The Triple specific symbolic information type returned by GetOpInfo.
+  int TagType;
+  // The function to get the symbolic information for operands.
+  LLVMOpInfoCallback GetOpInfo;
+  // The function to look up a symbol name.
+  LLVMSymbolLookupCallback SymbolLookUp;
+  //
+  // The objects created and saved by LLVMCreateDisasm() then used by
+  // LLVMDisasmInstruction().
+  //
+  // The LLVM target corresponding to the disassembler.
+  // FIXME: using llvm::OwningPtr<const llvm::Target> causes a malloc error
+  //        when this LLVMDisasmContext is deleted.
+  const Target *TheTarget;
+  // The assembly information for the target architecture.
+  llvm::OwningPtr<const llvm::MCAsmInfo> MAI;
+  // The target machine instance.
+  llvm::OwningPtr<llvm::TargetMachine> TM;
+  // The disassembler for the target architecture.
+  // FIXME: using llvm::OwningPtr<const llvm::TargetAsmInfo> causes a malloc
+  //        error when this LLVMDisasmContext is deleted.
+  const TargetAsmInfo *Tai;
+  // The assembly context for creating symbols and MCExprs.
+  llvm::OwningPtr<const llvm::MCContext> Ctx;
+  // The disassembler for the target architecture.
+  llvm::OwningPtr<const llvm::MCDisassembler> DisAsm;
+  // The instruction printer for the target architecture.
+  llvm::OwningPtr<llvm::MCInstPrinter> IP;
+
+public:
+  LLVMDisasmContext(std::string tripleName, void *disInfo, int tagType,
+	  LLVMOpInfoCallback getOpInfo,
+                    LLVMSymbolLookupCallback symbolLookUp,
+                    const Target *theTarget, const MCAsmInfo *mAI,
+                    llvm::TargetMachine *tM, const TargetAsmInfo *tai,
+                    llvm::MCContext *ctx, const MCDisassembler *disAsm,
+                    MCInstPrinter *iP) : TripleName(tripleName),
+                    DisInfo(disInfo), TagType(tagType), GetOpInfo(getOpInfo),
+                    SymbolLookUp(symbolLookUp), TheTarget(theTarget), Tai(tai) {
+    TM.reset(tM);
+    MAI.reset(mAI);
+    Ctx.reset(ctx);
+    DisAsm.reset(disAsm);
+    IP.reset(iP);
+  }
+  const MCDisassembler *getDisAsm() const { return DisAsm.get(); }
+  MCInstPrinter *getIP() { return IP.get(); }
+};
+
+} // namespace llvm
+



   Commit: 0314f172480b462e1cf0a06d55d63db8f9829200
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/28/2011 14:41:58
      URL: https://github.com/mono/llvm/commit/0314f172480b462e1cf0a06d55d63db8f9829200


Fix ARM disassembly for PLD/PLDW/PLI which suffers from code rot and add some test \
cases. Add comments to ThumbDisassemblerCore.h for recent change made for t2PLD \
disassembly.


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

Changed paths:
 M lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
 M lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
 M test/MC/Disassembler/ARM/arm-tests.txt

Modified: lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
===================================================================
--- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
@@ -2893,8 +2893,8 @@ static bool DisassemblePreLoadFrm(MCInst &MI, unsigned Opcode, \
uint32_t insn,  unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
 
   // Preload Data/Instruction requires either 2 or 3 operands.
-  // PLDi, PLDWi, PLIi:                addrmode_imm12
-  // PLDr[a|m], PLDWr[a|m], PLIr[a|m]: ldst_so_reg
+  // PLDi12, PLDWi12, PLIi12: addrmode_imm12
+  // PLDrs, PLDWrs, PLIrs:    ldst_so_reg
 
   MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
                                                      decodeRn(insn))));
@@ -2903,10 +2903,19 @@ static bool DisassemblePreLoadFrm(MCInst &MI, unsigned \
Opcode, uint32_t insn,  || Opcode == ARM::PLIi12) {
     unsigned Imm12 = slice(insn, 11, 0);
     bool Negative = getUBit(insn) == 0;
+
+    // A8.6.118 PLD (literal) PLDWi12 with Rn=PC is transformed to PLDi12.
+    if (Opcode == ARM::PLDWi12 && slice(insn, 19, 16) == 0xF) {
+      DEBUG(errs() << "Rn == '1111': PLDWi12 morphed to PLDi12\n");
+      MI.setOpcode(ARM::PLDi12);
+    }
+    
     // -0 is represented specially. All other values are as normal.
+    int Offset = Negative ? -1 * Imm12 : Imm12;
     if (Imm12 == 0 && Negative)
-      Imm12 = INT32_MIN;
-    MI.addOperand(MCOperand::CreateImm(Imm12));
+      Offset = INT32_MIN;
+
+    MI.addOperand(MCOperand::CreateImm(Offset));
     NumOpsAdded = 2;
   } else {
     MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
Modified: lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
===================================================================
--- a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
+++ b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
@@ -1799,8 +1799,12 @@ static bool DisassembleThumb2PreLoad(MCInst &MI, unsigned \
Opcode, uint32_t insn,  // A8.6.117 Encoding T2: add = FALSE
       unsigned Imm8 = getImm8(insn);
       Offset = -1 * Imm8;
-    } else // The i12 forms.  See, for example, A8.6.117 Encoding T1.
+    } else {
+      // The i12 forms.  See, for example, A8.6.117 Encoding T1.
+      // Note that currently t2PLDi12 also handles the previously named t2PLDpci
+      // opcode, that's why we use decodeImm12(insn) which returns +/- imm12.
       Offset = decodeImm12(insn);
+    }
     MI.addOperand(MCOperand::CreateImm(Offset));
   }
   ++OpIdx;
Modified: test/MC/Disassembler/ARM/arm-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/arm-tests.txt
+++ b/test/MC/Disassembler/ARM/arm-tests.txt
@@ -190,3 +190,12 @@
 
 # CHECK:	umull	r1, r2, r3, r4
 0x93 0x14 0x82 0xe0
+
+# CHECK:	pld	[pc, #-0]
+0x00 0xf0 0x1f 0xf5
+
+# CHECK:	pli	[pc, #-0]
+0x00 0xf0 0x5f 0xf4
+
+# CHECK:	pli	[r3, r1, lsl #2]
+0x01 0xf1 0xd3 0xf6


   Commit: e7f3db3975cd1b943355127a113d9fce79346e67
   Author: Devang Patel <dpatel@apple.com>
     Date: 03/28/2011 16:28:30
      URL: https://github.com/mono/llvm/commit/e7f3db3975cd1b943355127a113d9fce79346e67


Remove scripts used by TEST=dbg from here. They now live inside llvm test suite.


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

Removed paths:
 D utils/CollectDebugInfoUsingLLDB.py
 D utils/CompareDebugInfo.py

   Commit: cdd0b714d5e0d268d96ab8990f01f14e9fa2bf9f
   Author: Ted Kremenek <kremenek@apple.com>
     Date: 03/28/2011 16:43:53
      URL: https://github.com/mono/llvm/commit/cdd0b714d5e0d268d96ab8990f01f14e9fa2bf9f


Unbreak CMake build.

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

Changed paths:
 M lib/MC/MCDisassembler/CMakeLists.txt

Modified: lib/MC/MCDisassembler/CMakeLists.txt
===================================================================
--- a/lib/MC/MCDisassembler/CMakeLists.txt
+++ b/lib/MC/MCDisassembler/CMakeLists.txt
@@ -1,7 +1,8 @@
 
 add_llvm_library(LLVMMCDisassembler
+  Disassembler.cpp
   EDDisassembler.cpp
-  EDOperand.cpp
   EDInst.cpp
+  EDOperand.cpp
   EDToken.cpp
   )


   Commit: 374e301a9befc808d6298a5cddd9b5597e11bcde
   Author: Daniel Dunbar <daniel@zuster.org>
     Date: 03/28/2011 18:49:15
      URL: https://github.com/mono/llvm/commit/374e301a9befc808d6298a5cddd9b5597e11bcde


MC: Add support for disabling "temporary label" behavior. Useful for debugging
on Darwin.

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

Changed paths:
 M include/llvm/MC/MCContext.h
 M lib/MC/MCContext.cpp
 M tools/llvm-mc/llvm-mc.cpp
Added paths:
 A test/MC/MachO/temp-labels.s

Modified: include/llvm/MC/MCContext.h
===================================================================
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -84,6 +84,11 @@ namespace llvm {
     MCDwarfLoc CurrentDwarfLoc;
     bool DwarfLocSeen;
 
+    /// Honor temporary labels, this is useful for debugging semantic
+    /// differences between temporary and non-temporary labels (primarily on
+    /// Darwin).
+    bool AllowTemporaryLabels;
+
     /// The dwarf line information from the .loc directives for the sections
     /// with assembled machine instructions have after seeing .loc directives.
     DenseMap<const MCSection *, MCLineSection *> MCLineSections;
@@ -109,6 +114,8 @@ namespace llvm {
 
     const TargetAsmInfo &getTargetAsmInfo() const { return *TAI; }
 
+    void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; }
+
     /// @name Symbol Management
     /// @{
 
Modified: lib/MC/MCContext.cpp
===================================================================
--- a/lib/MC/MCContext.cpp
+++ b/lib/MC/MCContext.cpp
@@ -28,7 +28,8 @@ typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;
 
 MCContext::MCContext(const MCAsmInfo &mai, const TargetAsmInfo *tai) :
   MAI(mai), TAI(tai), NextUniqueID(0),
-  CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0) {
+  CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0),
+  AllowTemporaryLabels(true) {
   MachOUniquingMap = 0;
   ELFUniquingMap = 0;
   COFFUniquingMap = 0;
@@ -76,8 +77,10 @@ MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) {
 }
 
 MCSymbol *MCContext::CreateSymbol(StringRef Name) {
-  // Determine whether this is an assembler temporary or normal label.
-  bool isTemporary = Name.startswith(MAI.getPrivateGlobalPrefix());
+  // Determine whether this is an assembler temporary or normal label, if used.
+  bool isTemporary = false;
+  if (AllowTemporaryLabels)
+    isTemporary = Name.startswith(MAI.getPrivateGlobalPrefix());
 
   StringMapEntry<bool> *NameEntry = &UsedNames.GetOrCreateValue(Name);
   if (NameEntry->getValue()) {
Modified: tools/llvm-mc/llvm-mc.cpp
===================================================================
--- a/tools/llvm-mc/llvm-mc.cpp
+++ b/tools/llvm-mc/llvm-mc.cpp
@@ -113,6 +113,10 @@ static cl::opt<bool>
 NoInitialTextSection("n", cl::desc(
                    "Don't assume assembly file starts in the text section"));
 
+static cl::opt<bool>
+SaveTempLabels("L", cl::desc(
+                 "Don't discard temporary labels"));
+
 enum ActionType {
   AC_AsLex,
   AC_Assemble,
@@ -327,6 +331,8 @@ static int AssembleInput(const char *ProgName) {
 
   const TargetAsmInfo *tai = new TargetAsmInfo(*TM);
   MCContext Ctx(*MAI, tai);
+  if (SaveTempLabels)
+    Ctx.setAllowTemporaryLabels(false);
 
   OwningPtr<tool_output_file> Out(GetOutputStream());
   if (!Out)

Added: test/MC/MachO/temp-labels.s
===================================================================
--- /dev/null
+++ b/test/MC/MachO/temp-labels.s
@@ -0,0 +1,34 @@
+// RUN: llvm-mc -triple x86_64-apple-darwin10 %s -filetype=obj -L -o - | macho-dump \
--dump-section-data | FileCheck %s +
+// CHECK:   # Load Command 1
+// CHECK:  (('command', 2)
+// CHECK:   ('size', 24)
+// CHECK:   ('symoff', 296)
+// CHECK:   ('nsyms', 2)
+// CHECK:   ('stroff', 328)
+// CHECK:   ('strsize', 8)
+// CHECK:   ('_string_data', '\x00_f0\x00L0\x00')
+// CHECK:   ('_symbols', [
+// CHECK:     # Symbol 0
+// CHECK:    (('n_strx', 1)
+// CHECK:     ('n_type', 0xe)
+// CHECK:     ('n_sect', 1)
+// CHECK:     ('n_desc', 0)
+// CHECK:     ('n_value', 0)
+// CHECK:     ('_string', '_f0')
+// CHECK:    ),
+// CHECK:     # Symbol 1
+// CHECK:    (('n_strx', 5)
+// CHECK:     ('n_type', 0xe)
+// CHECK:     ('n_sect', 1)
+// CHECK:     ('n_desc', 0)
+// CHECK:     ('n_value', 4)
+// CHECK:     ('_string', 'L0')
+// CHECK:    ),
+// CHECK:   ])
+// CHECK:  ),
+_f0:
+        .long 0
+L0:
+        .long 0
+



   Commit: 72ec393805f103dccf1c0680320c7fecfc877d1f
   Author: Daniel Dunbar <daniel@zuster.org>
     Date: 03/28/2011 18:49:19
      URL: https://github.com/mono/llvm/commit/72ec393805f103dccf1c0680320c7fecfc877d1f


Integrated-As: Add support for setting the AllowTemporaryLabels flag via
integrated-as.

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

Changed paths:
 M include/llvm/Target/TargetMachine.h
 M lib/CodeGen/LLVMTargetMachine.cpp
 M lib/Target/TargetMachine.cpp

Modified: include/llvm/Target/TargetMachine.h
===================================================================
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -106,6 +106,7 @@ protected: // Can only create subclasses.
 
   unsigned MCRelaxAll : 1;
   unsigned MCNoExecStack : 1;
+  unsigned MCSaveTempLabels : 1;
   unsigned MCUseLoc : 1;
 
 public:
@@ -172,6 +173,14 @@ public:
   /// relaxed.
   void setMCRelaxAll(bool Value) { MCRelaxAll = Value; }
 
+  /// hasMCSaveTempLabels - Check whether temporary labels will be preserved
+  /// (i.e., not treated as temporary).
+  bool hasMCSaveTempLabels() const { return MCSaveTempLabels; }
+
+  /// setMCSaveTempLabels - Set whether temporary labels will be preserved
+  /// (i.e., not treated as temporary).
+  void setMCSaveTempLabels(bool Value) { MCSaveTempLabels = Value; }
+
   /// hasMCNoExecStack - Check whether an executable stack is not needed.
   bool hasMCNoExecStack() const { return MCNoExecStack; }
 
Modified: lib/CodeGen/LLVMTargetMachine.cpp
===================================================================
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -126,6 +126,9 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
     return true;
   assert(Context != 0 && "Failed to get MCContext");
 
+  if (hasMCSaveTempLabels())
+    Context->setAllowTemporaryLabels(false);
+
   const MCAsmInfo &MAI = *getMCAsmInfo();
   OwningPtr<MCStreamer> AsmStreamer;
 
@@ -231,6 +234,9 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
   if (addCommonCodeGenPasses(PM, OptLevel, DisableVerify, Ctx))
     return true;
 
+  if (hasMCSaveTempLabels())
+    Ctx->setAllowTemporaryLabels(false);
+
   // Create the code emitter for the target if it exists.  If not, .o file
   // emission fails.
   MCCodeEmitter *MCE = getTarget().createCodeEmitter(*this, *Ctx);
Modified: lib/Target/TargetMachine.cpp
===================================================================
--- a/lib/Target/TargetMachine.cpp
+++ b/lib/Target/TargetMachine.cpp
@@ -221,6 +221,7 @@ TargetMachine::TargetMachine(const Target &T)
   : TheTarget(T), AsmInfo(0),
     MCRelaxAll(false),
     MCNoExecStack(false),
+    MCSaveTempLabels(false),
     MCUseLoc(true) {
   // Typically it will be subtargets that will adjust FloatABIType from Default
   // to Soft or Hard.


   Commit: 8a645d4c8e089fa053c1c36ab2c443b4b8545ada
   Author: Bill Wendling <isanbard@gmail.com>
     Date: 03/28/2011 19:02:18
      URL: https://github.com/mono/llvm/commit/8a645d4c8e089fa053c1c36ab2c443b4b8545ada


In some cases, the "fail BB dominator" may be null after the BB was split (and
becomes reachable when before it wasn't). Check to make sure that it's not null
before trying to use it.


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

Changed paths:
 M lib/CodeGen/StackProtector.cpp
 M test/CodeGen/X86/crash.ll

Modified: lib/CodeGen/StackProtector.cpp
===================================================================
--- a/lib/CodeGen/StackProtector.cpp
+++ b/lib/CodeGen/StackProtector.cpp
@@ -221,7 +221,8 @@ bool StackProtector::InsertStackProtectors() {
     BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return");
     if (DT && DT->isReachableFromEntry(BB)) {
       DT->addNewBlock(NewBB, BB);
-      FailBBDom = DT->findNearestCommonDominator(FailBBDom, BB);
+      if (FailBBDom)
+        FailBBDom = DT->findNearestCommonDominator(FailBBDom, BB);
     }
 
     // Remove default branch instruction to the new BB.
Modified: test/CodeGen/X86/crash.ll
===================================================================
--- a/test/CodeGen/X86/crash.ll
+++ b/test/CodeGen/X86/crash.ll
@@ -189,7 +189,7 @@ for.inc44:                                        ; preds = \
%for.body  }
 
 ; PR9028
-define void @f(i64 %A) nounwind {
+define void @func_60(i64 %A) nounwind {
 entry:
   %0 = zext i64 %A to i160
   %1 = shl i160 %0, 64
@@ -199,3 +199,19 @@ entry:
   store i576 %4, i576* undef, align 8
   ret void
 }
+
+; <rdar://problem/9187792>
+define fastcc void @func_61() nounwind sspreq {
+entry:
+  %t1 = tail call i64 @llvm.objectsize.i64(i8* undef, i1 false)
+  %t2 = icmp eq i64 %t1, -1
+  br i1 %t2, label %bb2, label %bb1
+
+bb1:
+  ret void
+
+bb2:
+  ret void
+}
+
+declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readnone


   Commit: 20cca62a561582e8354467a75158a15a1bad8920
   Author: Devang Patel <dpatel@apple.com>
     Date: 03/28/2011 20:01:39
      URL: https://github.com/mono/llvm/commit/20cca62a561582e8354467a75158a15a1bad8920


Expoert c interface for disassembler.


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

Changed paths:
 M tools/lto/Makefile
 M tools/lto/lto.exports

Modified: tools/lto/Makefile
===================================================================
--- a/tools/lto/Makefile
+++ b/tools/lto/Makefile
@@ -20,7 +20,8 @@ include $(LEVEL)/Makefile.config
 LINK_LIBS_IN_SHARED = 1
 SHARED_LIBRARY = 1
 
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) ipo scalaropts linker bitreader bitwriter
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) ipo scalaropts linker bitreader \
+	bitwriter mcdisassembler
 
 include $(LEVEL)/Makefile.common
 
Modified: tools/lto/lto.exports
===================================================================
--- a/tools/lto/lto.exports
+++ b/tools/lto/lto.exports
@@ -27,3 +27,6 @@ lto_codegen_set_assembler_args
 lto_codegen_set_assembler_path
 lto_codegen_set_cpu
 lto_codegen_compile_to_file
+LLVMCreateDisasm
+LLVMDisasmDispose
+LLVMDisasmInstruction


   Commit: 25b23c0c5ec612bc9222257e8842f0bed2c2792c
   Author: Francois Pichet <pichet2000@gmail.com>
     Date: 03/28/2011 20:30:01
      URL: https://github.com/mono/llvm/commit/25b23c0c5ec612bc9222257e8842f0bed2c2792c


Fix the MSVC build.

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

Changed paths:
 M lib/MC/MCDisassembler/Disassembler.cpp

Modified: lib/MC/MCDisassembler/Disassembler.cpp
===================================================================
--- a/lib/MC/MCDisassembler/Disassembler.cpp
+++ b/lib/MC/MCDisassembler/Disassembler.cpp
@@ -160,7 +160,11 @@ size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t \
*Bytes,  
   std::string p;
   p = OS.str();
+#ifdef LLVM_ON_WIN32
+  sprintf(OutString, "%s", p.c_str());
+#else
   snprintf(OutString, OutStringSize, "%s", p.c_str());
+#endif
   return Size;
 }
 


   Commit: a028974d8a9a6bd2b8dc07c361a90eaa586a394a
   Author: Evan Cheng <evan.cheng@apple.com>
     Date: 03/28/2011 21:56:09
      URL: https://github.com/mono/llvm/commit/a028974d8a9a6bd2b8dc07c361a90eaa586a394a


Optimizing (zext A + zext B) * C, to (VMULL A, C) + (VMULL B, C) during               \
 isel lowering to fold the zero-extend's and take advantage of no-stall
back to back vmul + vmla:
 vmull q0, d4, d6
 vmlal q0, d5, d6
is faster than
 vaddl q0, d4, d5
 vmovl q1, d6                                                                         \
  vmul  q0, q0, q1

This allows us to vmull + vmlal for:
    f = vmull_u8(   vget_high_u8(s), c);
    f = vmlal_u8(f, vget_low_u8(s),  c);

rdar://9197392


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

Changed paths:
 M lib/Target/ARM/ARMISelLowering.cpp
 M test/CodeGen/ARM/vmul.ll

Modified: lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -4370,6 +4370,28 @@ static SDValue SkipExtension(SDNode *N, SelectionDAG &DAG) {
                      MVT::getVectorVT(TruncVT, NumElts), Ops.data(), NumElts);
 }
 
+static bool isAddSubSExt(SDNode *N, SelectionDAG &DAG) {
+  unsigned Opcode = N->getOpcode();
+  if (Opcode == ISD::ADD || Opcode == ISD::SUB) {
+    SDNode *N0 = N->getOperand(0).getNode();
+    SDNode *N1 = N->getOperand(1).getNode();
+    return N0->hasOneUse() && N1->hasOneUse() &&
+      isSignExtended(N0, DAG) && isSignExtended(N1, DAG);
+  }
+  return false;
+}
+
+static bool isAddSubZExt(SDNode *N, SelectionDAG &DAG) {
+  unsigned Opcode = N->getOpcode();
+  if (Opcode == ISD::ADD || Opcode == ISD::SUB) {
+    SDNode *N0 = N->getOperand(0).getNode();
+    SDNode *N1 = N->getOperand(1).getNode();
+    return N0->hasOneUse() && N1->hasOneUse() &&
+      isZeroExtended(N0, DAG) && isZeroExtended(N1, DAG);
+  }
+  return false;
+}
+
 static SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) {
   // Multiplications are only custom-lowered for 128-bit vectors so that
   // VMULL can be detected.  Otherwise v2i64 multiplications are not legal.
@@ -4378,26 +4400,70 @@ static SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) {
   SDNode *N0 = Op.getOperand(0).getNode();
   SDNode *N1 = Op.getOperand(1).getNode();
   unsigned NewOpc = 0;
-  if (isSignExtended(N0, DAG) && isSignExtended(N1, DAG))
+  bool isMLA = false;
+  bool isN0SExt = isSignExtended(N0, DAG);
+  bool isN1SExt = isSignExtended(N1, DAG);
+  if (isN0SExt && isN1SExt)
     NewOpc = ARMISD::VMULLs;
-  else if (isZeroExtended(N0, DAG) && isZeroExtended(N1, DAG))
-    NewOpc = ARMISD::VMULLu;
-  else if (VT == MVT::v2i64)
-    // Fall through to expand this.  It is not legal.
-    return SDValue();
-  else
-    // Other vector multiplications are legal.
-    return Op;
+  else {
+    bool isN0ZExt = isZeroExtended(N0, DAG);
+    bool isN1ZExt = isZeroExtended(N1, DAG);
+    if (isN0ZExt && isN1ZExt)
+      NewOpc = ARMISD::VMULLu;
+    else if (isN1SExt || isN1ZExt) {
+      // Look for (s/zext A + s/zext B) * (s/zext C). We want to turn these
+      // into (s/zext A * s/zext C) + (s/zext B * s/zext C)
+      if (isN1SExt && isAddSubSExt(N0, DAG)) {
+        NewOpc = ARMISD::VMULLs;
+        isMLA = true;
+      } else if (isN1ZExt && isAddSubZExt(N0, DAG)) {
+        NewOpc = ARMISD::VMULLu;
+        isMLA = true;
+      } else if (isN0ZExt && isAddSubZExt(N1, DAG)) {
+        std::swap(N0, N1);
+        NewOpc = ARMISD::VMULLu;
+        isMLA = true;
+      }
+    }
+
+    if (!NewOpc) {
+      if (VT == MVT::v2i64)
+        // Fall through to expand this.  It is not legal.
+        return SDValue();
+      else
+        // Other vector multiplications are legal.
+        return Op;
+    }
+  }
 
   // Legalize to a VMULL instruction.
   DebugLoc DL = Op.getDebugLoc();
-  SDValue Op0 = SkipExtension(N0, DAG);
+  SDValue Op0;
   SDValue Op1 = SkipExtension(N1, DAG);
-
-  assert(Op0.getValueType().is64BitVector() &&
-         Op1.getValueType().is64BitVector() &&
-         "unexpected types for extended operands to VMULL");
-  return DAG.getNode(NewOpc, DL, VT, Op0, Op1);
+  if (!isMLA) {
+    Op0 = SkipExtension(N0, DAG);
+    assert(Op0.getValueType().is64BitVector() &&
+           Op1.getValueType().is64BitVector() &&
+           "unexpected types for extended operands to VMULL");
+    return DAG.getNode(NewOpc, DL, VT, Op0, Op1);
+  }
+
+  // Optimizing (zext A + zext B) * C, to (VMULL A, C) + (VMULL B, C) during
+  // isel lowering to take advantage of no-stall back to back vmul + vmla.
+  //   vmull q0, d4, d6
+  //   vmlal q0, d5, d6
+  // is faster than
+  //   vaddl q0, d4, d5
+  //   vmovl q1, d6
+  //   vmul  q0, q0, q1
+  SDValue N00 = SkipExtension(N0->getOperand(0).getNode(), DAG);
+  SDValue N01 = SkipExtension(N0->getOperand(1).getNode(), DAG);
+  EVT Op1VT = Op1.getValueType();
+  return DAG.getNode(N0->getOpcode(), DL, VT,
+                     DAG.getNode(NewOpc, DL, VT,
+                               DAG.getNode(ISD::BITCAST, DL, Op1VT, N00), Op1),
+                     DAG.getNode(NewOpc, DL, VT,
+                               DAG.getNode(ISD::BITCAST, DL, Op1VT, N01), Op1));
 }
 
 static SDValue 
Modified: test/CodeGen/ARM/vmul.ll
===================================================================
--- a/test/CodeGen/ARM/vmul.ll
+++ b/test/CodeGen/ARM/vmul.ll
@@ -339,3 +339,32 @@ define <2 x i64> @vmull_extvec_u32(<2 x i32> %arg) nounwind {
   %tmp4 = mul <2 x i64> %tmp3, <i64 1234, i64 1234>
   ret <2 x i64> %tmp4
 }
+
+; rdar://9197392
+define void @distribue(i16* %dst, i8* %src, i32 %mul) nounwind {
+entry:
+; CHECK: distribue:
+; CHECK: vmull.u8 [[REG1:(q[0-9]+)]], d{{.*}}, [[REG2:(d[0-9]+)]]
+; CHECK: vmlal.u8 [[REG1]], d{{.*}}, [[REG2]]
+  %0 = trunc i32 %mul to i8
+  %1 = insertelement <8 x i8> undef, i8 %0, i32 0
+  %2 = shufflevector <8 x i8> %1, <8 x i8> undef, <8 x i32> zeroinitializer
+  %3 = tail call <16 x i8> @llvm.arm.neon.vld1.v16i8(i8* %src, i32 1)
+  %4 = bitcast <16 x i8> %3 to <2 x double>
+  %5 = extractelement <2 x double> %4, i32 1
+  %6 = bitcast double %5 to <8 x i8>
+  %7 = zext <8 x i8> %6 to <8 x i16>
+  %8 = zext <8 x i8> %2 to <8 x i16>
+  %9 = extractelement <2 x double> %4, i32 0
+  %10 = bitcast double %9 to <8 x i8>
+  %11 = zext <8 x i8> %10 to <8 x i16>
+  %12 = add <8 x i16> %7, %11
+  %13 = mul <8 x i16> %12, %8
+  %14 = bitcast i16* %dst to i8*
+  tail call void @llvm.arm.neon.vst1.v8i16(i8* %14, <8 x i16> %13, i32 2)
+  ret void
+}
+
+declare <16 x i8> @llvm.arm.neon.vld1.v16i8(i8*, i32) nounwind readonly
+
+declare void @llvm.arm.neon.vst1.v8i16(i8*, <8 x i16>, i32) nounwind


   Commit: c72455110df33785c4ca7e26afbe720065f5af3d
   Author: Rafael Espindola <rafael.espindola@gmail.com>
     Date: 03/28/2011 22:18:54
      URL: https://github.com/mono/llvm/commit/c72455110df33785c4ca7e26afbe720065f5af3d


Reduce test case.

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

Changed paths:
 M test/CodeGen/X86/dbg-file-name.ll

Modified: test/CodeGen/X86/dbg-file-name.ll
===================================================================
--- a/test/CodeGen/X86/dbg-file-name.ll
+++ b/test/CodeGen/X86/dbg-file-name.ll
@@ -1,69 +1,19 @@
-; RUN: llc -O0 < %s | FileCheck %s
-target datalayout = \
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
                
-target triple = "x86_64-apple-darwin10.0.0"
+; RUN: llc -mtriple x86_64-apple-darwin10.0.0  < %s | FileCheck %s
 
 ; Radar 8884898
 ; CHECK: file	1 "/Users/manav/one/two/simple.c"
 
-@.str = private unnamed_addr constant [8 x i8] c"i = %d\0A\00", align 4
-@.str1 = private unnamed_addr constant [12 x i8] c"i + 1 = %d\0A\00", align 4
-
-define void @foo(i32 %i) nounwind {
-entry:
-  %i_addr = alloca i32, align 4
-  %"alloca point" = bitcast i32 0 to i32
-  call void @llvm.dbg.declare(metadata !{i32* %i_addr}, metadata !9), !dbg !10
-  store i32 %i, i32* %i_addr
-  %0 = load i32* %i_addr, align 4, !dbg !11
-  %1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([8 x i8]* @.str, i32 \
                0, i32 0), i32 %0) nounwind, !dbg !11
-  %2 = load i32* %i_addr, align 4, !dbg !13
-  %3 = add nsw i32 %2, 1, !dbg !13
-  %4 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str1, \
                i32 0, i32 0), i32 %3) nounwind, !dbg !13
-  br label %return, !dbg !14
-
-return:                                           ; preds = %entry
-  ret void, !dbg !14
-}
-
-declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
-
 declare i32 @printf(i8*, ...) nounwind
 
 define i32 @main() nounwind {
-entry:
-  %retval = alloca i32
-  %0 = alloca i32
-  %"alloca point" = bitcast i32 0 to i32
-  call void @foo(i32 2) nounwind, !dbg !15
-  call void @foo(i32 4) nounwind, !dbg !17
-  store i32 0, i32* %0, align 4, !dbg !18
-  %1 = load i32* %0, align 4, !dbg !18
-  store i32 %1, i32* %retval, align 4, !dbg !18
-  br label %return, !dbg !18
-
-return:                                           ; preds = %entry
-  %retval1 = load i32* %retval, !dbg !18
-  ret i32 %retval1, !dbg !18
+  ret i32 0
 }
 
-!llvm.dbg.sp = !{!0, !6}
+!llvm.dbg.sp = !{ !6}
 
-!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"foo", metadata !"foo", \
metadata !"foo", metadata !1, i32 4, metadata !3, i1 false, i1 true, i32 0, i32 0, \
                null, i32 256, i1 false, void (i32)* @foo} ; [ DW_TAG_subprogram ]
 !1 = metadata !{i32 589865, metadata !"simple.c", metadata !"/Users/manav/one/two", \
                metadata !2} ; [ DW_TAG_file_type ]
 !2 = metadata !{i32 589841, i32 0, i32 1, metadata !"simple.c", metadata \
!"/Users/manav/one/two", metadata !"LLVM build 00", i1 true, i1 false, metadata !"", \
                i32 0} ; [ DW_TAG_compile_unit ]
-!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, \
                i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ \
                DW_TAG_subroutine_type ]
-!4 = metadata !{null, metadata !5}
 !5 = metadata !{i32 589860, metadata !1, metadata !"int", metadata !1, i32 0, i64 \
                32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
 !6 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", \
metadata !"main", metadata !1, i32 9, metadata !7, i1 false, i1 true, i32 0, i32 0, \
                null, i32 256, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ]
 !7 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, \
                i64 0, i64 0, i32 0, null, metadata !8, i32 0, null} ; [ \
                DW_TAG_subroutine_type ]
 !8 = metadata !{metadata !5}
-!9 = metadata !{i32 590081, metadata !0, metadata !"i", metadata !1, i32 4, metadata \
                !5, i32 0} ; [ DW_TAG_arg_variable ]
-!10 = metadata !{i32 4, i32 0, metadata !0, null}
-!11 = metadata !{i32 5, i32 0, metadata !12, null}
-!12 = metadata !{i32 589835, metadata !0, i32 4, i32 0, metadata !1, i32 0} ; [ \
                DW_TAG_lexical_block ]
-!13 = metadata !{i32 6, i32 0, metadata !12, null}
-!14 = metadata !{i32 7, i32 0, metadata !12, null}
-!15 = metadata !{i32 10, i32 0, metadata !16, null}
-!16 = metadata !{i32 589835, metadata !6, i32 9, i32 0, metadata !1, i32 1} ; [ \
                DW_TAG_lexical_block ]
-!17 = metadata !{i32 11, i32 0, metadata !16, null}
-!18 = metadata !{i32 12, i32 0, metadata !16, null}


   Commit: db8fb2efbc814742fe38870835bb8f29a1bd2402
   Author: Daniel Dunbar <daniel@zuster.org>
     Date: 03/28/2011 22:30:34
      URL: https://github.com/mono/llvm/commit/db8fb2efbc814742fe38870835bb8f29a1bd2402


C-API: Include DataTypes.h instead of stdint.h.

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

Changed paths:
 M include/llvm-c/Disassembler.h

Modified: include/llvm-c/Disassembler.h
===================================================================
--- a/include/llvm-c/Disassembler.h
+++ b/include/llvm-c/Disassembler.h
@@ -15,8 +15,8 @@
 #ifndef LLVM_C_DISASSEMBLER_H
 #define LLVM_C_DISASSEMBLER_H  1
 
-#include <stdint.h>
 #include <stddef.h>
+#include "llvm/Support/DataTypes.h"
 
 /**
  * An opaque reference to a disassembler context.


   Commit: 16302e659ebac58d3dc0de1b6ca97f26a190f175
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/28/2011 23:12:02
      URL: https://github.com/mono/llvm/commit/16302e659ebac58d3dc0de1b6ca97f26a190f175


Properly enable rematerialization when spilling after live range splitting.

The instruction to be rematerialized may not be the one defining the register
that is being spilled. The traceSiblingValue() function sees through sibling
copies to find the remat candidate.

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

Changed paths:
 M lib/CodeGen/InlineSpiller.cpp
 M lib/CodeGen/LiveRangeEdit.cpp
 M lib/CodeGen/LiveRangeEdit.h

Modified: lib/CodeGen/InlineSpiller.cpp
===================================================================
--- a/lib/CodeGen/InlineSpiller.cpp
+++ b/lib/CodeGen/InlineSpiller.cpp
@@ -120,13 +120,14 @@ private:
   }
 
   bool isSibling(unsigned Reg);
-  void traceSiblingValue(unsigned, VNInfo*, VNInfo*);
+  MachineInstr *traceSiblingValue(unsigned, VNInfo*, VNInfo*);
   void analyzeSiblingValues();
 
   bool hoistSpill(LiveInterval &SpillLI, MachineInstr *CopyMI);
   void eliminateRedundantSpills(LiveInterval &LI, VNInfo *VNI);
 
-  bool reMaterializeFor(MachineBasicBlock::iterator MI);
+  void markValueUsed(LiveInterval*, VNInfo*);
+  bool reMaterializeFor(LiveInterval&, MachineBasicBlock::iterator MI);
   void reMaterializeAll();
 
   bool coalesceStackAccess(MachineInstr *MI, unsigned Reg);
@@ -277,10 +278,10 @@ bool InlineSpiller::isSibling(unsigned Reg) {
 /// Determine if the value is defined by all reloads, so spilling isn't
 /// necessary - the value is already in the stack slot.
 ///
-/// Find a defining instruction that may be a candidate for rematerialization.
+/// Return a defining instruction that may be a candidate for rematerialization.
 ///
-void InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo *UseVNI,
-                                      VNInfo *OrigVNI) {
+MachineInstr *InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo *UseVNI,
+                                               VNInfo *OrigVNI) {
   DEBUG(dbgs() << "Tracing value " << PrintReg(UseReg) << ':'
                << UseVNI->id << '@' << UseVNI->def << '\n');
   SmallPtrSet<VNInfo*, 8> Visited;
@@ -365,7 +366,7 @@ void InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo \
*UseVNI,  // We have an 'original' def. Don't record trivial cases.
     if (VNI == UseVNI) {
       DEBUG(dbgs() << "Not a sibling copy.\n");
-      return;
+      return MI;
     }
 
     // Potential remat candidate.
@@ -385,10 +386,13 @@ void InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo \
*UseVNI,  << SVI.SpillVNI->id << '@' << SVI.SpillVNI->def << '\n';
   });
   SibValues.insert(std::make_pair(UseVNI, SVI));
+  return SVI.DefMI;
 }
 
 /// analyzeSiblingValues - Trace values defined by sibling copies back to
 /// something that isn't a sibling copy.
+///
+/// Keep track of values that may be rematerializable.
 void InlineSpiller::analyzeSiblingValues() {
   SibValues.clear();
 
@@ -403,11 +407,19 @@ void InlineSpiller::analyzeSiblingValues() {
     for (LiveInterval::const_vni_iterator VI = LI.vni_begin(),
          VE = LI.vni_end(); VI != VE; ++VI) {
       VNInfo *VNI = *VI;
-      if (VNI->isUnused() || !(VNI->isPHIDef() || VNI->getCopy()))
+      if (VNI->isUnused())
         continue;
-      VNInfo *OrigVNI = OrigLI.getVNInfoAt(VNI->def);
-      if (OrigVNI->def != VNI->def)
-        traceSiblingValue(Reg, VNI, OrigVNI);
+      MachineInstr *DefMI = 0;
+      // Check possible sibling copies.
+      if (VNI->isPHIDef() || VNI->getCopy()) {
+        VNInfo *OrigVNI = OrigLI.getVNInfoAt(VNI->def);
+        if (OrigVNI->def != VNI->def)
+          DefMI = traceSiblingValue(Reg, VNI, OrigVNI);
+      }
+      if (!DefMI && !VNI->isPHIDef())
+        DefMI = LIS.getInstructionFromIndex(VNI->def);
+      if (DefMI)
+        Edit->checkRematerializable(VNI, DefMI, TII, AA);
     }
   }
 }
@@ -520,12 +532,51 @@ void InlineSpiller::eliminateRedundantSpills(LiveInterval &SLI, \
VNInfo *VNI) {  } while (!WorkList.empty());
 }
 
+
+//===----------------------------------------------------------------------===//
+//                            Rematerialization
+//===----------------------------------------------------------------------===//
+
+/// markValueUsed - Remember that VNI failed to rematerialize, so its defining
+/// instruction cannot be eliminated. See through snippet copies
+void InlineSpiller::markValueUsed(LiveInterval *LI, VNInfo *VNI) {
+  SmallVector<std::pair<LiveInterval*, VNInfo*>, 8> WorkList;
+  WorkList.push_back(std::make_pair(LI, VNI));
+  do {
+    tie(LI, VNI) = WorkList.pop_back_val();
+    if (!UsedValues.insert(VNI))
+      continue;
+
+    if (VNI->isPHIDef()) {
+      MachineBasicBlock *MBB = LIS.getMBBFromIndex(VNI->def);
+      for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
+             PE = MBB->pred_end(); PI != PE; ++PI) {
+        VNInfo *PVNI = LI->getVNInfoAt(LIS.getMBBEndIdx(*PI).getPrevSlot());
+        if (PVNI)
+          WorkList.push_back(std::make_pair(LI, PVNI));
+      }
+      continue;
+    }
+
+    // Follow snippet copies.
+    MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def);
+    if (!SnippetCopies.count(MI))
+      continue;
+    LiveInterval &SnipLI = LIS.getInterval(MI->getOperand(1).getReg());
+    assert(isRegToSpill(SnipLI.reg) && "Unexpected register in copy");
+    VNInfo *SnipVNI = SnipLI.getVNInfoAt(VNI->def.getUseIndex());
+    assert(SnipVNI && "Snippet undefined before copy");
+    WorkList.push_back(std::make_pair(&SnipLI, SnipVNI));
+  } while (!WorkList.empty());
+}
+
 /// reMaterializeFor - Attempt to rematerialize before MI instead of reloading.
-bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) {
+bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg,
+                                     MachineBasicBlock::iterator MI) {
   SlotIndex UseIdx = LIS.getInstructionIndex(MI).getUseIndex();
-  VNInfo *OrigVNI = Edit->getParent().getVNInfoAt(UseIdx);
+  VNInfo *ParentVNI = VirtReg.getVNInfoAt(UseIdx);
 
-  if (!OrigVNI) {
+  if (!ParentVNI) {
     DEBUG(dbgs() << "\tadding <undef> flags: ");
     for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
       MachineOperand &MO = MI->getOperand(i);
@@ -536,15 +587,16 @@ bool \
InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) {  return true;
   }
 
-  // FIXME: Properly remat for snippets as well.
-  if (SnippetCopies.count(MI)) {
-    UsedValues.insert(OrigVNI);
+  if (SnippetCopies.count(MI))
     return false;
-  }
 
-  LiveRangeEdit::Remat RM(OrigVNI);
+  // Use an OrigVNI from traceSiblingValue when ParentVNI is a sibling copy.
+  LiveRangeEdit::Remat RM(ParentVNI);
+  SibValueMap::const_iterator SibI = SibValues.find(ParentVNI);
+  if (SibI != SibValues.end())
+    RM.OrigMI = SibI->second.DefMI;
   if (!Edit->canRematerializeAt(RM, UseIdx, false, LIS)) {
-    UsedValues.insert(OrigVNI);
+    markValueUsed(&VirtReg, ParentVNI);
     DEBUG(dbgs() << "\tcannot remat for " << UseIdx << '\t' << *MI);
     return false;
   }
@@ -558,7 +610,7 @@ bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator \
MI) {  for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
       MachineOperand &MO = MI->getOperand(Ops[i]);
       if (MO.isUse() ? MI->isRegTiedToDefOperand(Ops[i]) : MO.getSubReg()) {
-        UsedValues.insert(OrigVNI);
+        markValueUsed(&VirtReg, ParentVNI);
         DEBUG(dbgs() << "\tcannot remat tied reg: " << UseIdx << '\t' << *MI);
         return false;
       }
@@ -606,58 +658,48 @@ bool \
InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) {  /// \
reMaterializeAll - Try to rematerialize as many uses as possible,  /// and trim the \
live ranges after.  void InlineSpiller::reMaterializeAll() {
-  // Do a quick scan of the interval values to find if any are remattable.
+  // analyzeSiblingValues has already tested all relevant defining instructions.
   if (!Edit->anyRematerializable(LIS, TII, AA))
     return;
 
   UsedValues.clear();
 
-  // Try to remat before all uses of Edit->getReg().
+  // Try to remat before all uses of snippets.
   bool anyRemat = false;
-  for (MachineRegisterInfo::use_nodbg_iterator
-       RI = MRI.use_nodbg_begin(Edit->getReg());
-       MachineInstr *MI = RI.skipInstruction();)
-     anyRemat |= reMaterializeFor(MI);
-
+  for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i) {
+    unsigned Reg = RegsToSpill[i];
+    LiveInterval &LI = LIS.getInterval(Reg);
+    for (MachineRegisterInfo::use_nodbg_iterator
+         RI = MRI.use_nodbg_begin(Reg);
+         MachineInstr *MI = RI.skipInstruction();)
+      anyRemat |= reMaterializeFor(LI, MI);
+  }
   if (!anyRemat)
     return;
 
   // Remove any values that were completely rematted.
-  bool anyRemoved = false;
-  for (LiveInterval::vni_iterator I = Edit->getParent().vni_begin(),
-       E = Edit->getParent().vni_end(); I != E; ++I) {
-    VNInfo *VNI = *I;
-    if (VNI->hasPHIKill() || !Edit->didRematerialize(VNI) ||
-        UsedValues.count(VNI))
-      continue;
-    MachineInstr *DefMI = LIS.getInstructionFromIndex(VNI->def);
-    DEBUG(dbgs() << "\tremoving dead def: " << VNI->def << '\t' << *DefMI);
-    LIS.RemoveMachineInstrFromMaps(DefMI);
-    VRM.RemoveMachineInstrFromMaps(DefMI);
-    DefMI->eraseFromParent();
-    VNI->def = SlotIndex();
-    anyRemoved = true;
-  }
-
-  if (!anyRemoved)
-    return;
-
-  // Removing values may cause debug uses where parent is not live.
-  for (MachineRegisterInfo::use_iterator RI = MRI.use_begin(Edit->getReg());
-       MachineInstr *MI = RI.skipInstruction();) {
-    if (!MI->isDebugValue())
-      continue;
-    // Try to preserve the debug value if parent is live immediately after it.
-    MachineBasicBlock::iterator NextMI = MI;
-    ++NextMI;
-    if (NextMI != MI->getParent()->end() && !LIS.isNotInMIMap(NextMI)) {
-      SlotIndex Idx = LIS.getInstructionIndex(NextMI);
-      VNInfo *VNI = Edit->getParent().getVNInfoAt(Idx);
-      if (VNI && (VNI->hasPHIKill() || UsedValues.count(VNI)))
+  for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i) {
+    unsigned Reg = RegsToSpill[i];
+    LiveInterval &LI = LIS.getInterval(Reg);
+    for (LiveInterval::vni_iterator I = LI.vni_begin(), E = LI.vni_end();
+         I != E; ++I) {
+      VNInfo *VNI = *I;
+      if (VNI->isUnused() || VNI->isPHIDef() || VNI->hasPHIKill() ||
+          UsedValues.count(VNI))
         continue;
+      MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def);
+      MI->addRegisterDead(Reg, &TRI);
+      if (!MI->allDefsAreDead())
+        continue;
+      DEBUG(dbgs() << "All defs dead: " << *MI);
+      DeadDefs.push_back(MI);
+      // Remove all Reg references so we don't insert spill code around MI.
+      for (MachineInstr::mop_iterator MOI = MI->operands_begin(),
+             MOE = MI->operands_end(); MOI != MOE ; ++MOI)
+        if (MOI->isReg() && MOI->getReg() == Reg)
+          MOI->setReg(0);
+      VNI->setIsUnused(true);
     }
-    DEBUG(dbgs() << "Removing debug info due to remat:" << "\t" << *MI);
-    MI->eraseFromParent();
   }
 }
 
Modified: lib/CodeGen/LiveRangeEdit.cpp
===================================================================
--- a/lib/CodeGen/LiveRangeEdit.cpp
+++ b/lib/CodeGen/LiveRangeEdit.cpp
@@ -34,6 +34,16 @@ LiveInterval &LiveRangeEdit::createFrom(unsigned OldReg,
   return LI;
 }
 
+void LiveRangeEdit::checkRematerializable(VNInfo *VNI,
+                                          const MachineInstr *DefMI,
+                                          const TargetInstrInfo &tii,
+                                          AliasAnalysis *aa) {
+  assert(DefMI && "Missing instruction");
+  if (tii.isTriviallyReMaterializable(DefMI, aa))
+    remattable_.insert(VNI);
+  scannedRemattable_ = true;
+}
+
 void LiveRangeEdit::scanRemattable(LiveIntervals &lis,
                                    const TargetInstrInfo &tii,
                                    AliasAnalysis *aa) {
@@ -45,10 +55,8 @@ void LiveRangeEdit::scanRemattable(LiveIntervals &lis,
     MachineInstr *DefMI = lis.getInstructionFromIndex(VNI->def);
     if (!DefMI)
       continue;
-    if (tii.isTriviallyReMaterializable(DefMI, aa))
-      remattable_.insert(VNI);
+    checkRematerializable(VNI, DefMI, tii, aa);
   }
-  scannedRemattable_ = true;
 }
 
 bool LiveRangeEdit::anyRematerializable(LiveIntervals &lis,
@@ -69,14 +77,11 @@ bool LiveRangeEdit::allUsesAvailableAt(const MachineInstr \
*OrigMI,  UseIdx = UseIdx.getUseIndex();
   for (unsigned i = 0, e = OrigMI->getNumOperands(); i != e; ++i) {
     const MachineOperand &MO = OrigMI->getOperand(i);
-    if (!MO.isReg() || !MO.getReg() || MO.getReg() == getReg())
+    if (!MO.isReg() || !MO.getReg() || MO.isDef())
       continue;
     // Reserved registers are OK.
     if (MO.isUndef() || !lis.hasInterval(MO.getReg()))
       continue;
-    // We don't want to move any defs.
-    if (MO.isDef())
-      return false;
     // We cannot depend on virtual registers in uselessRegs_.
     if (uselessRegs_)
       for (unsigned ui = 0, ue = uselessRegs_->size(); ui != ue; ++ui)
@@ -103,16 +108,22 @@ bool LiveRangeEdit::canRematerializeAt(Remat &RM,
   if (!remattable_.count(RM.ParentVNI))
     return false;
 
-  // No defining instruction.
-  RM.OrigMI = lis.getInstructionFromIndex(RM.ParentVNI->def);
-  assert(RM.OrigMI && "Defining instruction for remattable value disappeared");
+  // No defining instruction provided.
+  SlotIndex DefIdx;
+  if (RM.OrigMI)
+    DefIdx = lis.getInstructionIndex(RM.OrigMI);
+  else {
+    DefIdx = RM.ParentVNI->def;
+    RM.OrigMI = lis.getInstructionFromIndex(DefIdx);
+    assert(RM.OrigMI && "No defining instruction for remattable value");
+  }
 
   // If only cheap remats were requested, bail out early.
   if (cheapAsAMove && !RM.OrigMI->getDesc().isAsCheapAsAMove())
     return false;
 
   // Verify that all used registers are available with the same values.
-  if (!allUsesAvailableAt(RM.OrigMI, RM.ParentVNI->def, UseIdx, lis))
+  if (!allUsesAvailableAt(RM.OrigMI, DefIdx, UseIdx, lis))
     return false;
 
   return true;
Modified: lib/CodeGen/LiveRangeEdit.h
===================================================================
--- a/lib/CodeGen/LiveRangeEdit.h
+++ b/lib/CodeGen/LiveRangeEdit.h
@@ -125,6 +125,11 @@ public:
   bool anyRematerializable(LiveIntervals&, const TargetInstrInfo&,
                            AliasAnalysis*);
 
+  /// checkRematerializable - Manually add VNI to the list of rematerializable
+  /// values if DefMI may be rematerializable.
+  void checkRematerializable(VNInfo *VNI, const MachineInstr *DefMI,
+                             const TargetInstrInfo&, AliasAnalysis*);
+
   /// Remat - Information needed to rematerialize at a specific location.
   struct Remat {
     VNInfo *ParentVNI;      // parent_'s value at the remat location.


   Commit: 10ef3497d85cf7d8dc378493388bd6a086523723
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/28/2011 23:12:04
      URL: https://github.com/mono/llvm/commit/10ef3497d85cf7d8dc378493388bd6a086523723


Handle the special case when all uses follow the last split point.

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

Changed paths:
 M lib/CodeGen/SplitKit.cpp

Modified: lib/CodeGen/SplitKit.cpp
===================================================================
--- a/lib/CodeGen/SplitKit.cpp
+++ b/lib/CodeGen/SplitKit.cpp
@@ -928,7 +928,8 @@ void SplitEditor::splitSingleBlocks(const \
SplitAnalysis::BlockPtrSet &Blocks) {  continue;
 
     openIntv();
-    SlotIndex SegStart = enterIntvBefore(BI.FirstUse);
+    SlotIndex SegStart = enterIntvBefore(std::min(BI.FirstUse,
+                                                  BI.LastSplitPoint));
     if (!BI.LiveOut || BI.LastUse < BI.LastSplitPoint) {
       useIntv(SegStart, leaveIntvAfter(BI.LastUse));
     } else {


   Commit: 47615d570f4c4fc1d39c587641e230d7fa4e3d4c
   Author: Bill Wendling <isanbard@gmail.com>
     Date: 03/29/2011 00:28:26
      URL: https://github.com/mono/llvm/commit/47615d570f4c4fc1d39c587641e230d7fa4e3d4c


Spruce up the error output.

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

Changed paths:
 M lib/VMCore/Dominators.cpp

Modified: lib/VMCore/Dominators.cpp
===================================================================
--- a/lib/VMCore/Dominators.cpp
+++ b/lib/VMCore/Dominators.cpp
@@ -68,9 +68,8 @@ void DominatorTree::verifyAnalysis() const {
   DominatorTree OtherDT;
   OtherDT.getBase().recalculate(F);
   if (compare(OtherDT)) {
-    errs() << "DominatorTree is not up to date!  Computed:\n";
+    errs() << "DominatorTree is not up to date!\nComputed:\n";
     print(errs());
-    
     errs() << "\nActual:\n";
     OtherDT.print(errs());
     abort();


   Commit: abdede827190f9803bbdf8fe554ad4759b02c7c4
   Author: Bill Wendling <isanbard@gmail.com>
     Date: 03/29/2011 01:15:48
      URL: https://github.com/mono/llvm/commit/abdede827190f9803bbdf8fe554ad4759b02c7c4


Don't try to add stack protector logic to a dead basic block. It messes up
dominator information.


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

Changed paths:
 M lib/CodeGen/StackProtector.cpp

Modified: lib/CodeGen/StackProtector.cpp
===================================================================
--- a/lib/CodeGen/StackProtector.cpp
+++ b/lib/CodeGen/StackProtector.cpp
@@ -150,9 +150,11 @@ bool StackProtector::InsertStackProtectors() {
   BasicBlock *FailBBDom = 0;    // FailBB's dominator.
   AllocaInst *AI = 0;           // Place on stack that stores the stack guard.
   Value *StackGuardVar = 0;  // The stack guard variable.
+  BasicBlock &Entry = F->getEntryBlock();
 
   for (Function::iterator I = F->begin(), E = F->end(); I != E; ) {
     BasicBlock *BB = I++;
+    if (BB->getNumUses() == 0 && BB != &Entry) continue;
 
     ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator());
     if (!RI) continue;
@@ -178,7 +180,6 @@ bool StackProtector::InsertStackProtectors() {
         StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy); 
       }
 
-      BasicBlock &Entry = F->getEntryBlock();
       Instruction *InsPt = &Entry.front();
 
       AI = new AllocaInst(PtrTy, "StackGuardSlot", InsPt);


   Commit: 28fee66560ff7a058fdb67f2b3e7572821d000bf
   Author: Cameron Zwarich <zwarich@apple.com>
     Date: 03/29/2011 01:19:52
      URL: https://github.com/mono/llvm/commit/28fee66560ff7a058fdb67f2b3e7572821d000bf


Do some simple copy propagation through integer loads and stores when promoting
vector types. This helps a lot with inlined functions when using the ARM soft
float ABI. Fixes <rdar://problem/9184212>.

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

Changed paths:
 M lib/Transforms/Scalar/ScalarReplAggregates.cpp
 M test/Transforms/ScalarRepl/vector_promote.ll
Added paths:
 A test/Transforms/ScalarRepl/inline-vector.ll

Modified: lib/Transforms/Scalar/ScalarReplAggregates.cpp
===================================================================
--- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp
+++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
@@ -252,7 +252,7 @@ public:
 
 private:
   bool CanConvertToScalar(Value *V, uint64_t Offset);
-  void MergeInType(const Type *In, uint64_t Offset);
+  void MergeInType(const Type *In, uint64_t Offset, bool IsLoadOrStore);
   bool MergeInVectorType(const VectorType *VInTy, uint64_t Offset);
   void ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset);
 
@@ -315,7 +315,8 @@ AllocaInst *ConvertToScalarInfo::TryConvert(AllocaInst *AI) {
 ///      large) integer type with extract and insert operations where the loads
 ///      and stores would mutate the memory.  We mark this by setting VectorTy
 ///      to VoidTy.
-void ConvertToScalarInfo::MergeInType(const Type *In, uint64_t Offset) {
+void ConvertToScalarInfo::MergeInType(const Type *In, uint64_t Offset,
+                                      bool IsLoadOrStore) {
   // If we already decided to turn this into a blob of integer memory, there is
   // nothing to be done.
   if (VectorTy && VectorTy->isVoidTy())
@@ -331,10 +332,14 @@ void ConvertToScalarInfo::MergeInType(const Type *In, uint64_t \
Offset) {  } else if (In->isFloatTy() || In->isDoubleTy() ||
              (In->isIntegerTy() && In->getPrimitiveSizeInBits() >= 8 &&
               isPowerOf2_32(In->getPrimitiveSizeInBits()))) {
+    // Full width accesses can be ignored, because they can always be turned
+    // into bitcasts.
+    unsigned EltSize = In->getPrimitiveSizeInBits()/8;
+    if (IsLoadOrStore && EltSize == AllocaSize)
+      return;
     // If we're accessing something that could be an element of a vector, see
     // if the implied vector agrees with what we already have and if Offset is
     // compatible with it.
-    unsigned EltSize = In->getPrimitiveSizeInBits()/8;
     if (Offset % EltSize == 0 && AllocaSize % EltSize == 0 &&
         (VectorTy == 0 ||
          cast<VectorType>(VectorTy)->getElementType()
@@ -442,7 +447,7 @@ bool ConvertToScalarInfo::CanConvertToScalar(Value *V, uint64_t \
Offset) {  if (LI->getType()->isX86_MMXTy())
         return false;
       HadNonMemTransferAccess = true;
-      MergeInType(LI->getType(), Offset);
+      MergeInType(LI->getType(), Offset, true);
       continue;
     }
 
@@ -453,7 +458,7 @@ bool ConvertToScalarInfo::CanConvertToScalar(Value *V, uint64_t \
Offset) {  if (SI->getOperand(0)->getType()->isX86_MMXTy())
         return false;
       HadNonMemTransferAccess = true;
-      MergeInType(SI->getOperand(0)->getType(), Offset);
+      MergeInType(SI->getOperand(0)->getType(), Offset, true);
       continue;
     }
 
@@ -691,11 +696,11 @@ ConvertScalar_ExtractValue(Value *FromVal, const Type *ToType,
   // If the result alloca is a vector type, this is either an element
   // access or a bitcast to another vector type of the same size.
   if (const VectorType *VTy = dyn_cast<VectorType>(FromVal->getType())) {
-    if (ToType->isVectorTy()) {
-      unsigned ToTypeSize = TD.getTypeAllocSize(ToType);
-      if (ToTypeSize == AllocaSize)
-        return Builder.CreateBitCast(FromVal, ToType, "tmp");
+    unsigned ToTypeSize = TD.getTypeAllocSize(ToType);
+    if (ToTypeSize == AllocaSize)
+      return Builder.CreateBitCast(FromVal, ToType, "tmp");
 
+    if (ToType->isVectorTy()) {
       assert(isPowerOf2_64(AllocaSize / ToTypeSize) &&
              "Partial vector access of an alloca must have a power-of-2 size "
              "ratio.");
Modified: test/Transforms/ScalarRepl/vector_promote.ll
===================================================================
--- a/test/Transforms/ScalarRepl/vector_promote.ll
+++ b/test/Transforms/ScalarRepl/vector_promote.ll
@@ -94,7 +94,7 @@ define i64 @test6(<2 x float> %X) {
 	%tmp = load i64* %P
 	ret i64 %tmp
 ; CHECK: @test6
-; CHECK: bitcast <2 x float> %X to <1 x i64>
+; CHECK: bitcast <2 x float> %X to i64
 ; CHECK: ret i64
 }
 

Added: test/Transforms/ScalarRepl/inline-vector.ll
===================================================================
--- /dev/null
+++ b/test/Transforms/ScalarRepl/inline-vector.ll
@@ -0,0 +1,54 @@
+; RUN: opt < %s -scalarrepl -S | FileCheck %s
+; RUN: opt < %s -scalarrepl-ssa -S | FileCheck %s
+target datalayout = \
"e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32"
 +target triple = "thumbv7-apple-darwin10.0.0"
+
+%struct.Vector4 = type { float, float, float, float }
+@f.vector = internal constant %struct.Vector4 { float 1.000000e+00, float \
2.000000e+00, float 3.000000e+00, float 4.000000e+00 }, align 16 +
+; CHECK: define void @f
+; CHECK-NOT: alloca
+; CHECK: phi <4 x float>
+
+define void @f() nounwind ssp {
+entry:
+  %i = alloca i32, align 4
+  %vector = alloca %struct.Vector4, align 16
+  %agg.tmp = alloca %struct.Vector4, align 16
+  %tmp = bitcast %struct.Vector4* %vector to i8*
+  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %tmp, i8* bitcast (%struct.Vector4* \
@f.vector to i8*), i32 16, i32 16, i1 false) +  br label %for.cond
+
+for.cond:                                         ; preds = %for.body, %entry
+  %storemerge = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+  store i32 %storemerge, i32* %i, align 4
+  %cmp = icmp slt i32 %storemerge, 1000000
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %tmp2 = bitcast %struct.Vector4* %agg.tmp to i8*
+  %tmp3 = bitcast %struct.Vector4* %vector to i8*
+  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %tmp2, i8* %tmp3, i32 16, i32 16, i1 \
false) +  %0 = bitcast %struct.Vector4* %agg.tmp to [2 x i64]*
+  %1 = load [2 x i64]* %0, align 16
+  %tmp2.i = extractvalue [2 x i64] %1, 0
+  %tmp3.i = zext i64 %tmp2.i to i128
+  %tmp10.i = bitcast i128 %tmp3.i to <4 x float>
+  %sub.i.i = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float \
-0.000000e+00, float -0.000000e+00>, %tmp10.i +  %2 = bitcast %struct.Vector4* \
%vector to <4 x float>* +  store <4 x float> %sub.i.i, <4 x float>* %2, align 16
+  %tmp4 = load i32* %i, align 4
+  %inc = add nsw i32 %tmp4, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  %x = getelementptr inbounds %struct.Vector4* %vector, i32 0, i32 0
+  %tmp5 = load float* %x, align 16
+  %conv = fpext float %tmp5 to double
+  %call = call i32 (...)* @printf(double %conv) nounwind
+  ret void
+}
+
+declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) \
nounwind +declare i32 @printf(...)
+



   Commit: 2af25ee1668246f07e635fe0535b29f749bfe382
   Author: Bill Wendling <isanbard@gmail.com>
     Date: 03/29/2011 03:28:52
      URL: https://github.com/mono/llvm/commit/2af25ee1668246f07e635fe0535b29f749bfe382


Rework the logic (and removing the bad check for an unreachable block) so that
the FailBB dominator is correctly calculated. Believe it or not, there isn't a
functionality change here.


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

Changed paths:
 M lib/CodeGen/StackProtector.cpp

Modified: lib/CodeGen/StackProtector.cpp
===================================================================
--- a/lib/CodeGen/StackProtector.cpp
+++ b/lib/CodeGen/StackProtector.cpp
@@ -150,12 +150,9 @@ bool StackProtector::InsertStackProtectors() {
   BasicBlock *FailBBDom = 0;    // FailBB's dominator.
   AllocaInst *AI = 0;           // Place on stack that stores the stack guard.
   Value *StackGuardVar = 0;  // The stack guard variable.
-  BasicBlock &Entry = F->getEntryBlock();
 
   for (Function::iterator I = F->begin(), E = F->end(); I != E; ) {
     BasicBlock *BB = I++;
-    if (BB->getNumUses() == 0 && BB != &Entry) continue;
-
     ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator());
     if (!RI) continue;
 
@@ -180,6 +177,7 @@ bool StackProtector::InsertStackProtectors() {
         StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy); 
       }
 
+      BasicBlock &Entry = F->getEntryBlock();
       Instruction *InsPt = &Entry.front();
 
       AI = new AllocaInst(PtrTy, "StackGuardSlot", InsPt);
@@ -192,8 +190,6 @@ bool StackProtector::InsertStackProtectors() {
 
       // Create the basic block to jump to when the guard check fails.
       FailBB = CreateFailBB();
-      if (DT)
-        FailBBDom = DT->isReachableFromEntry(BB) ? BB : 0;
     }
 
     // For each block with a return instruction, convert this:
@@ -219,11 +215,12 @@ bool StackProtector::InsertStackProtectors() {
     //     unreachable
 
     // Split the basic block before the return instruction.
+    bool BBIsReachable = (DT && DT->isReachableFromEntry(BB));
     BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return");
-    if (DT && DT->isReachableFromEntry(BB)) {
+
+    if (BBIsReachable) {
       DT->addNewBlock(NewBB, BB);
-      if (FailBBDom)
-        FailBBDom = DT->findNearestCommonDominator(FailBBDom, BB);
+      FailBBDom = FailBBDom ? DT->findNearestCommonDominator(FailBBDom, BB) :BB;
     }
 
     // Remove default branch instruction to the new BB.


   Commit: 6d1d3ebbc9b451c8d14a03024b82c7de0e738a86
   Author: Owen Anderson <resistor@mac.com>
     Date: 03/29/2011 12:45:53
      URL: https://github.com/mono/llvm/commit/6d1d3ebbc9b451c8d14a03024b82c7de0e738a86


Get rid of the non-writeback versions VLDMDB and VSTMDB, which don't actually exist.


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

Changed paths:
 M lib/Target/ARM/ARMBaseInstrInfo.cpp
 M lib/Target/ARM/ARMExpandPseudoInsts.cpp
 M lib/Target/ARM/ARMInstrNEON.td
 M lib/Target/ARM/ARMInstrVFP.td
 M lib/Target/ARM/ARMLoadStoreOptimizer.cpp
 M lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
 M test/MC/Disassembler/ARM/arm-tests.txt
 M test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt

Modified: lib/Target/ARM/ARMBaseInstrInfo.cpp
===================================================================
--- a/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -1789,9 +1789,7 @@ ARMBaseInstrInfo::getNumMicroOps(const InstrItineraryData \
*ItinData,  llvm_unreachable("Unexpected multi-uops instruction!");
     break;
   case ARM::VLDMQIA:
-  case ARM::VLDMQDB:
   case ARM::VSTMQIA:
-  case ARM::VSTMQDB:
     return 2;
 
   // The number of uOps for load / store multiple are determined by the number
@@ -1805,19 +1803,15 @@ ARMBaseInstrInfo::getNumMicroOps(const InstrItineraryData \
*ItinData,  // is not 64-bit aligned, then AGU would take an extra cycle.  For VFP / \
NEON  // load / store multiple, the formula is (#reg / 2) + (#reg % 2) + 1.
   case ARM::VLDMDIA:
-  case ARM::VLDMDDB:
   case ARM::VLDMDIA_UPD:
   case ARM::VLDMDDB_UPD:
   case ARM::VLDMSIA:
-  case ARM::VLDMSDB:
   case ARM::VLDMSIA_UPD:
   case ARM::VLDMSDB_UPD:
   case ARM::VSTMDIA:
-  case ARM::VSTMDDB:
   case ARM::VSTMDIA_UPD:
   case ARM::VSTMDDB_UPD:
   case ARM::VSTMSIA:
-  case ARM::VSTMSDB:
   case ARM::VSTMSIA_UPD:
   case ARM::VSTMSDB_UPD: {
     unsigned NumRegs = MI->getNumOperands() - Desc.getNumOperands();
@@ -1907,7 +1901,6 @@ ARMBaseInstrInfo::getVLDMDefCycle(const InstrItineraryData \
*ItinData,  switch (DefTID.getOpcode()) {
     default: break;
     case ARM::VLDMSIA:
-    case ARM::VLDMSDB:
     case ARM::VLDMSIA_UPD:
     case ARM::VLDMSDB_UPD:
       isSLoad = true;
@@ -1983,7 +1976,6 @@ ARMBaseInstrInfo::getVSTMUseCycle(const InstrItineraryData \
*ItinData,  switch (UseTID.getOpcode()) {
     default: break;
     case ARM::VSTMSIA:
-    case ARM::VSTMSDB:
     case ARM::VSTMSIA_UPD:
     case ARM::VSTMSDB_UPD:
       isSStore = true;
@@ -2054,11 +2046,9 @@ ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData \
*ItinData,  break;
 
   case ARM::VLDMDIA:
-  case ARM::VLDMDDB:
   case ARM::VLDMDIA_UPD:
   case ARM::VLDMDDB_UPD:
   case ARM::VLDMSIA:
-  case ARM::VLDMSDB:
   case ARM::VLDMSIA_UPD:
   case ARM::VLDMSDB_UPD:
     DefCycle = getVLDMDefCycle(ItinData, DefTID, DefClass, DefIdx, DefAlign);
@@ -2097,11 +2087,9 @@ ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData \
*ItinData,  break;
 
   case ARM::VSTMDIA:
-  case ARM::VSTMDDB:
   case ARM::VSTMDIA_UPD:
   case ARM::VSTMDDB_UPD:
   case ARM::VSTMSIA:
-  case ARM::VSTMSDB:
   case ARM::VSTMSIA_UPD:
   case ARM::VSTMSDB_UPD:
     UseCycle = getVSTMUseCycle(ItinData, UseTID, UseClass, UseIdx, UseAlign);
@@ -2312,9 +2300,7 @@ int ARMBaseInstrInfo::getInstrLatency(const InstrItineraryData \
*ItinData,  default:
     return ItinData->getStageLatency(get(Opcode).getSchedClass());
   case ARM::VLDMQIA:
-  case ARM::VLDMQDB:
   case ARM::VSTMQIA:
-  case ARM::VSTMQDB:
     return 2;
   }
 }
Modified: lib/Target/ARM/ARMExpandPseudoInsts.cpp
===================================================================
--- a/lib/Target/ARM/ARMExpandPseudoInsts.cpp
+++ b/lib/Target/ARM/ARMExpandPseudoInsts.cpp
@@ -967,9 +967,8 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
       return true;
     }
 
-    case ARM::VLDMQIA:
-    case ARM::VLDMQDB: {
-      unsigned NewOpc = (Opcode == ARM::VLDMQIA) ? ARM::VLDMDIA : ARM::VLDMDDB;
+    case ARM::VLDMQIA: {
+      unsigned NewOpc = ARM::VLDMDIA;
       MachineInstrBuilder MIB =
         BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc));
       unsigned OpIdx = 0;
@@ -998,9 +997,8 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
       return true;
     }
 
-    case ARM::VSTMQIA:
-    case ARM::VSTMQDB: {
-      unsigned NewOpc = (Opcode == ARM::VSTMQIA) ? ARM::VSTMDIA : ARM::VSTMDDB;
+    case ARM::VSTMQIA: {
+      unsigned NewOpc = ARM::VSTMDIA;
       MachineInstrBuilder MIB =
         BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc));
       unsigned OpIdx = 0;
Modified: lib/Target/ARM/ARMInstrNEON.td
===================================================================
--- a/lib/Target/ARM/ARMInstrNEON.td
+++ b/lib/Target/ARM/ARMInstrNEON.td
@@ -146,10 +146,6 @@ def VLDMQIA
   : PseudoVFPLdStM<(outs QPR:$dst), (ins GPR:$Rn),
                     IIC_fpLoad_m, "",
                    [(set QPR:$dst, (v2f64 (load GPR:$Rn)))]>;
-def VLDMQDB
-  : PseudoVFPLdStM<(outs QPR:$dst), (ins GPR:$Rn),
-                    IIC_fpLoad_m, "",
-                   [(set QPR:$dst, (v2f64 (load GPR:$Rn)))]>;
 
 // Use VSTM to store a Q register as a D register pair.
 // This is a pseudo instruction that is expanded to VSTMD after reg alloc.
@@ -157,10 +153,6 @@ def VSTMQIA
   : PseudoVFPLdStM<(outs), (ins QPR:$src, GPR:$Rn),
                     IIC_fpStore_m, "",
                    [(store (v2f64 QPR:$src), GPR:$Rn)]>;
-def VSTMQDB
-  : PseudoVFPLdStM<(outs), (ins QPR:$src, GPR:$Rn),
-                    IIC_fpStore_m, "",
-                   [(store (v2f64 QPR:$src), GPR:$Rn)]>;
 
 // Classes for VLD* pseudo-instructions with multi-register operands.
 // These are expanded to real instructions after register allocation.
Modified: lib/Target/ARM/ARMInstrVFP.td
===================================================================
--- a/lib/Target/ARM/ARMInstrVFP.td
+++ b/lib/Target/ARM/ARMInstrVFP.td
@@ -101,14 +101,6 @@ multiclass vfp_ldst_mult<string asm, bit L_bit,
     let Inst{21}    = 1;          // Writeback
     let Inst{20}    = L_bit;
   }
-  def DDB :
-    AXDI4<(outs), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops),
-          IndexModeNone, itin,
-          !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
-    let Inst{24-23} = 0b10;       // Decrement Before
-    let Inst{21}    = 0;          // No writeback
-    let Inst{20}    = L_bit;
-  }
   def DDB_UPD :
     AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops),
           IndexModeUpd, itin_upd,
@@ -143,18 +135,6 @@ multiclass vfp_ldst_mult<string asm, bit L_bit,
     // VFP pipelines.
     let D = VFPNeonDomain;
   }
-  def SDB :
-    AXSI4<(outs), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, variable_ops),
-          IndexModeNone, itin,
-          !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
-    let Inst{24-23} = 0b10;       // Decrement Before
-    let Inst{21}    = 0;          // No writeback
-    let Inst{20}    = L_bit;
-
-    // Some single precision VFP instructions may be executed on both NEON and
-    // VFP pipelines.
-    let D = VFPNeonDomain;
-  }
   def SDB_UPD :
     AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, variable_ops),
           IndexModeUpd, itin_upd,
Modified: lib/Target/ARM/ARMLoadStoreOptimizer.cpp
===================================================================
--- a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
+++ b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -79,7 +79,7 @@ namespace {
       unsigned Position;
       MachineBasicBlock::iterator MBBI;
       bool Merged;
-      MemOpQueueEntry(int o, unsigned r, bool k, unsigned p, 
+      MemOpQueueEntry(int o, unsigned r, bool k, unsigned p,
                       MachineBasicBlock::iterator i)
         : Offset(o), Reg(r), isKill(k), Position(p), MBBI(i), Merged(false) {}
     };
@@ -174,7 +174,7 @@ static int getLoadStoreMultipleOpcode(int Opcode, \
ARM_AM::AMSubMode Mode) {  switch (Mode) {
     default: llvm_unreachable("Unhandled submode!");
     case ARM_AM::ia: return ARM::VLDMSIA;
-    case ARM_AM::db: return ARM::VLDMSDB;
+    case ARM_AM::db: return 0; // Only VLDMSDB_UPD exists.
     }
     break;
   case ARM::VSTRS:
@@ -182,7 +182,7 @@ static int getLoadStoreMultipleOpcode(int Opcode, \
ARM_AM::AMSubMode Mode) {  switch (Mode) {
     default: llvm_unreachable("Unhandled submode!");
     case ARM_AM::ia: return ARM::VSTMSIA;
-    case ARM_AM::db: return ARM::VSTMSDB;
+    case ARM_AM::db: return 0; // Only VSTMSDB_UPD exists.
     }
     break;
   case ARM::VLDRD:
@@ -190,7 +190,7 @@ static int getLoadStoreMultipleOpcode(int Opcode, \
ARM_AM::AMSubMode Mode) {  switch (Mode) {
     default: llvm_unreachable("Unhandled submode!");
     case ARM_AM::ia: return ARM::VLDMDIA;
-    case ARM_AM::db: return ARM::VLDMDDB;
+    case ARM_AM::db: return 0; // Only VLDMDDB_UPD exists.
     }
     break;
   case ARM::VSTRD:
@@ -198,7 +198,7 @@ static int getLoadStoreMultipleOpcode(int Opcode, \
ARM_AM::AMSubMode Mode) {  switch (Mode) {
     default: llvm_unreachable("Unhandled submode!");
     case ARM_AM::ia: return ARM::VSTMDIA;
-    case ARM_AM::db: return ARM::VSTMDDB;
+    case ARM_AM::db: return 0; // Only VSTMDDB_UPD exists.
     }
     break;
   }
@@ -246,13 +246,9 @@ AMSubMode getLoadStoreMultipleSubMode(int Opcode) {
   case ARM::t2LDMDB_UPD:
   case ARM::t2STMDB:
   case ARM::t2STMDB_UPD:
-  case ARM::VLDMSDB:
   case ARM::VLDMSDB_UPD:
-  case ARM::VSTMSDB:
   case ARM::VSTMSDB_UPD:
-  case ARM::VLDMDDB:
   case ARM::VLDMDDB_UPD:
-  case ARM::VSTMDDB:
   case ARM::VSTMDDB_UPD:
     return ARM_AM::db;
 
@@ -567,14 +563,10 @@ static inline unsigned getLSMultipleTransferSize(MachineInstr \
*MI) {  case ARM::t2STMIA:
   case ARM::t2STMDB:
   case ARM::VLDMSIA:
-  case ARM::VLDMSDB:
   case ARM::VSTMSIA:
-  case ARM::VSTMSDB:
     return (MI->getNumOperands() - MI->getDesc().getNumOperands() + 1) * 4;
   case ARM::VLDMDIA:
-  case ARM::VLDMDDB:
   case ARM::VSTMDIA:
-  case ARM::VSTMDDB:
     return (MI->getNumOperands() - MI->getDesc().getNumOperands() + 1) * 8;
   }
 }
@@ -624,7 +616,6 @@ static unsigned getUpdatingLSMultipleOpcode(unsigned Opc,
     }
     break;
   case ARM::VLDMSIA:
-  case ARM::VLDMSDB:
     switch (Mode) {
     default: llvm_unreachable("Unhandled submode!");
     case ARM_AM::ia: return ARM::VLDMSIA_UPD;
@@ -632,7 +623,6 @@ static unsigned getUpdatingLSMultipleOpcode(unsigned Opc,
     }
     break;
   case ARM::VLDMDIA:
-  case ARM::VLDMDDB:
     switch (Mode) {
     default: llvm_unreachable("Unhandled submode!");
     case ARM_AM::ia: return ARM::VLDMDIA_UPD;
@@ -640,7 +630,6 @@ static unsigned getUpdatingLSMultipleOpcode(unsigned Opc,
     }
     break;
   case ARM::VSTMSIA:
-  case ARM::VSTMSDB:
     switch (Mode) {
     default: llvm_unreachable("Unhandled submode!");
     case ARM_AM::ia: return ARM::VSTMSIA_UPD;
@@ -648,7 +637,6 @@ static unsigned getUpdatingLSMultipleOpcode(unsigned Opc,
     }
     break;
   case ARM::VSTMDIA:
-  case ARM::VSTMDDB:
     switch (Mode) {
     default: llvm_unreachable("Unhandled submode!");
     case ARM_AM::ia: return ARM::VSTMDIA_UPD;
Modified: lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
===================================================================
--- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
@@ -1123,7 +1123,7 @@ static bool HasDualReg(unsigned Opcode) {
   case ARM::LDRD: case ARM::LDRD_PRE: case ARM::LDRD_POST:
   case ARM::STRD: case ARM::STRD_PRE: case ARM::STRD_POST:
     return true;
-  }  
+  }
 }
 
 static bool DisassembleLdStMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
@@ -1610,7 +1610,7 @@ static bool DisassembleVFPBinaryFrm(MCInst &MI, unsigned \
Opcode, uint32_t insn,  // A8.6.295 vcvt (floating-point <-> integer)
 // Int to FP: VSITOD, VSITOS, VUITOD, VUITOS
 // FP to Int: VTOSI[Z|R]D, VTOSI[Z|R]S, VTOUI[Z|R]D, VTOUI[Z|R]S
-// 
+//
 // A8.6.297 vcvt (floating-point and fixed-point)
 // Dd|Sd Dd|Sd(TIED_TO) #fbits(= 16|32 - UInt(imm4:i))
 static bool DisassembleVFPConv1Frm(MCInst &MI, unsigned Opcode, uint32_t insn,
@@ -1832,9 +1832,9 @@ static bool DisassembleVFPLdStMulFrm(MCInst &MI, unsigned \
Opcode, uint32_t insn,  
   OpIdx += 3;
 
-  bool isSPVFP = (Opcode == ARM::VLDMSIA     || Opcode == ARM::VLDMSDB     ||
+  bool isSPVFP = (Opcode == ARM::VLDMSIA     ||
                   Opcode == ARM::VLDMSIA_UPD || Opcode == ARM::VLDMSDB_UPD ||
-                  Opcode == ARM::VSTMSIA     || Opcode == ARM::VSTMSDB     ||
+                  Opcode == ARM::VSTMSIA     ||
                   Opcode == ARM::VSTMSIA_UPD || Opcode == ARM::VSTMSDB_UPD);
   unsigned RegClassID = isSPVFP ? ARM::SPRRegClassID : ARM::DPRRegClassID;
 
@@ -1848,7 +1848,7 @@ static bool DisassembleVFPLdStMulFrm(MCInst &MI, unsigned \
Opcode, uint32_t insn,  // Apply some sanity checks before proceeding.
   if (Regs == 0 || (RegD + Regs) > 32 || (!isSPVFP && Regs > 16))
     return false;
-  
+
   for (unsigned i = 0; i < Regs; ++i) {
     MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassID,
                                                        RegD + i)));
@@ -2286,15 +2286,15 @@ static bool DisassembleNLdSt(MCInst &MI, unsigned Opcode, \
uint32_t insn,  // n == 2 && type == 0b1001 -> DblSpaced = true
     if (Name.startswith("VST2") || Name.startswith("VLD2"))
       DblSpaced = slice(insn, 11, 8) == 9;
-    
+
     // n == 3 && type == 0b0101 -> DblSpaced = true
     if (Name.startswith("VST3") || Name.startswith("VLD3"))
       DblSpaced = slice(insn, 11, 8) == 5;
-    
+
     // n == 4 && type == 0b0001 -> DblSpaced = true
     if (Name.startswith("VST4") || Name.startswith("VLD4"))
       DblSpaced = slice(insn, 11, 8) == 1;
-    
+
   }
   return DisassembleNLdSt0(MI, Opcode, insn, NumOps, NumOpsAdded,
                            slice(insn, 21, 21) == 0, DblSpaced, B);
@@ -2391,7 +2391,7 @@ enum N2VFlag {
 //
 // Vector Move Long:
 //   Qd Dm
-// 
+//
 // Vector Move Narrow:
 //   Dd Qm
 //
@@ -2533,7 +2533,7 @@ static bool DisassembleNVectorShift(MCInst &MI, unsigned \
Opcode, uint32_t insn,  assert(OpInfo[OpIdx].RegClass < 0 && "Imm operand expected");
 
   // Add the imm operand.
-  
+
   // VSHLL has maximum shift count as the imm, inferred from its size.
   unsigned Imm;
   switch (Opcode) {
@@ -2646,7 +2646,7 @@ static bool DisassembleNVdVnVmOptImm(MCInst &MI, unsigned \
Opcode, uint32_t insn,  // N3RegFrm.
   if (Opcode == ARM::VMOVDneon || Opcode == ARM::VMOVQ)
     return true;
-  
+
   // Dm = Inst{5:3-0} => NEON Rm
   // or
   // Dm is restricted to D0-D7 if size is 16, D0-D15 otherwise
@@ -3183,7 +3183,7 @@ bool ARMBasicMCBuilder::DoPredicateOperands(MCInst& MI, \
unsigned Opcode,  
   return false;
 }
-  
+
 /// TryPredicateAndSBitModifier - TryPredicateAndSBitModifier tries to process
 /// the possible Predicate and SBitModifier, to build the remaining MCOperand
 /// constituents.
Modified: test/MC/Disassembler/ARM/arm-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/arm-tests.txt
+++ b/test/MC/Disassembler/ARM/arm-tests.txt
@@ -173,9 +173,6 @@
 # CHECK:	vcmpe.f64	d8, #0
 0xc0 0x8b 0xb5 0xee
 
-# CHECK:	vldmdb	r2, {s7, s8, s9, s10, s11}
-0x05 0x3a 0x52 0xed
-
 # CHECK:	strtvc	r5, [r3], r0, lsr #20
 0x30 0x5a 0xa3 0x76
 
Modified: test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt
===================================================================
--- a/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt
+++ b/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt
@@ -1,4 +1,5 @@
 # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid \
instruction encoding} +# XFAIL: *
 
 # core registers out of range
-0xa5 0xba 0x52 0xed
+0xa5 0xba 0xd2 0xed


   Commit: a4a9f18359fe1575cd04708ba869a2e92affa024
   Author: Bill Wendling <isanbard@gmail.com>
     Date: 03/29/2011 13:12:55
      URL: https://github.com/mono/llvm/commit/a4a9f18359fe1575cd04708ba869a2e92affa024


Inline check that's used only once.

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

Changed paths:
 M lib/CodeGen/StackProtector.cpp

Modified: lib/CodeGen/StackProtector.cpp
===================================================================
--- a/lib/CodeGen/StackProtector.cpp
+++ b/lib/CodeGen/StackProtector.cpp
@@ -215,10 +215,9 @@ bool StackProtector::InsertStackProtectors() {
     //     unreachable
 
     // Split the basic block before the return instruction.
-    bool BBIsReachable = (DT && DT->isReachableFromEntry(BB));
     BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return");
 
-    if (BBIsReachable) {
+    if (DT && DT->isReachableFromEntry(BB)) {
       DT->addNewBlock(NewBB, BB);
       FailBBDom = FailBBDom ? DT->findNearestCommonDominator(FailBBDom, BB) :BB;
     }


   Commit: 94a35ac3540808119e45149e55c22e215c7d978f
   Author: Devang Patel <dpatel@apple.com>
     Date: 03/29/2011 13:27:08
      URL: https://github.com/mono/llvm/commit/94a35ac3540808119e45149e55c22e215c7d978f


Document llvm.dbg.sp, llvm.dbg.gv and llvm.dbg.enum


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

Changed paths:
 M docs/SourceLevelDebugging.html

Modified: docs/SourceLevelDebugging.html
===================================================================
--- a/docs/SourceLevelDebugging.html
+++ b/docs/SourceLevelDebugging.html
@@ -407,7 +407,8 @@ height="369">
 </div>
 
 <p>These descriptors provide debug information about globals variables.  The
-provide details such as name, type and where the variable is defined.</p>
+provide details such as name, type and where the variable is defined. All
+global variables are collected by named metadata <tt>!llvm.dbg.gv</tt>.</p>
 
 </div>
 
@@ -446,7 +447,10 @@ provide details such as name, type and where the variable is \
defined.</p>  
 <p>These descriptors provide debug information about functions, methods and
    subprograms.  They provide details such as name, return types and the source
-   location where the subprogram is defined.</p>
+   location where the subprogram is defined.
+   All subprogram descriptors are collected by a named metadata 
+   <tt>!llvm.dbg.sp</tt>.
+</p>
 
 </div>
 
@@ -646,7 +650,8 @@ DW_TAG_inheritance      = 28
 
 <p>The members of enumeration types (tag = <tt>DW_TAG_enumeration_type</tt>) are
    <a href="#format_enumeration">enumerator descriptors</a>, each representing
-   the definition of enumeration value for the set.</p>
+   the definition of enumeration value for the set. All enumeration type
+   descriptors are collected by named metadata <tt>!llvm.dbg.enum</tt>.</p>
 
 <p>The members of structure (tag = <tt>DW_TAG_structure_type</tt>) or union (tag
    = <tt>DW_TAG_union_type</tt>) types are any one of


   Commit: 303862288f273c70857e5f7c48308a844e45f448
   Author: Owen Anderson <resistor@mac.com>
     Date: 03/29/2011 13:42:25
      URL: https://github.com/mono/llvm/commit/303862288f273c70857e5f7c48308a844e45f448


Add safety check that didn't show up in testing.


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

Changed paths:
 M lib/Target/ARM/ARMLoadStoreOptimizer.cpp

Modified: lib/Target/ARM/ARMLoadStoreOptimizer.cpp
===================================================================
--- a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
+++ b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -350,6 +350,7 @@ ARMLoadStoreOpt::MergeOps(MachineBasicBlock &MBB,
   bool isDef = (isi32Load(Opcode) || Opcode == ARM::VLDRS ||
                 Opcode == ARM::VLDRD);
   Opcode = getLoadStoreMultipleOpcode(Opcode, Mode);
+  if (!Opcode) return false;
   MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(Opcode))
     .addReg(Base, getKillRegState(BaseKill))
     .addImm(Pred).addReg(PredReg);


   Commit: 94be9aaf41b04491bbdf4be1c688971373c86f3a
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/29/2011 13:47:00
      URL: https://github.com/mono/llvm/commit/94be9aaf41b04491bbdf4be1c688971373c86f3a


Run dead code elimination immediately after rematerialization.

This may eliminate some uses of the spilled registers, and we don't want to
insert reloads for that.

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

Changed paths:
 M lib/CodeGen/InlineSpiller.cpp

Modified: lib/CodeGen/InlineSpiller.cpp
===================================================================
--- a/lib/CodeGen/InlineSpiller.cpp
+++ b/lib/CodeGen/InlineSpiller.cpp
@@ -684,8 +684,7 @@ void InlineSpiller::reMaterializeAll() {
     for (LiveInterval::vni_iterator I = LI.vni_begin(), E = LI.vni_end();
          I != E; ++I) {
       VNInfo *VNI = *I;
-      if (VNI->isUnused() || VNI->isPHIDef() || VNI->hasPHIKill() ||
-          UsedValues.count(VNI))
+      if (VNI->isUnused() || VNI->isPHIDef() || UsedValues.count(VNI))
         continue;
       MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def);
       MI->addRegisterDead(Reg, &TRI);
@@ -693,14 +692,30 @@ void InlineSpiller::reMaterializeAll() {
         continue;
       DEBUG(dbgs() << "All defs dead: " << *MI);
       DeadDefs.push_back(MI);
-      // Remove all Reg references so we don't insert spill code around MI.
-      for (MachineInstr::mop_iterator MOI = MI->operands_begin(),
-             MOE = MI->operands_end(); MOI != MOE ; ++MOI)
-        if (MOI->isReg() && MOI->getReg() == Reg)
-          MOI->setReg(0);
-      VNI->setIsUnused(true);
     }
   }
+
+  // Eliminate dead code after remat. Note that some snippet copies may be
+  // deleted here.
+  if (DeadDefs.empty())
+    return;
+  DEBUG(dbgs() << "Remat created " << DeadDefs.size() << " dead defs.\n");
+  Edit->eliminateDeadDefs(DeadDefs, LIS, VRM, TII);
+
+  // Get rid of deleted and empty intervals.
+  for (unsigned i = RegsToSpill.size(); i != 0; --i) {
+    unsigned Reg = RegsToSpill[i-1];
+    if (!LIS.hasInterval(Reg)) {
+      RegsToSpill.erase(RegsToSpill.begin() + (i - 1));
+      continue;
+    }
+    LiveInterval &LI = LIS.getInterval(Reg);
+    if (!LI.empty())
+      continue;
+    Edit->eraseVirtReg(Reg, LIS);
+    RegsToSpill.erase(RegsToSpill.begin() + (i - 1));
+  }
+  DEBUG(dbgs() << RegsToSpill.size() << " registers to spill after remat.\n");
 }
 
 /// If MI is a load or store of StackSlot, it can be removed.
@@ -913,7 +928,7 @@ void InlineSpiller::spill(LiveRangeEdit &edit) {
   reMaterializeAll();
 
   // Remat may handle everything.
-  if (Edit->getParent().empty())
+  if (RegsToSpill.empty())
     return;
 
   // Update LiveStacks now that we are committed to spilling.


   Commit: ee5eff3403fb5be3c90ce98823b8f563d73eb985
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/29/2011 13:47:02
      URL: https://github.com/mono/llvm/commit/ee5eff3403fb5be3c90ce98823b8f563d73eb985


Remember to use the correct register when rematerializing for snippets.

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

Changed paths:
 M lib/CodeGen/InlineSpiller.cpp
 M lib/CodeGen/LiveRangeEdit.cpp

Modified: lib/CodeGen/InlineSpiller.cpp
===================================================================
--- a/lib/CodeGen/InlineSpiller.cpp
+++ b/lib/CodeGen/InlineSpiller.cpp
@@ -580,7 +580,7 @@ bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg,
     DEBUG(dbgs() << "\tadding <undef> flags: ");
     for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
       MachineOperand &MO = MI->getOperand(i);
-      if (MO.isReg() && MO.isUse() && MO.getReg() == Edit->getReg())
+      if (MO.isReg() && MO.isUse() && MO.getReg() == VirtReg.reg)
         MO.setIsUndef();
     }
     DEBUG(dbgs() << UseIdx << '\t' << *MI);
@@ -601,11 +601,11 @@ bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg,
     return false;
   }
 
-  // If the instruction also writes Edit->getReg(), it had better not require
-  // the same register for uses and defs.
+  // If the instruction also writes VirtReg.reg, it had better not require the
+  // same register for uses and defs.
   bool Reads, Writes;
   SmallVector<unsigned, 8> Ops;
-  tie(Reads, Writes) = MI->readsWritesVirtualRegister(Edit->getReg(), &Ops);
+  tie(Reads, Writes) = MI->readsWritesVirtualRegister(VirtReg.reg, &Ops);
   if (Writes) {
     for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
       MachineOperand &MO = MI->getOperand(Ops[i]);
@@ -626,7 +626,7 @@ bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg,
   }
 
   // Alocate a new register for the remat.
-  LiveInterval &NewLI = Edit->create(LIS, VRM);
+  LiveInterval &NewLI = Edit->createFrom(VirtReg.reg, LIS, VRM);
   NewLI.markNotSpillable();
 
   // Rematting for a copy: Set allocation hint to be the destination register.
@@ -642,7 +642,7 @@ bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg,
   // Replace operands
   for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
     MachineOperand &MO = MI->getOperand(Ops[i]);
-    if (MO.isReg() && MO.isUse() && MO.getReg() == Edit->getReg()) {
+    if (MO.isReg() && MO.isUse() && MO.getReg() == VirtReg.reg) {
       MO.setReg(NewLI.reg);
       MO.setIsKill();
     }
Modified: lib/CodeGen/LiveRangeEdit.cpp
===================================================================
--- a/lib/CodeGen/LiveRangeEdit.cpp
+++ b/lib/CodeGen/LiveRangeEdit.cpp
@@ -11,6 +11,7 @@
 // is spilled or split.
 //===----------------------------------------------------------------------===//
 
+#define DEBUG_TYPE "regalloc"
 #include "LiveRangeEdit.h"
 #include "VirtRegMap.h"
 #include "llvm/ADT/SetVector.h"


   Commit: dc0edcc81168080fafe7eff1cbe7f67aaa326bde
   Author: Argyrios Kyrtzidis <akyrtzi@gmail.com>
     Date: 03/29/2011 14:53:00
      URL: https://github.com/mono/llvm/commit/dc0edcc81168080fafe7eff1cbe7f67aaa326bde


For ClangSACheckersEmitter, allow a package to belong to checker group, in which all \
its checkers will go into the group.


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

Changed paths:
 M utils/TableGen/ClangSACheckersEmitter.cpp

Modified: utils/TableGen/ClangSACheckersEmitter.cpp
===================================================================
--- a/utils/TableGen/ClangSACheckersEmitter.cpp
+++ b/utils/TableGen/ClangSACheckersEmitter.cpp
@@ -71,7 +71,7 @@ static std::string getStringValue(const Record &R, StringRef field) \
{  
 namespace {
 struct GroupInfo {
-  std::vector<const Record*> Checkers;
+  llvm::DenseSet<const Record*> Checkers;
   llvm::DenseSet<const Record *> SubGroups;
   bool Hidden;
   unsigned Index;
@@ -80,6 +80,19 @@ struct GroupInfo {
 };
 }
 
+static void addPackageToCheckerGroup(const Record *package, const Record *group,
+                  llvm::DenseMap<const Record *, GroupInfo *> &recordGroupMap) {
+  llvm::DenseSet<const Record *> &checkers = recordGroupMap[package]->Checkers;
+  for (llvm::DenseSet<const Record *>::iterator
+         I = checkers.begin(), E = checkers.end(); I != E; ++I)
+    recordGroupMap[group]->Checkers.insert(*I);
+
+  llvm::DenseSet<const Record *> &subGroups = recordGroupMap[package]->SubGroups;
+  for (llvm::DenseSet<const Record *>::iterator
+         I = subGroups.begin(), E = subGroups.end(); I != E; ++I)
+    addPackageToCheckerGroup(*I, group, recordGroupMap);
+}
+
 void ClangSACheckersEmitter::run(raw_ostream &OS) {
   std::vector<Record*> checkers = Records.getAllDerivedDefinitions("Checker");
   llvm::DenseMap<const Record *, unsigned> checkerRecIndexMap;
@@ -150,9 +163,9 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) {
       GroupInfo &info = groupInfoByName[fullName];
       info.Hidden = R->getValueAsBit("Hidden");
       recordGroupMap[R] = &info;
-      info.Checkers.push_back(R);
+      info.Checkers.insert(R);
     } else {
-      recordGroupMap[package]->Checkers.push_back(R);
+      recordGroupMap[package]->Checkers.insert(R);
     }
 
     Record *currR = isCheckerNamed(R) ? R : package;
@@ -166,9 +179,15 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) {
     }
     // Insert the checker into the set of its group.
     if (DefInit *DI = dynamic_cast<DefInit*>(R->getValueInit("Group")))
-      recordGroupMap[DI->getDef()]->Checkers.push_back(R);
+      recordGroupMap[DI->getDef()]->Checkers.insert(R);
   }
 
+  // If a package is in group, add all its checkers and its sub-packages
+  // checkers into the group.
+  for (unsigned i = 0, e = packages.size(); i != e; ++i)
+    if (DefInit *DI = dynamic_cast<DefInit*>(packages[i]->getValueInit("Group")))
+      addPackageToCheckerGroup(packages[i], DI->getDef(), recordGroupMap);
+
   unsigned index = 0;
   for (std::map<std::string, GroupInfo>::iterator
          I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I)
@@ -183,11 +202,12 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) {
          I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) {
     maxLen = std::max(maxLen, (unsigned)I->first.size());
     
-    std::vector<const Record*> &V = I->second.Checkers;
-    if (!V.empty()) {
+    llvm::DenseSet<const Record *> &checkers = I->second.Checkers;
+    if (!checkers.empty()) {
       OS << "static const short CheckerArray" << I->second.Index << "[] = { ";
-      for (unsigned i = 0, e = V.size(); i != e; ++i)
-        OS << checkerRecIndexMap[V[i]] << ", ";
+      for (llvm::DenseSet<const Record *>::iterator
+          I = checkers.begin(), E = checkers.end(); I != E; ++I)
+        OS << checkerRecIndexMap[*I] << ", ";
       OS << "-1 };\n";
     }
     


   Commit: e8814986e137c60e78a7575292a1e5482dc15d11
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/29/2011 15:08:52
      URL: https://github.com/mono/llvm/commit/e8814986e137c60e78a7575292a1e5482dc15d11


Add and modify some tests.


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

Changed paths:
 M test/MC/Disassembler/ARM/arm-tests.txt
 M test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt

Modified: test/MC/Disassembler/ARM/arm-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/arm-tests.txt
+++ b/test/MC/Disassembler/ARM/arm-tests.txt
@@ -173,6 +173,12 @@
 # CHECK:	vcmpe.f64	d8, #0
 0xc0 0x8b 0xb5 0xee
 
+# CHECK:	vldmdb	r2!, {s7, s8, s9, s10, s11}
+0x05 0x3a 0x72 0xed
+
+# CHECK:	vldr.32	s23, [r2, #660]
+0xa5 0xba 0xd2 0xed
+
 # CHECK:	strtvc	r5, [r3], r0, lsr #20
 0x30 0x5a 0xa3 0x76
 
Modified: test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt
===================================================================
--- a/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt
+++ b/test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt
@@ -1,5 +1,4 @@
 # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid \
                instruction encoding}
-# XFAIL: *
 
 # core registers out of range
-0xa5 0xba 0xd2 0xed
+0xa5 0xba 0x72 0xed


   Commit: 915c9c6be25e8928a9fbd04abc8fb453b5f6f07f
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/29/2011 15:10:06
      URL: https://github.com/mono/llvm/commit/915c9c6be25e8928a9fbd04abc8fb453b5f6f07f


Rename invalid-VLDMSDB-arm.txt to be invalid-VLDMSDB_UPD-arm.txt.


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

Added paths:
 A test/MC/Disassembler/ARM/invalid-VLDMSDB_UPD-arm.txt
Removed paths:
 D test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt

Added: test/MC/Disassembler/ARM/invalid-VLDMSDB_UPD-arm.txt
===================================================================
--- /dev/null
+++ b/test/MC/Disassembler/ARM/invalid-VLDMSDB_UPD-arm.txt
@@ -0,0 +1,5 @@
+# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid \
instruction encoding} +
+# core registers out of range
+0xa5 0xba 0x72 0xed
+



   Commit: 9e68c423317c228b6b384dc7de70cf28950b2f42
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/29/2011 15:49:38
      URL: https://github.com/mono/llvm/commit/9e68c423317c228b6b384dc7de70cf28950b2f42


A8.6.188 STC, STC2
The STC_OPTION and STC2_OPTION instructions should have their coprocessor option \
enclosed in {}.

rdar://problem/9200661


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

Changed paths:
 M lib/Target/ARM/ARMInstrInfo.td
 M test/MC/Disassembler/ARM/arm-tests.txt

Modified: lib/Target/ARM/ARMInstrInfo.td
===================================================================
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -3430,8 +3430,8 @@ multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
   }
 
   def _OPTION : ACI<(outs),
-      (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
-      opc, "\tp$cop, cr$CRd, [$base], $option"> {
+      (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
+      opc, "\tp$cop, cr$CRd, [$base], \\{$option\\}"> {
     let Inst{31-28} = op31_28;
     let Inst{24} = 0; // P = 0
     let Inst{23} = 1; // U = 1
@@ -3472,7 +3472,7 @@ multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
 
   def L_OPTION : ACI<(outs),
       (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
-      !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
+      !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], \\{$option\\}"> {
     let Inst{31-28} = op31_28;
     let Inst{24} = 0; // P = 0
     let Inst{23} = 1; // U = 1
Modified: test/MC/Disassembler/ARM/arm-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/arm-tests.txt
+++ b/test/MC/Disassembler/ARM/arm-tests.txt
@@ -202,3 +202,9 @@
 
 # CHECK:	pli	[r3, r1, lsl #2]
 0x01 0xf1 0xd3 0xf6
+
+# CHECK:	stc	p2, cr4, [r9], {157}
+0x9d 0x42 0x89 0xec
+
+# CHECK:	stc2	p2, cr4, [r9], {157}
+0x9d 0x42 0x89 0xfc


   Commit: eb7b501849b95f1181934f637259755a5dab8ea7
   Author: Owen Anderson <resistor@mac.com>
     Date: 03/29/2011 16:27:38
      URL: https://github.com/mono/llvm/commit/eb7b501849b95f1181934f637259755a5dab8ea7


Check early if this is an unsupported opcode, so that we can avoid needlessly \
instantiating the base register in some cases.


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

Changed paths:
 M lib/Target/ARM/ARMLoadStoreOptimizer.cpp

Modified: lib/Target/ARM/ARMLoadStoreOptimizer.cpp
===================================================================
--- a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
+++ b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -308,6 +308,10 @@ ARMLoadStoreOpt::MergeOps(MachineBasicBlock &MBB,
     // VLDM/VSTM do not support DB mode without also updating the base reg.
     Mode = ARM_AM::db;
   else if (Offset != 0) {
+    // Check if this is a supported opcode before we insert instructions to
+    // calculate a new base register.
+    if (!getLoadStoreMultipleOpcode(Opcode, Mode)) return false;
+
     // If starting offset isn't zero, insert a MI to materialize a new base.
     // But only do so if it is cost effective, i.e. merging more than two
     // loads / stores.


   Commit: ca841866f9a51355bc3e2c4cf7f627181ae7d6be
   Author: Benjamin Kramer <benny.kra@googlemail.com>
     Date: 03/29/2011 16:28:57
      URL: https://github.com/mono/llvm/commit/ca841866f9a51355bc3e2c4cf7f627181ae7d6be


DSE: Remove an early exit optimization that depended on the ordering of a \
SmallPtrSet.

Fixes PR9569 and will hopefully make selfhost on ASLR-enabled systems more \
deterministic.

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

Changed paths:
 M lib/Transforms/Scalar/DeadStoreElimination.cpp

Modified: lib/Transforms/Scalar/DeadStoreElimination.cpp
===================================================================
--- a/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -640,28 +640,15 @@ bool DSE::handleEndBlock(BasicBlock &BB) {
       if (AA->doesNotAccessMemory(CS))
         continue;
       
-      unsigned NumModRef = 0, NumOther = 0;
-      
       // If the call might load from any of our allocas, then any store above
       // the call is live.
       SmallVector<Value*, 8> LiveAllocas;
       for (SmallPtrSet<Value*, 16>::iterator I = DeadStackObjects.begin(),
            E = DeadStackObjects.end(); I != E; ++I) {
-        // If we detect that our AA is imprecise, it's not worth it to scan the
-        // rest of the DeadPointers set.  Just assume that the AA will return
-        // ModRef for everything, and go ahead and bail out.
-        if (NumModRef >= 16 && NumOther == 0)
-          return MadeChange;
-
         // See if the call site touches it.
         AliasAnalysis::ModRefResult A = 
           AA->getModRefInfo(CS, *I, getPointerSize(*I, *AA));
         
-        if (A == AliasAnalysis::ModRef)
-          ++NumModRef;
-        else
-          ++NumOther;
-        
         if (A == AliasAnalysis::ModRef || A == AliasAnalysis::Ref)
           LiveAllocas.push_back(*I);
       }


   Commit: b96071bcf8c91ab2351de339eda089db97ddc180
   Author: Oscar Fuentes <ofv@wanadoo.es>
     Date: 03/29/2011 16:51:08
      URL: https://github.com/mono/llvm/commit/b96071bcf8c91ab2351de339eda089db97ddc180


Fixed the build of Clang's unit tests on MinGW. Also removed some
unnecesary conditionals and introduced a new convenience function.

The problem was that the list of libraries for Clang's unit tests was
<clang libraries> <system libraries> <llvm libraries>. As the llvm
libraries references symbols defined on the system libraries, those
were reported as undefined.

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

Changed paths:
 M cmake/modules/AddLLVM.cmake
 M cmake/modules/LLVMConfig.cmake

Modified: cmake/modules/AddLLVM.cmake
===================================================================
--- a/cmake/modules/AddLLVM.cmake
+++ b/cmake/modules/AddLLVM.cmake
@@ -11,10 +11,12 @@ macro(add_llvm_library name)
 
   if( BUILD_SHARED_LIBS )
     llvm_config( ${name} ${LLVM_LINK_COMPONENTS} )
-    get_system_libs(sl)
-    target_link_libraries( ${name} ${sl} )
   endif()
 
+  # Ensure that the system libraries always comes last on the
+  # list. Without this, linking the unit tests on MinGW fails.
+  link_system_libs( ${name} )
+
   install(TARGETS ${name}
     LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
     ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
@@ -47,8 +49,7 @@ ${name} ignored.")
     set_target_properties( ${name} PROPERTIES PREFIX "" )
 
     llvm_config( ${name} ${LLVM_LINK_COMPONENTS} )
-    get_system_libs(sl)
-    target_link_libraries( ${name} ${sl} )
+    link_system_libs( ${name} )
 
     if (APPLE)
       # Darwin-specific linker flags for loadable modules.
@@ -73,21 +74,12 @@ macro(add_llvm_executable name)
     add_executable(${name} ${ALL_FILES})
   endif()
   set(EXCLUDE_FROM_ALL OFF)
-  if( LLVM_USED_LIBS )
-    foreach(lib ${LLVM_USED_LIBS})
-      target_link_libraries( ${name} ${lib} )
-    endforeach(lib)
-  endif( LLVM_USED_LIBS )
-  if( LLVM_LINK_COMPONENTS )
-    llvm_config(${name} ${LLVM_LINK_COMPONENTS})
-  endif( LLVM_LINK_COMPONENTS )
+  target_link_libraries( ${name} ${LLVM_USED_LIBS} )
+  llvm_config( ${name} ${LLVM_LINK_COMPONENTS} )
   if( LLVM_COMMON_DEPENDS )
     add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} )
   endif( LLVM_COMMON_DEPENDS )
-  get_system_libs(llvm_system_libs)
-  if( llvm_system_libs )
-    target_link_libraries(${name} ${llvm_system_libs})
-  endif()
+  link_system_libs( ${name} )
 endmacro(add_llvm_executable name)
 
 
Modified: cmake/modules/LLVMConfig.cmake
===================================================================
--- a/cmake/modules/LLVMConfig.cmake
+++ b/cmake/modules/LLVMConfig.cmake
@@ -16,6 +16,12 @@ function(get_system_libs return_var)
 endfunction(get_system_libs)
 
 
+function(link_system_libs target)
+  get_system_libs(llvm_system_libs)
+  target_link_libraries(${target} ${llvm_system_libs})
+endfunction(link_system_libs)
+
+
 function(is_llvm_target_library library return_var)
   # Sets variable `return_var' to ON if `library' corresponds to a
   # LLVM supported target. To OFF if it doesn't.


   Commit: ae65471594fce490efee59a8eca23b459269d094
   Author: Jim Grosbach <grosbach@apple.com>
     Date: 03/29/2011 17:03:05
      URL: https://github.com/mono/llvm/commit/ae65471594fce490efee59a8eca23b459269d094


Instantiate a JITMemoryManager for MCJIT Dyld

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

Changed paths:
 M include/llvm/ExecutionEngine/RuntimeDyld.h
 M lib/ExecutionEngine/MCJIT/MCJIT.cpp
 M lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
 M tools/llvm-rtdyld/Makefile
 M tools/llvm-rtdyld/llvm-rtdyld.cpp

Modified: include/llvm/ExecutionEngine/RuntimeDyld.h
===================================================================
--- a/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -21,6 +21,7 @@ namespace llvm {
 
 class RuntimeDyldImpl;
 class MemoryBuffer;
+class JITMemoryManager;
 
 class RuntimeDyld {
   RuntimeDyld(const RuntimeDyld &);     // DO NOT IMPLEMENT
@@ -30,7 +31,7 @@ class RuntimeDyld {
   // interface.
   RuntimeDyldImpl *Dyld;
 public:
-  RuntimeDyld();
+  RuntimeDyld(JITMemoryManager*);
   ~RuntimeDyld();
 
   bool loadObject(MemoryBuffer *InputBuffer);
Modified: lib/ExecutionEngine/MCJIT/MCJIT.cpp
===================================================================
--- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp
+++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp
@@ -67,7 +67,7 @@ ExecutionEngine *MCJIT::createJIT(Module *M,
 MCJIT::MCJIT(Module *m, TargetMachine *tm, TargetJITInfo &tji,
              JITMemoryManager *JMM, CodeGenOpt::Level OptLevel,
              bool AllocateGVsWithCode)
-  : ExecutionEngine(m), TM(tm), M(m), OS(Buffer) {
+  : ExecutionEngine(m), TM(tm), M(m), OS(Buffer), Dyld(JMM) {
 
   PM.add(new TargetData(*TM->getTargetData()));
 
Modified: lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
===================================================================
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -18,6 +18,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/ExecutionEngine/JITMemoryManager.h"
 #include "llvm/Object/MachOObject.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -34,6 +35,9 @@ class RuntimeDyldImpl {
   unsigned CPUType;
   unsigned CPUSubtype;
 
+  // The JITMemoryManager to load objects into.
+  JITMemoryManager *JMM;
+
   // Master symbol table. As modules are loaded and external symbols are
   // resolved, their addresses are stored here.
   StringMap<void*> SymbolTable;
@@ -68,7 +72,7 @@ class RuntimeDyldImpl {
                      const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC);
 
 public:
-  RuntimeDyldImpl() : HasError(false) {}
+  RuntimeDyldImpl(JITMemoryManager *jmm) : JMM(jmm), HasError(false) {}
 
   bool loadObject(MemoryBuffer *InputBuffer);
 
@@ -526,8 +530,8 @@ bool RuntimeDyldImpl::loadObject(MemoryBuffer *InputBuffer) {
 
 //===----------------------------------------------------------------------===//
 // RuntimeDyld class implementation
-RuntimeDyld::RuntimeDyld() {
-  Dyld = new RuntimeDyldImpl;
+RuntimeDyld::RuntimeDyld(JITMemoryManager *JMM) {
+  Dyld = new RuntimeDyldImpl(JMM);
 }
 
 RuntimeDyld::~RuntimeDyld() {
Modified: tools/llvm-rtdyld/Makefile
===================================================================
--- a/tools/llvm-rtdyld/Makefile
+++ b/tools/llvm-rtdyld/Makefile
@@ -18,6 +18,6 @@ TOOL_NO_EXPORTS = 1
 # early so we can set up LINK_COMPONENTS before including Makefile.rules
 include $(LEVEL)/Makefile.config
 
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) support MC object RuntimeDyld
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) support MC object RuntimeDyld JIT
 
 include $(LLVM_SRC_ROOT)/Makefile.rules
Modified: tools/llvm-rtdyld/llvm-rtdyld.cpp
===================================================================
--- a/tools/llvm-rtdyld/llvm-rtdyld.cpp
+++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp
@@ -13,6 +13,7 @@
 
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/OwningPtr.h"
+#include "llvm/ExecutionEngine/JITMemoryManager.h"
 #include "llvm/ExecutionEngine/RuntimeDyld.h"
 #include "llvm/Object/MachOObject.h"
 #include "llvm/Support/CommandLine.h"
@@ -60,7 +61,7 @@ static int executeInput() {
     return Error("unable to read input: '" + ec.message() + "'");
 
   // Instantiate a dynamic linker.
-  RuntimeDyld Dyld;
+  RuntimeDyld Dyld(JITMemoryManager::CreateDefaultMemManager());
 
   // Load the object file into it.
   if (Dyld.loadObject(InputBuffer.take())) {


   Commit: cea24589705a836e45ca03c3ba7b580520fa4442
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/29/2011 17:09:30
      URL: https://github.com/mono/llvm/commit/cea24589705a836e45ca03c3ba7b580520fa4442


Add a thumb test file for printf (iOS 4.3).


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

Added paths:
 A test/MC/Disassembler/ARM/thumb-printf.txt

Added: test/MC/Disassembler/ARM/thumb-printf.txt
===================================================================
--- /dev/null
+++ b/test/MC/Disassembler/ARM/thumb-printf.txt
@@ -0,0 +1,77 @@
+# RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 | FileCheck %s
+
+# CHECK:	push	{r0, r1, r2, r3}
+# CHECK-NEXT:	push	{r4, r5, r7, lr}
+# CHECK-NEXT:	add	r7, sp, #8
+# CHECK-NEXT:	sub	sp, #4
+# CHECK-NEXT:	add	r3, sp, #20
+# CHECK-NEXT:	ldr	r5, [r3], #4
+# CHECK-NEXT:	str	r3, [sp]
+# CHECK-NEXT:	ldr.n	r3, #52
+# CHECK-NEXT:	add	r3, pc
+# CHECK-NEXT:	ldr	r0, [r3]
+# CHECK-NEXT:	ldr	r4, [r0]
+# CHECK-NEXT:	ldr.n	r0, #48
+# CHECK-NEXT:	add	r0, pc
+# CHECK-NEXT:	ldr	r0, [r0]
+# CHECK-NEXT:	ldr	r0, [r0]
+# CHECK-NEXT:	blx	#191548
+# CHECK-NEXT:	cbnz	r0, #6
+# CHECK-NEXT:	ldr.n	r1, #40
+# CHECK-NEXT:	add	r1, pc
+# CHECK-NEXT:	ldr	r1, [r1]
+# CHECK-NEXT:	b	#0
+# CHECK-NEXT:	mov	r1, r0
+# CHECK-NEXT:	mov	r0, r4
+# CHECK-NEXT:	mov	r2, r5
+# CHECK-NEXT:	ldr	r3, [sp]
+# CHECK-NEXT:	bl	#-8390
+# CHECK-NEXT:	sub.w	sp, r7, #8
+# CHECK-NEXT:	pop.w	{r4, r5, r7, lr}
+# CHECK-NEXT:	add	sp, #16
+# CHECK-NEXT:	bx	lr
+# CHECK-NEXT:	nop
+# CHECK-NEXT:	movs	r3, #142
+# CHECK-NEXT:	movs	r5, r0
+# CHECK-NEXT:	adds	r1, #122
+# CHECK-NEXT:	movs	r5, r0
+# CHECK-NEXT:	adds	r1, #104
+# CHECK-NEXT:	movs	r5, r0
+0x0f	0xb4
+0xb0	0xb5
+0x02	0xaf
+0x81	0xb0
+0x05	0xab
+0x53	0xf8	0x04	0x5b
+0x00	0x93
+0x0d	0x4b
+0x7b	0x44
+0x18	0x68
+0x04	0x68
+0x0c	0x48
+0x78	0x44
+0x00	0x68
+0x00	0x68
+0x2e	0xf0	0x1e	0xee
+0x18	0xb9
+0x0a	0x49
+0x79	0x44
+0x09	0x68
+0x00	0xe0
+0x01	0x46
+0x20	0x46
+0x2a	0x46
+0x00	0x9b
+0xfd	0xf7	0x9d	0xff
+0xa7	0xf1	0x08	0x0d
+0xbd	0xe8	0xb0	0x40
+0x04	0xb0
+0x70	0x47
+0x00	0xbf
+0x8e	0x23
+0x05	0x00
+0x7a	0x31
+0x05	0x00
+0x68	0x31
+0x05	0x00
+



   Commit: 67d3b8f0782f2db6c071009793f21f7edd78dbbb
   Author: Kevin Enderby <enderby@apple.com>
     Date: 03/29/2011 17:11:52
      URL: https://github.com/mono/llvm/commit/67d3b8f0782f2db6c071009793f21f7edd78dbbb


Added support symbolic floating point constants in the MC assembler for Infinity
and Nans with the same strings as GAS supports.  rdar://8673024


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

Changed paths:
 M lib/MC/MCParser/AsmParser.cpp
 M test/MC/AsmParser/floating-literals.s

Modified: lib/MC/MCParser/AsmParser.cpp
===================================================================
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -1552,13 +1552,21 @@ bool AsmParser::ParseDirectiveRealValue(const fltSemantics \
&Semantics) {  Lex();
 
       if (getLexer().isNot(AsmToken::Integer) &&
-          getLexer().isNot(AsmToken::Real))
+          getLexer().isNot(AsmToken::Real) &&
+          getLexer().isNot(AsmToken::Identifier))
         return TokError("unexpected token in directive");
 
       // Convert to an APFloat.
       APFloat Value(Semantics);
-      if (Value.convertFromString(getTok().getString(),
-                                  APFloat::rmNearestTiesToEven) ==
+      StringRef IDVal = getTok().getString();
+      if (getLexer().is(AsmToken::Identifier)) {
+        if (!IDVal.compare_lower("infinity") || !IDVal.compare_lower("inf"))
+          Value = APFloat::getInf(Semantics);
+        else if (!IDVal.compare_lower("nan"))
+          Value = APFloat::getNaN(Semantics, false, ~0);
+        else
+          return TokError("invalid floating point literal");
+      } else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) ==
           APFloat::opInvalidOp)
         return TokError("invalid floating point literal");
       if (IsNeg)
Modified: test/MC/AsmParser/floating-literals.s
===================================================================
--- a/test/MC/AsmParser/floating-literals.s
+++ b/test/MC/AsmParser/floating-literals.s
@@ -6,6 +6,12 @@
 # CHECK: .long	1082549862
 .single 1.2455, +2.3, 3, + 4.2
 
+# CHECK: .long	2139095040
+.single InFinIty
+
+# CHECK: .long	2147483647
+.single nAN
+
 # CHECK: .long  1067928519
 .float 1.307
         


   Commit: caeb47997cce90f4e930725cbeb0777fa230e823
   Author: Argyrios Kyrtzidis <akyrtzi@gmail.com>
     Date: 03/29/2011 17:16:19
      URL: https://github.com/mono/llvm/commit/caeb47997cce90f4e930725cbeb0777fa230e823


In ClangSACheckersEmitter:
  - Also emit a list of packages and groups sorted by name
  - Avoid iterating over DenseSet so that the output of the arrays is deterministic.


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

Changed paths:
 M utils/TableGen/ClangSACheckersEmitter.cpp

Modified: utils/TableGen/ClangSACheckersEmitter.cpp
===================================================================
--- a/utils/TableGen/ClangSACheckersEmitter.cpp
+++ b/utils/TableGen/ClangSACheckersEmitter.cpp
@@ -148,6 +148,48 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) {
     }
   }
 
+  typedef std::map<std::string, const Record *> SortedRecords;
+
+  OS << "\n#ifdef GET_PACKAGES\n";
+  {
+    SortedRecords sortedPackages;
+    for (unsigned i = 0, e = packages.size(); i != e; ++i)
+      sortedPackages[getPackageFullName(packages[i])] = packages[i];
+  
+    for (SortedRecords::iterator
+           I = sortedPackages.begin(), E = sortedPackages.end(); I != E; ++I) {
+      const Record &R = *I->second;
+  
+      OS << "PACKAGE(" << "\"";
+      OS.write_escaped(getPackageFullName(&R)) << "\", ";
+      // Hidden bit
+      if (isHidden(R))
+        OS << "true";
+      else
+        OS << "false";
+      OS << ")\n";
+    }
+  }
+  OS << "#endif // GET_PACKAGES\n\n";
+
+  OS << "\n#ifdef GET_GROUPS\n";
+  {
+    SortedRecords sortedGroups;
+    for (unsigned i = 0, e = checkerGroups.size(); i != e; ++i)
+      sortedGroups[checkerGroups[i]->getValueAsString("GroupName")]
+                   = checkerGroups[i];
+
+    for (SortedRecords::iterator
+           I = sortedGroups.begin(), E = sortedGroups.end(); I != E; ++I) {
+      const Record &R = *I->second;
+  
+      OS << "GROUP(" << "\"";
+      OS.write_escaped(R.getValueAsString("GroupName")) << "\"";
+      OS << ")\n";
+    }
+  }
+  OS << "#endif // GET_GROUPS\n\n";
+
   for (unsigned i = 0, e = checkers.size(); i != e; ++i) {
     Record *R = checkers[i];
     Record *package = 0;
@@ -201,22 +243,34 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) {
   for (std::map<std::string, GroupInfo>::iterator
          I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) {
     maxLen = std::max(maxLen, (unsigned)I->first.size());
-    
+
     llvm::DenseSet<const Record *> &checkers = I->second.Checkers;
     if (!checkers.empty()) {
-      OS << "static const short CheckerArray" << I->second.Index << "[] = { ";
+      // Make the output order deterministic.
+      std::map<int, const Record *> sorted;
       for (llvm::DenseSet<const Record *>::iterator
-          I = checkers.begin(), E = checkers.end(); I != E; ++I)
-        OS << checkerRecIndexMap[*I] << ", ";
+             I = checkers.begin(), E = checkers.end(); I != E; ++I)
+        sorted[(*I)->getID()] = *I;
+
+      OS << "static const short CheckerArray" << I->second.Index << "[] = { ";
+      for (std::map<int, const Record *>::iterator
+             I = sorted.begin(), E = sorted.end(); I != E; ++I)
+        OS << checkerRecIndexMap[I->second] << ", ";
       OS << "-1 };\n";
     }
     
     llvm::DenseSet<const Record *> &subGroups = I->second.SubGroups;
     if (!subGroups.empty()) {
-      OS << "static const short SubPackageArray" << I->second.Index << "[] = { ";
+      // Make the output order deterministic.
+      std::map<int, const Record *> sorted;
       for (llvm::DenseSet<const Record *>::iterator
-             I = subGroups.begin(), E = subGroups.end(); I != E; ++I) {
-        OS << recordGroupMap[*I]->Index << ", ";
+             I = subGroups.begin(), E = subGroups.end(); I != E; ++I)
+        sorted[(*I)->getID()] = *I;
+
+      OS << "static const short SubPackageArray" << I->second.Index << "[] = { ";
+      for (std::map<int, const Record *>::iterator
+             I = sorted.begin(), E = sorted.end(); I != E; ++I) {
+        OS << recordGroupMap[I->second]->Index << ", ";
       }
       OS << "-1 };\n";
     }


   Commit: 52d4aba834db54e985347161eeb5b97e1952d028
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/29/2011 17:20:19
      URL: https://github.com/mono/llvm/commit/52d4aba834db54e985347161eeb5b97e1952d028


Recompute register class and hint for registers created during spilling.

The spill weight is not recomputed for an unspillable register - it stays infinite.

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

Changed paths:
 M lib/CodeGen/CalcSpillWeights.cpp
 M lib/CodeGen/InlineSpiller.cpp
 M lib/CodeGen/LiveRangeEdit.cpp
 M lib/CodeGen/LiveRangeEdit.h
 M lib/CodeGen/RegAllocGreedy.cpp
 M lib/CodeGen/SplitKit.cpp

Modified: lib/CodeGen/CalcSpillWeights.cpp
===================================================================
--- a/lib/CodeGen/CalcSpillWeights.cpp
+++ b/lib/CodeGen/CalcSpillWeights.cpp
@@ -103,6 +103,9 @@ void VirtRegAuxInfo::CalculateWeightAndHint(LiveInterval &li) {
   // Don't recompute a target specific hint.
   bool noHint = mri.getRegAllocationHint(li.reg).first != 0;
 
+  // Don't recompute spill weight for an unspillable register.
+  bool Spillable = li.isSpillable();
+
   for (MachineRegisterInfo::reg_iterator I = mri.reg_begin(li.reg);
        MachineInstr *mi = I.skipInstruction();) {
     if (mi->isIdentityCopy() || mi->isImplicitDef() || mi->isDebugValue())
@@ -110,25 +113,28 @@ void VirtRegAuxInfo::CalculateWeightAndHint(LiveInterval &li) {
     if (!visited.insert(mi))
       continue;
 
-    // Get loop info for mi.
-    if (mi->getParent() != mbb) {
-      mbb = mi->getParent();
-      loop = loops_.getLoopFor(mbb);
-      loopDepth = loop ? loop->getLoopDepth() : 0;
-      isExiting = loop ? loop->isLoopExiting(mbb) : false;
+    float weight = 1.0f;
+    if (Spillable) {
+      // Get loop info for mi.
+      if (mi->getParent() != mbb) {
+        mbb = mi->getParent();
+        loop = loops_.getLoopFor(mbb);
+        loopDepth = loop ? loop->getLoopDepth() : 0;
+        isExiting = loop ? loop->isLoopExiting(mbb) : false;
+      }
+
+      // Calculate instr weight.
+      bool reads, writes;
+      tie(reads, writes) = mi->readsWritesVirtualRegister(li.reg);
+      weight = LiveIntervals::getSpillWeight(writes, reads, loopDepth);
+
+      // Give extra weight to what looks like a loop induction variable update.
+      if (writes && isExiting && lis_.isLiveOutOfMBB(li, mbb))
+        weight *= 3;
+
+      totalWeight += weight;
     }
 
-    // Calculate instr weight.
-    bool reads, writes;
-    tie(reads, writes) = mi->readsWritesVirtualRegister(li.reg);
-    float weight = LiveIntervals::getSpillWeight(writes, reads, loopDepth);
-
-    // Give extra weight to what looks like a loop induction variable update.
-    if (writes && isExiting && lis_.isLiveOutOfMBB(li, mbb))
-      weight *= 3;
-
-    totalWeight += weight;
-
     // Get allocation hints from copies.
     if (noHint || !mi->isCopy())
       continue;
@@ -150,10 +156,14 @@ void VirtRegAuxInfo::CalculateWeightAndHint(LiveInterval &li) {
   // Always prefer the physreg hint.
   if (unsigned hint = hintPhys ? hintPhys : hintVirt) {
     mri.setRegAllocationHint(li.reg, 0, hint);
-    // Weakly boost the spill weifght of hinted registers.
+    // Weakly boost the spill weight of hinted registers.
     totalWeight *= 1.01F;
   }
 
+  // If the live interval was already unspillable, leave it that way.
+  if (!Spillable)
+    return;
+
   // Mark li as unspillable if all live ranges are tiny.
   if (li.isZeroLength()) {
     li.markNotSpillable();
Modified: lib/CodeGen/InlineSpiller.cpp
===================================================================
--- a/lib/CodeGen/InlineSpiller.cpp
+++ b/lib/CodeGen/InlineSpiller.cpp
@@ -139,6 +139,7 @@ private:
                    MachineBasicBlock::iterator MI);
 
   void spillAroundUses(unsigned Reg);
+  void spillAll();
 };
 }
 
@@ -629,10 +630,6 @@ bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg,
   LiveInterval &NewLI = Edit->createFrom(VirtReg.reg, LIS, VRM);
   NewLI.markNotSpillable();
 
-  // Rematting for a copy: Set allocation hint to be the destination register.
-  if (MI->isCopy())
-    MRI.setRegAllocationHint(NewLI.reg, 0, MI->getOperand(0).getReg());
-
   // Finally we can rematerialize OrigMI before MI.
   SlotIndex DefIdx = Edit->rematerializeAt(*MI->getParent(), MI, NewLI.reg, RM,
                                            LIS, TII, TRI);
@@ -718,6 +715,11 @@ void InlineSpiller::reMaterializeAll() {
   DEBUG(dbgs() << RegsToSpill.size() << " registers to spill after remat.\n");
 }
 
+
+//===----------------------------------------------------------------------===//
+//                                 Spilling
+//===----------------------------------------------------------------------===//
+
 /// If MI is a load or store of StackSlot, it can be removed.
 bool InlineSpiller::coalesceStackAccess(MachineInstr *MI, unsigned Reg) {
   int FI = 0;
@@ -906,31 +908,8 @@ void InlineSpiller::spillAroundUses(unsigned Reg) {
   }
 }
 
-void InlineSpiller::spill(LiveRangeEdit &edit) {
-  Edit = &edit;
-  assert(!TargetRegisterInfo::isStackSlot(edit.getReg())
-         && "Trying to spill a stack slot.");
-  // Share a stack slot among all descendants of Original.
-  Original = VRM.getOriginal(edit.getReg());
-  StackSlot = VRM.getStackSlot(Original);
-  StackInt = 0;
-
-  DEBUG(dbgs() << "Inline spilling "
-               << MRI.getRegClass(edit.getReg())->getName()
-               << ':' << edit.getParent() << "\nFrom original "
-               << LIS.getInterval(Original) << '\n');
-  assert(edit.getParent().isSpillable() &&
-         "Attempting to spill already spilled value.");
-  assert(DeadDefs.empty() && "Previous spill didn't remove dead defs");
-
-  collectRegsToSpill();
-  analyzeSiblingValues();
-  reMaterializeAll();
-
-  // Remat may handle everything.
-  if (RegsToSpill.empty())
-    return;
-
+/// spillAll - Spill all registers remaining after rematerialization.
+void InlineSpiller::spillAll() {
   // Update LiveStacks now that we are committed to spilling.
   if (StackSlot == VirtRegMap::NO_STACK_SLOT) {
     StackSlot = VRM.assignVirt2StackSlot(Original);
@@ -939,8 +918,8 @@ void InlineSpiller::spill(LiveRangeEdit &edit) {
   } else
     StackInt = &LSS.getInterval(StackSlot);
 
-  if (Original != edit.getReg())
-    VRM.assignVirt2StackSlot(edit.getReg(), StackSlot);
+  if (Original != Edit->getReg())
+    VRM.assignVirt2StackSlot(Edit->getReg(), StackSlot);
 
   assert(StackInt->getNumValNums() == 1 && "Bad stack interval values");
   for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i)
@@ -959,7 +938,7 @@ void InlineSpiller::spill(LiveRangeEdit &edit) {
   }
 
   // Finally delete the SnippetCopies.
-  for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(edit.getReg());
+  for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Edit->getReg());
        MachineInstr *MI = RI.skipInstruction();) {
     assert(SnippetCopies.count(MI) && "Remaining use wasn't a snippet copy");
     // FIXME: Do this with a LiveRangeEdit callback.
@@ -968,6 +947,35 @@ void InlineSpiller::spill(LiveRangeEdit &edit) {
     MI->eraseFromParent();
   }
 
+  // Delete all spilled registers.
   for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i)
-    edit.eraseVirtReg(RegsToSpill[i], LIS);
+    Edit->eraseVirtReg(RegsToSpill[i], LIS);
+}
+
+void InlineSpiller::spill(LiveRangeEdit &edit) {
+  Edit = &edit;
+  assert(!TargetRegisterInfo::isStackSlot(edit.getReg())
+         && "Trying to spill a stack slot.");
+  // Share a stack slot among all descendants of Original.
+  Original = VRM.getOriginal(edit.getReg());
+  StackSlot = VRM.getStackSlot(Original);
+  StackInt = 0;
+
+  DEBUG(dbgs() << "Inline spilling "
+               << MRI.getRegClass(edit.getReg())->getName()
+               << ':' << edit.getParent() << "\nFrom original "
+               << LIS.getInterval(Original) << '\n');
+  assert(edit.getParent().isSpillable() &&
+         "Attempting to spill already spilled value.");
+  assert(DeadDefs.empty() && "Previous spill didn't remove dead defs");
+
+  collectRegsToSpill();
+  analyzeSiblingValues();
+  reMaterializeAll();
+
+  // Remat may handle everything.
+  if (!RegsToSpill.empty())
+    spillAll();
+
+  Edit->calculateRegClassAndHint(MF, LIS, Loops);
 }
Modified: lib/CodeGen/LiveRangeEdit.cpp
===================================================================
--- a/lib/CodeGen/LiveRangeEdit.cpp
+++ b/lib/CodeGen/LiveRangeEdit.cpp
@@ -15,6 +15,7 @@
 #include "LiveRangeEdit.h"
 #include "VirtRegMap.h"
 #include "llvm/ADT/SetVector.h"
+#include "llvm/CodeGen/CalcSpillWeights.h"
 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
@@ -236,3 +237,13 @@ void \
LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,  }
 }
 
+void LiveRangeEdit::calculateRegClassAndHint(MachineFunction &MF,
+                                             LiveIntervals &LIS,
+                                             const MachineLoopInfo &Loops) {
+  VirtRegAuxInfo VRAI(MF, LIS, Loops);
+  for (iterator I = begin(), E = end(); I != E; ++I) {
+    LiveInterval &LI = **I;
+    VRAI.CalculateRegClass(LI.reg);
+    VRAI.CalculateWeightAndHint(LI);
+  }
+}
Modified: lib/CodeGen/LiveRangeEdit.h
===================================================================
--- a/lib/CodeGen/LiveRangeEdit.h
+++ b/lib/CodeGen/LiveRangeEdit.h
@@ -25,6 +25,7 @@ namespace llvm {
 
 class AliasAnalysis;
 class LiveIntervals;
+class MachineLoopInfo;
 class MachineRegisterInfo;
 class VirtRegMap;
 
@@ -179,6 +180,10 @@ public:
                          LiveIntervals&, VirtRegMap&,
                          const TargetInstrInfo&);
 
+  /// calculateRegClassAndHint - Recompute register class and hint for each new
+  /// register.
+  void calculateRegClassAndHint(MachineFunction&, LiveIntervals&,
+                                const MachineLoopInfo&);
 };
 
 }
Modified: lib/CodeGen/RegAllocGreedy.cpp
===================================================================
--- a/lib/CodeGen/RegAllocGreedy.cpp
+++ b/lib/CodeGen/RegAllocGreedy.cpp
@@ -1164,6 +1164,7 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg,
   NamedRegionTimer T("Spiller", TimerGroupName, TimePassesIsEnabled);
   LiveRangeEdit LRE(VirtReg, NewVRegs, this);
   spiller().spill(LRE);
+  setStage(NewVRegs.begin(), NewVRegs.end(), RS_Spill);
 
   if (VerifyEnabled)
     MF->verify(this, "After spilling");
Modified: lib/CodeGen/SplitKit.cpp
===================================================================
--- a/lib/CodeGen/SplitKit.cpp
+++ b/lib/CodeGen/SplitKit.cpp
@@ -17,7 +17,6 @@
 #include "LiveRangeEdit.h"
 #include "VirtRegMap.h"
 #include "llvm/ADT/Statistic.h"
-#include "llvm/CodeGen/CalcSpillWeights.h"
 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
 #include "llvm/CodeGen/MachineDominators.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -881,14 +880,7 @@ void SplitEditor::finish() {
   }
 
   // Calculate spill weight and allocation hints for new intervals.
-  VirtRegAuxInfo vrai(VRM.getMachineFunction(), LIS, SA.Loops);
-  for (LiveRangeEdit::iterator I = Edit->begin(), E = Edit->end(); I != E; ++I){
-    LiveInterval &li = **I;
-    vrai.CalculateRegClass(li.reg);
-    vrai.CalculateWeightAndHint(li);
-    DEBUG(dbgs() << "  new interval " << MRI.getRegClass(li.reg)->getName()
-                 << ":" << li << '\n');
-  }
+  Edit->calculateRegClassAndHint(VRM.getMachineFunction(), LIS, SA.Loops);
 }
 
 


   Commit: a1d70fd0cce5d7feaa03a4898907b4e70734b4be
   Author: Cameron Zwarich <zwarich@apple.com>
     Date: 03/29/2011 17:41:55
      URL: https://github.com/mono/llvm/commit/a1d70fd0cce5d7feaa03a4898907b4e70734b4be


Add Neon SINT_TO_FP and UINT_TO_FP lowering from v4i16 to v4f32. Fixes
<rdar://problem/8875309> and <rdar://problem/9057191>.

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

Changed paths:
 M lib/Target/ARM/ARMISelLowering.cpp
Added paths:
 A test/CodeGen/ARM/int-to-fp.ll

Modified: lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -461,6 +461,10 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
     setOperationAction(ISD::UDIV, MVT::v8i8, Custom);
     setOperationAction(ISD::VSETCC, MVT::v1i64, Expand);
     setOperationAction(ISD::VSETCC, MVT::v2i64, Expand);
+    // Neon does not have single instruction SINT_TO_FP and UINT_TO_FP with
+    // a destination type that is wider than the source.
+    setOperationAction(ISD::SINT_TO_FP, MVT::v4i16, Custom);
+    setOperationAction(ISD::UINT_TO_FP, MVT::v4i16, Custom);
 
     setTargetDAGCombine(ISD::INTRINSIC_VOID);
     setTargetDAGCombine(ISD::INTRINSIC_W_CHAIN);
@@ -2854,8 +2858,39 @@ static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) {
   return DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op);
 }
 
+static SDValue LowerVectorINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
+  EVT VT = Op.getValueType();
+  DebugLoc dl = Op.getDebugLoc();
+
+  EVT OperandVT = Op.getOperand(0).getValueType();
+  assert(OperandVT == MVT::v4i16 && "Invalid type for custom lowering!");
+  if (VT != MVT::v4f32)
+    return DAG.UnrollVectorOp(Op.getNode());
+
+  unsigned CastOpc;
+  unsigned Opc;
+  switch (Op.getOpcode()) {
+  default:
+    assert(0 && "Invalid opcode!");
+  case ISD::SINT_TO_FP:
+    CastOpc = ISD::SIGN_EXTEND;
+    Opc = ISD::SINT_TO_FP;
+    break;
+  case ISD::UINT_TO_FP:
+    CastOpc = ISD::ZERO_EXTEND;
+    Opc = ISD::UINT_TO_FP;
+    break;
+  }
+
+  Op = DAG.getNode(CastOpc, dl, MVT::v4i32, Op.getOperand(0));
+  return DAG.getNode(Opc, dl, VT, Op);
+}
+
 static SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
   EVT VT = Op.getValueType();
+  if (VT.isVector())
+    return LowerVectorINT_TO_FP(Op, DAG);
+
   DebugLoc dl = Op.getDebugLoc();
   unsigned Opc;
 

Added: test/CodeGen/ARM/int-to-fp.ll
===================================================================
--- /dev/null
+++ b/test/CodeGen/ARM/int-to-fp.ll
@@ -0,0 +1,20 @@
+; RUN: llc < %s | FileCheck %s
+target datalayout = \
"e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32"
 +target triple = "thumbv7-apple-darwin10.0.0"
+
+; CHECK: sint_to_fp
+; CHECK: vmovl.s16
+; CHECK: vcvt.f32.s32
+define <4 x float> @sint_to_fp(<4 x i16> %x) nounwind ssp {
+  %a = sitofp <4 x i16> %x to <4 x float>
+  ret <4 x float> %a
+}
+
+; CHECK: uint_to_fp
+; CHECK: vmovl.u16
+; CHECK: vcvt.f32.u32
+define <4 x float> @uint_to_fp(<4 x i16> %x) nounwind ssp {
+  %a = uitofp <4 x i16> %x to <4 x float>
+  ret <4 x float> %a
+}
+



   Commit: c5cfdfb261ffdea8cae01d625b6fae4941f32784
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/29/2011 17:52:02
      URL: https://github.com/mono/llvm/commit/c5cfdfb261ffdea8cae01d625b6fae4941f32784


Add a test case for MSRi.


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

Changed paths:
 M test/MC/Disassembler/ARM/arm-tests.txt

Modified: test/MC/Disassembler/ARM/arm-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/arm-tests.txt
+++ b/test/MC/Disassembler/ARM/arm-tests.txt
@@ -140,6 +140,9 @@
 # CHECK: msr cpsr_fc, r0
 0x00 0xf0 0x29 0xe1
 
+# CHECK:	msrmi	cpsr_c, #241, 8
+0xf1 0xf4 0x21 0x43
+
 # CHECK: rsbs r6, r7, r8
 0x08 0x60 0x77 0xe0
 


   Commit: 1dc6ed7ee92ccd4356874611b946884e10206edd
   Author: Kevin Enderby <enderby@apple.com>
     Date: 03/29/2011 17:54:10
      URL: https://github.com/mono/llvm/commit/1dc6ed7ee92ccd4356874611b946884e10206edd


Adding a test for "-inf" as well.


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

Changed paths:
 M test/MC/AsmParser/floating-literals.s

Modified: test/MC/AsmParser/floating-literals.s
===================================================================
--- a/test/MC/AsmParser/floating-literals.s
+++ b/test/MC/AsmParser/floating-literals.s
@@ -9,6 +9,9 @@
 # CHECK: .long	2139095040
 .single InFinIty
 
+# CHECK: .long	4286578688
+.single -iNf
+
 # CHECK: .long	2147483647
 .single nAN
 


   Commit: 63680c7dc21427ae6e7d8eda96eb0ad77c0b0212
   Author: Benjamin Kramer <benny.kra@googlemail.com>
     Date: 03/29/2011 18:06:41
      URL: https://github.com/mono/llvm/commit/63680c7dc21427ae6e7d8eda96eb0ad77c0b0212


InstCombine: Add a few missing combines for ANDs and ORs of sign bit tests.

On x86 we now compile "if (a < 0 && b < 0)" into
	testl	%edi, %esi
	js	IF.THEN

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

Changed paths:
 M lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
Added paths:
 A test/Transforms/InstCombine/sign-test-and-or.ll

Modified: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -756,6 +756,18 @@ Value *InstCombiner::FoldAndOfICmps(ICmpInst *LHS, ICmpInst \
*RHS) {  Value *NewOr = Builder->CreateOr(Val, Val2);
       return Builder->CreateICmp(LHSCC, NewOr, LHSCst);
     }
+
+    // (icmp slt A, 0) & (icmp slt B, 0) --> (icmp slt (A&B), 0)
+    if (LHSCC == ICmpInst::ICMP_SLT && LHSCst->isZero()) {
+      Value *NewAnd = Builder->CreateAnd(Val, Val2);
+      return Builder->CreateICmp(LHSCC, NewAnd, LHSCst);
+    }
+
+    // (icmp sgt A, -1) & (icmp sgt B, -1) --> (icmp sgt (A|B), -1)
+    if (LHSCC == ICmpInst::ICMP_SGT && LHSCst->isAllOnesValue()) {
+      Value *NewOr = Builder->CreateOr(Val, Val2);
+      return Builder->CreateICmp(LHSCC, NewOr, LHSCst);
+    }
   }
   
   // From here on, we only handle:
@@ -1442,6 +1454,18 @@ Value *InstCombiner::FoldOrOfICmps(ICmpInst *LHS, ICmpInst \
*RHS) {  Value *NewOr = Builder->CreateOr(Val, Val2);
       return Builder->CreateICmp(LHSCC, NewOr, LHSCst);
     }
+
+    // (icmp slt A, 0) | (icmp slt B, 0) --> (icmp slt (A|B), 0)
+    if (LHSCC == ICmpInst::ICMP_SLT && LHSCst->isZero()) {
+      Value *NewOr = Builder->CreateOr(Val, Val2);
+      return Builder->CreateICmp(LHSCC, NewOr, LHSCst);
+    }
+
+    // (icmp sgt A, -1) | (icmp sgt B, -1) --> (icmp sgt (A&B), -1)
+    if (LHSCC == ICmpInst::ICMP_SGT && LHSCst->isAllOnesValue()) {
+      Value *NewAnd = Builder->CreateAnd(Val, Val2);
+      return Builder->CreateICmp(LHSCC, NewAnd, LHSCst);
+    }
   }
 
   // (icmp ult (X + CA), C1) | (icmp eq X, C2) -> (icmp ule (X + CA), C1)

Added: test/Transforms/InstCombine/sign-test-and-or.ll
===================================================================
--- /dev/null
+++ b/test/Transforms/InstCombine/sign-test-and-or.ll
@@ -0,0 +1,80 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+
+declare void @foo()
+
+define void @test1(i32 %a, i32 %b) nounwind {
+  %1 = icmp slt i32 %a, 0
+  %2 = icmp slt i32 %b, 0
+  %or.cond = or i1 %1, %2
+  br i1 %or.cond, label %if.then, label %if.end
+
+; CHECK: @test1
+; CHECK-NEXT: %1 = or i32 %a, %b
+; CHECK-NEXT: %2 = icmp slt i32 %1, 0
+; CHECK-NEXT: br
+
+if.then:
+  tail call void @foo() nounwind
+  ret void
+
+if.end:
+  ret void
+}
+
+define void @test2(i32 %a, i32 %b) nounwind {
+  %1 = icmp sgt i32 %a, -1
+  %2 = icmp sgt i32 %b, -1
+  %or.cond = or i1 %1, %2
+  br i1 %or.cond, label %if.then, label %if.end
+
+; CHECK: @test2
+; CHECK-NEXT: %1 = and i32 %a, %b
+; CHECK-NEXT: %2 = icmp sgt i32 %1, -1
+; CHECK-NEXT: br
+
+if.then:
+  tail call void @foo() nounwind
+  ret void
+
+if.end:
+  ret void
+}
+
+define void @test3(i32 %a, i32 %b) nounwind {
+  %1 = icmp slt i32 %a, 0
+  %2 = icmp slt i32 %b, 0
+  %or.cond = and i1 %1, %2
+  br i1 %or.cond, label %if.then, label %if.end
+
+; CHECK: @test3
+; CHECK-NEXT: %1 = and i32 %a, %b
+; CHECK-NEXT: %2 = icmp slt i32 %1, 0
+; CHECK-NEXT: br
+
+if.then:
+  tail call void @foo() nounwind
+  ret void
+
+if.end:
+  ret void
+}
+
+define void @test4(i32 %a, i32 %b) nounwind {
+  %1 = icmp sgt i32 %a, -1
+  %2 = icmp sgt i32 %b, -1
+  %or.cond = and i1 %1, %2
+  br i1 %or.cond, label %if.then, label %if.end
+
+; CHECK: @test4
+; CHECK-NEXT: %1 = or i32 %a, %b
+; CHECK-NEXT: %2 = icmp sgt i32 %1, -1
+; CHECK-NEXT: br
+
+if.then:
+  tail call void @foo() nounwind
+  ret void
+
+if.end:
+  ret void
+}
+



   Commit: d1735a5be6f7416909b8736fa5a200e36b3a0b66
   Author: Matt Beaumont-Gay <matthewbg@google.com>
     Date: 03/29/2011 18:25:36
      URL: https://github.com/mono/llvm/commit/d1735a5be6f7416909b8736fa5a200e36b3a0b66


Quiet a gcc warning about changed name lookup rules

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

Changed paths:
 M cmake/modules/LLVMLibDeps.cmake
 M utils/TableGen/ClangSACheckersEmitter.cpp

Modified: cmake/modules/LLVMLibDeps.cmake
===================================================================
--- a/cmake/modules/LLVMLibDeps.cmake
+++ b/cmake/modules/LLVMLibDeps.cmake
@@ -33,7 +33,7 @@ set(MSVC_LIB_DEPS_LLVMMBlazeCodeGen LLVMAsmPrinter LLVMCodeGen \
LLVMCore LLVMMBla  set(MSVC_LIB_DEPS_LLVMMBlazeDisassembler LLVMMBlazeCodeGen \
LLVMMBlazeInfo LLVMMC LLVMSupport)  set(MSVC_LIB_DEPS_LLVMMBlazeInfo LLVMMC \
LLVMSupport)  set(MSVC_LIB_DEPS_LLVMMC LLVMSupport)
-set(MSVC_LIB_DEPS_LLVMMCDisassembler LLVMARMAsmParser LLVMARMCodeGen \
LLVMARMDisassembler LLVMARMInfo LLVMAlphaCodeGen LLVMAlphaInfo LLVMBlackfinCodeGen \
LLVMBlackfinInfo LLVMCBackend LLVMCBackendInfo LLVMCellSPUCodeGen LLVMCellSPUInfo \
LLVMCppBackend LLVMCppBackendInfo LLVMMBlazeAsmParser LLVMMBlazeCodeGen \
LLVMMBlazeDisassembler LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMMSP430CodeGen \
LLVMMSP430Info LLVMMipsCodeGen LLVMMipsInfo LLVMPTXCodeGen LLVMPTXInfo \
LLVMPowerPCCodeGen LLVMPowerPCInfo LLVMSparcCodeGen LLVMSparcInfo LLVMSupport \
LLVMSystemZCodeGen LLVMSystemZInfo LLVMX86AsmParser LLVMX86CodeGen \
LLVMX86Disassembler LLVMX86Info LLVMXCoreCodeGen LLVMXCoreInfo) \
+set(MSVC_LIB_DEPS_LLVMMCDisassembler LLVMARMAsmParser LLVMARMCodeGen \
LLVMARMDisassembler LLVMARMInfo LLVMAlphaCodeGen LLVMAlphaInfo LLVMBlackfinCodeGen \
LLVMBlackfinInfo LLVMCBackend LLVMCBackendInfo LLVMCellSPUCodeGen LLVMCellSPUInfo \
LLVMCppBackend LLVMCppBackendInfo LLVMMBlazeAsmParser LLVMMBlazeCodeGen \
LLVMMBlazeDisassembler LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMMSP430CodeGen \
LLVMMSP430Info LLVMMipsCodeGen LLVMMipsInfo LLVMPTXCodeGen LLVMPTXInfo \
LLVMPowerPCCodeGen LLVMPowerPCInfo LLVMSparcCodeGen LLVMSparcInfo LLVMSupport \
LLVMSystemZCodeGen LLVMSystemZInfo LLVMTarget LLVMX86AsmParser LLVMX86CodeGen \
LLVMX86Disassembler LLVMX86Info LLVMXCoreCodeGen LLVMXCoreInfo)  \
set(MSVC_LIB_DEPS_LLVMMCJIT LLVMCore LLVMExecutionEngine LLVMRuntimeDyld LLVMSupport \
LLVMTarget)  set(MSVC_LIB_DEPS_LLVMMCParser LLVMMC LLVMSupport)
 set(MSVC_LIB_DEPS_LLVMMSP430AsmPrinter LLVMMC LLVMSupport)
Modified: utils/TableGen/ClangSACheckersEmitter.cpp
===================================================================
--- a/utils/TableGen/ClangSACheckersEmitter.cpp
+++ b/utils/TableGen/ClangSACheckersEmitter.cpp
@@ -246,13 +246,13 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) {
 
     llvm::DenseSet<const Record *> &checkers = I->second.Checkers;
     if (!checkers.empty()) {
+      OS << "static const short CheckerArray" << I->second.Index << "[] = { ";
       // Make the output order deterministic.
       std::map<int, const Record *> sorted;
       for (llvm::DenseSet<const Record *>::iterator
              I = checkers.begin(), E = checkers.end(); I != E; ++I)
         sorted[(*I)->getID()] = *I;
 
-      OS << "static const short CheckerArray" << I->second.Index << "[] = { ";
       for (std::map<int, const Record *>::iterator
              I = sorted.begin(), E = sorted.end(); I != E; ++I)
         OS << checkerRecIndexMap[I->second] << ", ";
@@ -261,13 +261,13 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) {
     
     llvm::DenseSet<const Record *> &subGroups = I->second.SubGroups;
     if (!subGroups.empty()) {
+      OS << "static const short SubPackageArray" << I->second.Index << "[] = { ";
       // Make the output order deterministic.
       std::map<int, const Record *> sorted;
       for (llvm::DenseSet<const Record *>::iterator
              I = subGroups.begin(), E = subGroups.end(); I != E; ++I)
         sorted[(*I)->getID()] = *I;
 
-      OS << "static const short SubPackageArray" << I->second.Index << "[] = { ";
       for (std::map<int, const Record *>::iterator
              I = sorted.begin(), E = sorted.end(); I != E; ++I) {
         OS << recordGroupMap[I->second]->Index << ", ";


   Commit: 7a0a8a5b1fce9c69e9f0fe51fbf27bf98ddd1266
   Author: Matt Beaumont-Gay <matthewbg@google.com>
     Date: 03/29/2011 18:42:41
      URL: https://github.com/mono/llvm/commit/7a0a8a5b1fce9c69e9f0fe51fbf27bf98ddd1266


Revert accidental change to LLVMLibDeps.cmake

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

Changed paths:
 M cmake/modules/LLVMLibDeps.cmake

Modified: cmake/modules/LLVMLibDeps.cmake
===================================================================
--- a/cmake/modules/LLVMLibDeps.cmake
+++ b/cmake/modules/LLVMLibDeps.cmake
@@ -33,7 +33,7 @@ set(MSVC_LIB_DEPS_LLVMMBlazeCodeGen LLVMAsmPrinter LLVMCodeGen \
LLVMCore LLVMMBla  set(MSVC_LIB_DEPS_LLVMMBlazeDisassembler LLVMMBlazeCodeGen \
LLVMMBlazeInfo LLVMMC LLVMSupport)  set(MSVC_LIB_DEPS_LLVMMBlazeInfo LLVMMC \
LLVMSupport)  set(MSVC_LIB_DEPS_LLVMMC LLVMSupport)
-set(MSVC_LIB_DEPS_LLVMMCDisassembler LLVMARMAsmParser LLVMARMCodeGen \
LLVMARMDisassembler LLVMARMInfo LLVMAlphaCodeGen LLVMAlphaInfo LLVMBlackfinCodeGen \
LLVMBlackfinInfo LLVMCBackend LLVMCBackendInfo LLVMCellSPUCodeGen LLVMCellSPUInfo \
LLVMCppBackend LLVMCppBackendInfo LLVMMBlazeAsmParser LLVMMBlazeCodeGen \
LLVMMBlazeDisassembler LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMMSP430CodeGen \
LLVMMSP430Info LLVMMipsCodeGen LLVMMipsInfo LLVMPTXCodeGen LLVMPTXInfo \
LLVMPowerPCCodeGen LLVMPowerPCInfo LLVMSparcCodeGen LLVMSparcInfo LLVMSupport \
LLVMSystemZCodeGen LLVMSystemZInfo LLVMTarget LLVMX86AsmParser LLVMX86CodeGen \
LLVMX86Disassembler LLVMX86Info LLVMXCoreCodeGen LLVMXCoreInfo) \
+set(MSVC_LIB_DEPS_LLVMMCDisassembler LLVMARMAsmParser LLVMARMCodeGen \
LLVMARMDisassembler LLVMARMInfo LLVMAlphaCodeGen LLVMAlphaInfo LLVMBlackfinCodeGen \
LLVMBlackfinInfo LLVMCBackend LLVMCBackendInfo LLVMCellSPUCodeGen LLVMCellSPUInfo \
LLVMCppBackend LLVMCppBackendInfo LLVMMBlazeAsmParser LLVMMBlazeCodeGen \
LLVMMBlazeDisassembler LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMMSP430CodeGen \
LLVMMSP430Info LLVMMipsCodeGen LLVMMipsInfo LLVMPTXCodeGen LLVMPTXInfo \
LLVMPowerPCCodeGen LLVMPowerPCInfo LLVMSparcCodeGen LLVMSparcInfo LLVMSupport \
LLVMSystemZCodeGen LLVMSystemZInfo LLVMX86AsmParser LLVMX86CodeGen \
LLVMX86Disassembler LLVMX86Info LLVMXCoreCodeGen LLVMXCoreInfo)  \
set(MSVC_LIB_DEPS_LLVMMCJIT LLVMCore LLVMExecutionEngine LLVMRuntimeDyld LLVMSupport \
LLVMTarget)  set(MSVC_LIB_DEPS_LLVMMCParser LLVMMC LLVMSupport)
 set(MSVC_LIB_DEPS_LLVMMSP430AsmPrinter LLVMMC LLVMSupport)


   Commit: ec293590b8b638ff62e5430dec97641afae5422a
   Author: Bill Wendling <isanbard@gmail.com>
     Date: 03/29/2011 19:05:41
      URL: https://github.com/mono/llvm/commit/ec293590b8b638ff62e5430dec97641afae5422a


We need to copy over the unnamed_addr attribute.

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

Changed paths:
 M lib/Linker/LinkModules.cpp

Modified: lib/Linker/LinkModules.cpp
===================================================================
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -352,6 +352,7 @@ static void CopyGVAttributes(GlobalValue *DestGV, const \
GlobalValue *SrcGV) {  unsigned Alignment = std::max(DestGV->getAlignment(), \
SrcGV->getAlignment());  DestGV->copyAttributesFrom(SrcGV);
   DestGV->setAlignment(Alignment);
+  DestGV->setUnnamedAddr(SrcGV->hasUnnamedAddr());
 }
 
 /// GetLinkageResult - This analyzes the two global values and determines what


   Commit: 0401975f34e151c638eff752ef3e08c701218580
   Author: Evan Cheng <evan.cheng@apple.com>
     Date: 03/29/2011 19:06:19
      URL: https://github.com/mono/llvm/commit/0401975f34e151c638eff752ef3e08c701218580


Add intrinsics @llvm.arm.neon.vmulls and @llvm.arm.neon.vmullu.* back. Frontends
was lowering them to sext / uxt + mul instructions. Unfortunately the
optimization passes may hoist the extensions out of the loop and separate them.
When that happens, the long multiplication instructions can be broken into
several scalar instructions, causing significant performance issue.

Note the vmla and vmls intrinsics are not added back. Frontend will codegen them
as intrinsics vmull* + add / sub. Also note the isel optimizations for catching
mul + sext / zext are not changed either.

First part of rdar://8832507, rdar://9203134


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

Changed paths:
 M include/llvm/IntrinsicsARM.td
 M lib/Target/ARM/ARMISelLowering.cpp
 M lib/VMCore/AutoUpgrade.cpp
 M test/Bitcode/neon-intrinsics.ll
 M test/CodeGen/ARM/vmul.ll

Modified: include/llvm/IntrinsicsARM.td
===================================================================
--- a/include/llvm/IntrinsicsARM.td
+++ b/include/llvm/IntrinsicsARM.td
@@ -129,8 +129,12 @@ let Properties = [IntrNoMem, Commutative] in {
   def int_arm_neon_vmulp : Neon_2Arg_Intrinsic;
   def int_arm_neon_vqdmulh : Neon_2Arg_Intrinsic;
   def int_arm_neon_vqrdmulh : Neon_2Arg_Intrinsic;
+  def int_arm_neon_vmulls : Neon_2Arg_Long_Intrinsic;
+  def int_arm_neon_vmullu : Neon_2Arg_Long_Intrinsic;
   def int_arm_neon_vmullp : Neon_2Arg_Long_Intrinsic;
   def int_arm_neon_vqdmull : Neon_2Arg_Long_Intrinsic;
+
+  // Vector Multiply and Accumulate/Subtract.
   def int_arm_neon_vqdmlal : Neon_3Arg_Long_Intrinsic;
   def int_arm_neon_vqdmlsl : Neon_3Arg_Long_Intrinsic;
 
@@ -292,7 +296,7 @@ def int_arm_neon_vcvtfp2hf
 def int_arm_neon_vcvthf2fp
     : Intrinsic<[llvm_v4f32_ty], [llvm_v4i16_ty], [IntrNoMem]>;
 
-// Narrowing Saturating Vector Moves.
+// Narrowing and Lengthening Vector Moves.
 def int_arm_neon_vqmovns : Neon_1Arg_Narrow_Intrinsic;
 def int_arm_neon_vqmovnu : Neon_1Arg_Narrow_Intrinsic;
 def int_arm_neon_vqmovnsu : Neon_1Arg_Narrow_Intrinsic;
Modified: lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -2157,6 +2157,13 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, \
SelectionDAG &DAG,  }
     return Result;
   }
+  case Intrinsic::arm_neon_vmulls:
+  case Intrinsic::arm_neon_vmullu: {
+    unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmulls)
+      ? ARMISD::VMULLs : ARMISD::VMULLu;
+    return DAG.getNode(NewOpc, Op.getDebugLoc(), Op.getValueType(),
+                       Op.getOperand(1), Op.getOperand(2));
+  }
   }
 }
 
Modified: lib/VMCore/AutoUpgrade.cpp
===================================================================
--- a/lib/VMCore/AutoUpgrade.cpp
+++ b/lib/VMCore/AutoUpgrade.cpp
@@ -84,7 +84,6 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function \
*&NewFn) {  Name.compare(14, 5, "vsubl", 5) == 0 ||
             Name.compare(14, 5, "vaddw", 5) == 0 ||
             Name.compare(14, 5, "vsubw", 5) == 0 ||
-            Name.compare(14, 5, "vmull", 5) == 0 ||
             Name.compare(14, 5, "vmlal", 5) == 0 ||
             Name.compare(14, 5, "vmlsl", 5) == 0 ||
             Name.compare(14, 5, "vabdl", 5) == 0 ||
Modified: test/Bitcode/neon-intrinsics.ll
===================================================================
--- a/test/Bitcode/neon-intrinsics.ll
+++ b/test/Bitcode/neon-intrinsics.ll
@@ -76,20 +76,13 @@
 ; CHECK: zext <4 x i16>
 ; CHECK-NEXT: sub <4 x i32>
 
-; vmull should be auto-upgraded to multiply with sext/zext
-; (but vmullp should remain an intrinsic)
+; vmull* intrinsics will remain intrinsics
 
 ; CHECK: vmulls8
-; CHECK-NOT: arm.neon.vmulls.v8i16
-; CHECK: sext <8 x i8>
-; CHECK-NEXT: sext <8 x i8>
-; CHECK-NEXT: mul <8 x i16>
+; CHECK: arm.neon.vmulls.v8i16
 
 ; CHECK: vmullu16
-; CHECK-NOT: arm.neon.vmullu.v4i32
-; CHECK: zext <4 x i16>
-; CHECK-NEXT: zext <4 x i16>
-; CHECK-NEXT: mul <4 x i32>
+; CHECK: arm.neon.vmullu.v4i32
 
 ; CHECK: vmullp8
 ; CHECK: arm.neon.vmullp.v8i16
Modified: test/CodeGen/ARM/vmul.ll
===================================================================
--- a/test/CodeGen/ARM/vmul.ll
+++ b/test/CodeGen/ARM/vmul.ll
@@ -158,6 +158,15 @@ define <8 x i16> @vmulls8(<8 x i8>* %A, <8 x i8>* %B) nounwind {
 	ret <8 x i16> %tmp5
 }
 
+define <8 x i16> @vmulls8_int(<8 x i8>* %A, <8 x i8>* %B) nounwind {
+;CHECK: vmulls8_int:
+;CHECK: vmull.s8
+	%tmp1 = load <8 x i8>* %A
+	%tmp2 = load <8 x i8>* %B
+	%tmp3 = call <8 x i16> @llvm.arm.neon.vmulls.v8i16(<8 x i8> %tmp1, <8 x i8> %tmp2)
+	ret <8 x i16> %tmp3
+}
+
 define <4 x i32> @vmulls16(<4 x i16>* %A, <4 x i16>* %B) nounwind {
 ;CHECK: vmulls16:
 ;CHECK: vmull.s16
@@ -169,6 +178,15 @@ define <4 x i32> @vmulls16(<4 x i16>* %A, <4 x i16>* %B) \
nounwind {  ret <4 x i32> %tmp5
 }
 
+define <4 x i32> @vmulls16_int(<4 x i16>* %A, <4 x i16>* %B) nounwind {
+;CHECK: vmulls16_int:
+;CHECK: vmull.s16
+	%tmp1 = load <4 x i16>* %A
+	%tmp2 = load <4 x i16>* %B
+	%tmp3 = call <4 x i32> @llvm.arm.neon.vmulls.v4i32(<4 x i16> %tmp1, <4 x i16> \
%tmp2) +	ret <4 x i32> %tmp3
+}
+
 define <2 x i64> @vmulls32(<2 x i32>* %A, <2 x i32>* %B) nounwind {
 ;CHECK: vmulls32:
 ;CHECK: vmull.s32
@@ -180,6 +198,15 @@ define <2 x i64> @vmulls32(<2 x i32>* %A, <2 x i32>* %B) \
nounwind {  ret <2 x i64> %tmp5
 }
 
+define <2 x i64> @vmulls32_int(<2 x i32>* %A, <2 x i32>* %B) nounwind {
+;CHECK: vmulls32_int:
+;CHECK: vmull.s32
+	%tmp1 = load <2 x i32>* %A
+	%tmp2 = load <2 x i32>* %B
+	%tmp3 = call <2 x i64> @llvm.arm.neon.vmulls.v2i64(<2 x i32> %tmp1, <2 x i32> \
%tmp2) +	ret <2 x i64> %tmp3
+}
+
 define <8 x i16> @vmullu8(<8 x i8>* %A, <8 x i8>* %B) nounwind {
 ;CHECK: vmullu8:
 ;CHECK: vmull.u8
@@ -191,6 +218,15 @@ define <8 x i16> @vmullu8(<8 x i8>* %A, <8 x i8>* %B) nounwind {
 	ret <8 x i16> %tmp5
 }
 
+define <8 x i16> @vmullu8_int(<8 x i8>* %A, <8 x i8>* %B) nounwind {
+;CHECK: vmullu8_int:
+;CHECK: vmull.u8
+	%tmp1 = load <8 x i8>* %A
+	%tmp2 = load <8 x i8>* %B
+	%tmp3 = call <8 x i16> @llvm.arm.neon.vmullu.v8i16(<8 x i8> %tmp1, <8 x i8> %tmp2)
+	ret <8 x i16> %tmp3
+}
+
 define <4 x i32> @vmullu16(<4 x i16>* %A, <4 x i16>* %B) nounwind {
 ;CHECK: vmullu16:
 ;CHECK: vmull.u16
@@ -202,6 +238,15 @@ define <4 x i32> @vmullu16(<4 x i16>* %A, <4 x i16>* %B) \
nounwind {  ret <4 x i32> %tmp5
 }
 
+define <4 x i32> @vmullu16_int(<4 x i16>* %A, <4 x i16>* %B) nounwind {
+;CHECK: vmullu16_int:
+;CHECK: vmull.u16
+	%tmp1 = load <4 x i16>* %A
+	%tmp2 = load <4 x i16>* %B
+	%tmp3 = call <4 x i32> @llvm.arm.neon.vmullu.v4i32(<4 x i16> %tmp1, <4 x i16> \
%tmp2) +	ret <4 x i32> %tmp3
+}
+
 define <2 x i64> @vmullu32(<2 x i32>* %A, <2 x i32>* %B) nounwind {
 ;CHECK: vmullu32:
 ;CHECK: vmull.u32
@@ -213,6 +258,15 @@ define <2 x i64> @vmullu32(<2 x i32>* %A, <2 x i32>* %B) \
nounwind {  ret <2 x i64> %tmp5
 }
 
+define <2 x i64> @vmullu32_int(<2 x i32>* %A, <2 x i32>* %B) nounwind {
+;CHECK: vmullu32_int:
+;CHECK: vmull.u32
+	%tmp1 = load <2 x i32>* %A
+	%tmp2 = load <2 x i32>* %B
+	%tmp3 = call <2 x i64> @llvm.arm.neon.vmullu.v2i64(<2 x i32> %tmp1, <2 x i32> \
%tmp2) +	ret <2 x i64> %tmp3
+}
+
 define <8 x i16> @vmullp8(<8 x i8>* %A, <8 x i8>* %B) nounwind {
 ;CHECK: vmullp8:
 ;CHECK: vmull.p8
@@ -233,6 +287,15 @@ entry:
   ret <4 x i32> %3
 }
 
+define arm_aapcs_vfpcc <4 x i32> @test_vmull_lanes16_int(<4 x i16> %arg0_int16x4_t, \
<4 x i16> %arg1_int16x4_t) nounwind readnone { +entry:
+; CHECK: test_vmull_lanes16_int
+; CHECK: vmull.s16 q0, d0, d1[1]
+  %0 = shufflevector <4 x i16> %arg1_int16x4_t, <4 x i16> undef, <4 x i32> <i32 1, \
i32 1, i32 1, i32 1> ; <<4 x i16>> [#uses=1] +  %1 = tail call <4 x i32> \
@llvm.arm.neon.vmulls.v4i32(<4 x i16> %arg0_int16x4_t, <4 x i16> %0) ; <<4 x i32>> \
[#uses=1] +  ret <4 x i32> %1
+}
+
 define arm_aapcs_vfpcc <2 x i64> @test_vmull_lanes32(<2 x i32> %arg0_int32x2_t, <2 x \
i32> %arg1_int32x2_t) nounwind readnone {  entry:
 ; CHECK: test_vmull_lanes32
@@ -244,6 +307,15 @@ entry:
   ret <2 x i64> %3
 }
 
+define arm_aapcs_vfpcc <2 x i64> @test_vmull_lanes32_int(<2 x i32> %arg0_int32x2_t, \
<2 x i32> %arg1_int32x2_t) nounwind readnone { +entry:
+; CHECK: test_vmull_lanes32_int
+; CHECK: vmull.s32 q0, d0, d1[1]
+  %0 = shufflevector <2 x i32> %arg1_int32x2_t, <2 x i32> undef, <2 x i32> <i32 1, \
i32 1> ; <<2 x i32>> [#uses=1] +  %1 = tail call <2 x i64> \
@llvm.arm.neon.vmulls.v2i64(<2 x i32> %arg0_int32x2_t, <2 x i32> %0) ; <<2 x i64>> \
[#uses=1] +  ret <2 x i64> %1
+}
+
 define arm_aapcs_vfpcc <4 x i32> @test_vmull_laneu16(<4 x i16> %arg0_uint16x4_t, <4 \
x i16> %arg1_uint16x4_t) nounwind readnone {  entry:
 ; CHECK: test_vmull_laneu16
@@ -255,6 +327,15 @@ entry:
   ret <4 x i32> %3
 }
 
+define arm_aapcs_vfpcc <4 x i32> @test_vmull_laneu16_int(<4 x i16> %arg0_uint16x4_t, \
<4 x i16> %arg1_uint16x4_t) nounwind readnone { +entry:
+; CHECK: test_vmull_laneu16_int
+; CHECK: vmull.u16 q0, d0, d1[1]
+  %0 = shufflevector <4 x i16> %arg1_uint16x4_t, <4 x i16> undef, <4 x i32> <i32 1, \
i32 1, i32 1, i32 1> ; <<4 x i16>> [#uses=1] +  %1 = tail call <4 x i32> \
@llvm.arm.neon.vmullu.v4i32(<4 x i16> %arg0_uint16x4_t, <4 x i16> %0) ; <<4 x i32>> \
[#uses=1] +  ret <4 x i32> %1
+}
+
 define arm_aapcs_vfpcc <2 x i64> @test_vmull_laneu32(<2 x i32> %arg0_uint32x2_t, <2 \
x i32> %arg1_uint32x2_t) nounwind readnone {  entry:
 ; CHECK: test_vmull_laneu32
@@ -266,6 +347,23 @@ entry:
   ret <2 x i64> %3
 }
 
+define arm_aapcs_vfpcc <2 x i64> @test_vmull_laneu32_int(<2 x i32> %arg0_uint32x2_t, \
<2 x i32> %arg1_uint32x2_t) nounwind readnone { +entry:
+; CHECK: test_vmull_laneu32_int
+; CHECK: vmull.u32 q0, d0, d1[1]
+  %0 = shufflevector <2 x i32> %arg1_uint32x2_t, <2 x i32> undef, <2 x i32> <i32 1, \
i32 1> ; <<2 x i32>> [#uses=1] +  %1 = tail call <2 x i64> \
@llvm.arm.neon.vmullu.v2i64(<2 x i32> %arg0_uint32x2_t, <2 x i32> %0) ; <<2 x i64>> \
[#uses=1] +  ret <2 x i64> %1
+}
+
+declare <8 x i16> @llvm.arm.neon.vmulls.v8i16(<8 x i8>, <8 x i8>) nounwind readnone
+declare <4 x i32> @llvm.arm.neon.vmulls.v4i32(<4 x i16>, <4 x i16>) nounwind \
readnone +declare <2 x i64> @llvm.arm.neon.vmulls.v2i64(<2 x i32>, <2 x i32>) \
nounwind readnone +
+declare <8 x i16> @llvm.arm.neon.vmullu.v8i16(<8 x i8>, <8 x i8>) nounwind readnone
+declare <4 x i32> @llvm.arm.neon.vmullu.v4i32(<4 x i16>, <4 x i16>) nounwind \
readnone +declare <2 x i64> @llvm.arm.neon.vmullu.v2i64(<2 x i32>, <2 x i32>) \
nounwind readnone +
 declare <8 x i16>  @llvm.arm.neon.vmullp.v8i16(<8 x i8>, <8 x i8>) nounwind readnone
 
 


   Commit: 3be48b025f5a7d3479742f2a4fba3060d7215110
   Author: Francois Pichet <pichet2000@gmail.com>
     Date: 03/29/2011 19:18:51
      URL: https://github.com/mono/llvm/commit/3be48b025f5a7d3479742f2a4fba3060d7215110


Update CMake link dependency.

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

Changed paths:
 M tools/llvm-rtdyld/CMakeLists.txt

Modified: tools/llvm-rtdyld/CMakeLists.txt
===================================================================
--- a/tools/llvm-rtdyld/CMakeLists.txt
+++ b/tools/llvm-rtdyld/CMakeLists.txt
@@ -1,4 +1,4 @@
-set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support MC object RuntimeDyld)
+set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support MC object RuntimeDyld JIT)
 
 add_llvm_tool(llvm-rtdyld
   llvm-rtdyld.cpp


   Commit: 87971a00e40cdc636aa1642838ad819efa7a8197
   Author: Jim Grosbach <grosbach@apple.com>
     Date: 03/29/2011 19:20:22
      URL: https://github.com/mono/llvm/commit/87971a00e40cdc636aa1642838ad819efa7a8197


Tidy up. 80 columns and trailing whitespace.

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

Changed paths:
 M lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Modified: lib/CodeGen/AsmPrinter/AsmPrinter.cpp
===================================================================
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -70,17 +70,17 @@ static unsigned getGVAlignmentLog2(const GlobalValue *GV, const \
TargetData &TD,  unsigned NumBits = 0;
   if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
     NumBits = TD.getPreferredAlignmentLog(GVar);
-  
+
   // If InBits is specified, round it to it.
   if (InBits > NumBits)
     NumBits = InBits;
-  
+
   // If the GV has a specified alignment, take it into account.
   if (GV->getAlignment() == 0)
     return NumBits;
-  
+
   unsigned GVAlign = Log2_32(GV->getAlignment());
-  
+
   // If the GVAlign is larger than NumBits, or if we are required to obey
   // NumBits because the GV has an assigned section, obey it.
   if (GVAlign > NumBits || GV->hasSection())
@@ -104,16 +104,16 @@ AsmPrinter::AsmPrinter(TargetMachine &tm, MCStreamer &Streamer)
 
 AsmPrinter::~AsmPrinter() {
   assert(DD == 0 && DE == 0 && "Debug/EH info didn't get finalized");
-  
+
   if (GCMetadataPrinters != 0) {
     gcp_map_type &GCMap = getGCMap(GCMetadataPrinters);
-    
+
     for (gcp_map_type::iterator I = GCMap.begin(), E = GCMap.end(); I != E; ++I)
       delete I->second;
     delete &GCMap;
     GCMetadataPrinters = 0;
   }
-  
+
   delete &OutStreamer;
 }
 
@@ -156,9 +156,9 @@ bool AsmPrinter::doInitialization(Module &M) {
   // Initialize TargetLoweringObjectFile.
   const_cast<TargetLoweringObjectFile&>(getObjFileLowering())
     .Initialize(OutContext, TM);
-  
+
   Mang = new Mangler(OutContext, *TM.getTargetData());
-  
+
   // Allow the target to emit any magic that it wants at the start of the file.
   EmitStartOfAsmFile(M);
 
@@ -255,7 +255,7 @@ void AsmPrinter::EmitLinkage(unsigned Linkage, MCSymbol *GVSym) \
const {  void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
   if (!GV->hasInitializer())   // External globals require no code.
     return;
-  
+
   // Check to see if this is a special global used by LLVM, if so, emit it.
   if (EmitSpecialLLVMGlobal(GV))
     return;
@@ -265,44 +265,44 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
                    /*PrintType=*/false, GV->getParent());
     OutStreamer.GetCommentOS() << '\n';
   }
-  
+
   MCSymbol *GVSym = Mang->getSymbol(GV);
   EmitVisibility(GVSym, GV->getVisibility());
 
   if (MAI->hasDotTypeDotSizeDirective())
     OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject);
-  
+
   SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM);
 
   const TargetData *TD = TM.getTargetData();
   uint64_t Size = TD->getTypeAllocSize(GV->getType()->getElementType());
-  
+
   // If the alignment is specified, we *must* obey it.  Overaligning a global
   // with a specified alignment is a prompt way to break globals emitted to
   // sections and expected to be contiguous (e.g. ObjC metadata).
   unsigned AlignLog = getGVAlignmentLog2(GV, *TD);
-  
+
   // Handle common and BSS local symbols (.lcomm).
   if (GVKind.isCommon() || GVKind.isBSSLocal()) {
     if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
-    
+
     if (isVerbose()) {
       WriteAsOperand(OutStreamer.GetCommentOS(), GV,
                      /*PrintType=*/false, GV->getParent());
       OutStreamer.GetCommentOS() << '\n';
     }
-    
+
     // Handle common symbols.
     if (GVKind.isCommon()) {
       unsigned Align = 1 << AlignLog;
       if (!getObjFileLowering().getCommDirectiveSupportsAlignment())
         Align = 0;
-          
+
       // .comm _foo, 42, 4
       OutStreamer.EmitCommonSymbol(GVSym, Size, Align);
       return;
     }
-    
+
     // Handle local BSS symbols.
     if (MAI->hasMachoZeroFillDirective()) {
       const MCSection *TheSection =
@@ -311,7 +311,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
       OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog);
       return;
     }
-    
+
     if (MAI->hasLCOMMDirective()) {
       // .lcomm _foo, 42
       OutStreamer.EmitLocalCommonSymbol(GVSym, Size);
@@ -321,14 +321,14 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
     unsigned Align = 1 << AlignLog;
     if (!getObjFileLowering().getCommDirectiveSupportsAlignment())
       Align = 0;
-    
+
     // .local _foo
     OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Local);
     // .comm _foo, 42, 4
     OutStreamer.EmitCommonSymbol(GVSym, Size, Align);
     return;
   }
-  
+
   const MCSection *TheSection =
     getObjFileLowering().SectionForGlobal(GV, GVKind, Mang, TM);
 
@@ -336,14 +336,14 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
   // emission.
   if (GVKind.isBSSExtern() && MAI->hasMachoZeroFillDirective()) {
     if (Size == 0) Size = 1;  // zerofill of 0 bytes is undefined.
-    
+
     // .globl _foo
     OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
     // .zerofill __DATA, __common, _foo, 400, 5
     OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog);
     return;
   }
-  
+
   // Handle thread local data for mach-o which requires us to output an
   // additional structure of data and mangle the original symbol so that we
   // can reference it later.
@@ -356,31 +356,31 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
   // specific code.
   if (GVKind.isThreadLocal() && MAI->hasMachoTBSSDirective()) {
     // Emit the .tbss symbol
-    MCSymbol *MangSym = 
+    MCSymbol *MangSym =
       OutContext.GetOrCreateSymbol(GVSym->getName() + Twine("$tlv$init"));
-    
+
     if (GVKind.isThreadBSS())
       OutStreamer.EmitTBSSSymbol(TheSection, MangSym, Size, 1 << AlignLog);
     else if (GVKind.isThreadData()) {
       OutStreamer.SwitchSection(TheSection);
 
-      EmitAlignment(AlignLog, GV);      
+      EmitAlignment(AlignLog, GV);
       OutStreamer.EmitLabel(MangSym);
-      
+
       EmitGlobalConstant(GV->getInitializer());
     }
-    
+
     OutStreamer.AddBlankLine();
-    
+
     // Emit the variable struct for the runtime.
-    const MCSection *TLVSect 
+    const MCSection *TLVSect
       = getObjFileLowering().getTLSExtraDataSection();
-      
+
     OutStreamer.SwitchSection(TLVSect);
     // Emit the linkage here.
     EmitLinkage(GV->getLinkage(), GVSym);
     OutStreamer.EmitLabel(GVSym);
-    
+
     // Three pointers in size:
     //   - __tlv_bootstrap - used to make sure support exists
     //   - spare pointer, used when mapped by the runtime
@@ -390,7 +390,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
                           PtrSize, 0);
     OutStreamer.EmitIntValue(0, PtrSize, 0);
     OutStreamer.EmitSymbolValue(MangSym, PtrSize, 0);
-    
+
     OutStreamer.AddBlankLine();
     return;
   }
@@ -407,7 +407,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
   if (MAI->hasDotTypeDotSizeDirective())
     // .size foo, 42
     OutStreamer.EmitELFSize(GVSym, MCConstantExpr::Create(Size, OutContext));
-  
+
   OutStreamer.AddBlankLine();
 }
 
@@ -416,7 +416,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
 void AsmPrinter::EmitFunctionHeader() {
   // Print out constants referenced by the function
   EmitConstantPool();
-  
+
   // Print the 'header' of function.
   const Function *F = MF->getFunction();
 
@@ -438,7 +438,7 @@ void AsmPrinter::EmitFunctionHeader() {
   // Emit the CurrentFnSym.  This is a virtual function to allow targets to
   // do their wild and crazy things as required.
   EmitFunctionEntryLabel();
-  
+
   // If the function had address-taken blocks that got deleted, then we have
   // references to the dangling symbols.  Emit them at the start of the function
   // so that we don't get references to undefined symbols.
@@ -448,17 +448,17 @@ void AsmPrinter::EmitFunctionHeader() {
     OutStreamer.AddComment("Address taken block that was later removed");
     OutStreamer.EmitLabel(DeadBlockSyms[i]);
   }
-  
+
   // Add some workaround for linkonce linkage on Cygwin\MinGW.
   if (MAI->getLinkOnceDirective() != 0 &&
       (F->hasLinkOnceLinkage() || F->hasWeakLinkage())) {
     // FIXME: What is this?
-    MCSymbol *FakeStub = 
+    MCSymbol *FakeStub =
       OutContext.GetOrCreateSymbol(Twine("Lllvm$workaround$fake$stub$")+
                                    CurrentFnSym->getName());
     OutStreamer.EmitLabel(FakeStub);
   }
-  
+
   // Emit pre-function debug and/or EH information.
   if (DE) {
     NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled);
@@ -483,7 +483,7 @@ void AsmPrinter::EmitFunctionEntryLabel() {
 }
 
 
-static void EmitDebugLoc(DebugLoc DL, const MachineFunction *MF, 
+static void EmitDebugLoc(DebugLoc DL, const MachineFunction *MF,
                          raw_ostream &CommentOS) {
   const LLVMContext &Ctx = MF->getFunction()->getContext();
   if (!DL.isUnknown()) {          // Print source line info.
@@ -509,18 +509,18 @@ static void EmitDebugLoc(DebugLoc DL, const MachineFunction \
*MF,  static void EmitComments(const MachineInstr &MI, raw_ostream &CommentOS) {
   const MachineFunction *MF = MI.getParent()->getParent();
   const TargetMachine &TM = MF->getTarget();
-  
+
   DebugLoc DL = MI.getDebugLoc();
   if (!DL.isUnknown()) {          // Print source line info.
     EmitDebugLoc(DL, MF, CommentOS);
     CommentOS << '\n';
   }
-  
+
   // Check for spills and reloads
   int FI;
-  
+
   const MachineFrameInfo *FrameInfo = MF->getFrameInfo();
-  
+
   // We assume a single instruction only has a spill or reload, not
   // both.
   const MachineMemOperand *MMO;
@@ -541,7 +541,7 @@ static void EmitComments(const MachineInstr &MI, raw_ostream \
&CommentOS) {  if (FrameInfo->isSpillSlotObjectIndex(FI))
       CommentOS << MMO->getSize() << "-byte Folded Spill\n";
   }
-  
+
   // Check for spill-induced copies
   if (MI.getAsmPrinterFlag(MachineInstr::ReloadReuse))
     CommentOS << " Reload Reuse\n";
@@ -615,7 +615,7 @@ static bool EmitDebugValueComment(const MachineInstr *MI, \
AsmPrinter &AP) {  }
     OS << AP.TM.getRegisterInfo()->getName(MI->getOperand(0).getReg());
   }
-  
+
   OS << '+' << MI->getOperand(1).getImm();
   // NOTE: Want this comment at start of line, don't emit with AddComment.
   AP.OutStreamer.EmitRawText(OS.str());
@@ -627,9 +627,9 @@ static bool EmitDebugValueComment(const MachineInstr *MI, \
AsmPrinter &AP) {  void AsmPrinter::EmitFunctionBody() {
   // Emit target-specific gunk before the function body.
   EmitFunctionBodyStart();
-  
+
   bool ShouldPrintDebugScopes = DD && MMI->hasDebugInfo();
-  
+
   // Print out code for the function.
   bool HasAnyRealCode = false;
   const MachineInstr *LastMI = 0;
@@ -652,7 +652,7 @@ void AsmPrinter::EmitFunctionBody() {
         NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
         DD->beginInstruction(II);
       }
-      
+
       if (isVerbose())
         EmitComments(*II, OutStreamer.GetCommentOS());
 
@@ -681,7 +681,7 @@ void AsmPrinter::EmitFunctionBody() {
         EmitInstruction(II);
         break;
       }
-      
+
       if (ShouldPrintDebugScopes) {
         NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
         DD->endInstruction(II);
@@ -708,10 +708,10 @@ void AsmPrinter::EmitFunctionBody() {
     } else  // Target not mc-ized yet.
       OutStreamer.EmitRawText(StringRef("\tnop\n"));
   }
-  
+
   // Emit target-specific gunk after the function body.
   EmitFunctionBodyEnd();
-  
+
   // If the target wants a .size directive for the size of the function, emit
   // it.
   if (MAI->hasDotTypeDotSizeDirective()) {
@@ -719,14 +719,14 @@ void AsmPrinter::EmitFunctionBody() {
     // difference between the function label and the temp label.
     MCSymbol *FnEndLabel = OutContext.CreateTempSymbol();
     OutStreamer.EmitLabel(FnEndLabel);
-    
+
     const MCExpr *SizeExp =
       MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(FnEndLabel, OutContext),
                               MCSymbolRefExpr::Create(CurrentFnSym, OutContext),
                               OutContext);
     OutStreamer.EmitELFSize(CurrentFnSym, SizeExp);
   }
-  
+
   // Emit post-function debug information.
   if (DD) {
     NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
@@ -737,16 +737,17 @@ void AsmPrinter::EmitFunctionBody() {
     DE->EndFunction();
   }
   MMI->EndFunction();
-  
+
   // Print out jump tables referenced by the function.
   EmitJumpTableInfo();
-  
+
   OutStreamer.AddBlankLine();
 }
 
 /// getDebugValueLocation - Get location information encoded by DBG_VALUE
 /// operands.
-MachineLocation AsmPrinter::getDebugValueLocation(const MachineInstr *MI) const {
+MachineLocation AsmPrinter::
+getDebugValueLocation(const MachineInstr *MI) const {
   // Target specific DBG_VALUE instructions are handled by each target.
   return MachineLocation();
 }
@@ -785,7 +786,7 @@ bool AsmPrinter::doFinalization(Module &M) {
     }
     delete DD; DD = 0;
   }
-  
+
   // If the target wants to know about weak references, print them all.
   if (MAI->getWeakRefDirective()) {
     // FIXME: This is not lazy, it would be nice to only print weak references
@@ -799,7 +800,7 @@ bool AsmPrinter::doFinalization(Module &M) {
       if (!I->hasExternalWeakLinkage()) continue;
       OutStreamer.EmitSymbolAttribute(Mang->getSymbol(I), MCSA_WeakReference);
     }
-    
+
     for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) {
       if (!I->hasExternalWeakLinkage()) continue;
       OutStreamer.EmitSymbolAttribute(Mang->getSymbol(I), MCSA_WeakReference);
@@ -825,7 +826,7 @@ bool AsmPrinter::doFinalization(Module &M) {
       EmitVisibility(Name, I->getVisibility());
 
       // Emit the directives as assignments aka .set:
-      OutStreamer.EmitAssignment(Name, 
+      OutStreamer.EmitAssignment(Name,
                                  MCSymbolRefExpr::Create(Target, OutContext));
     }
   }
@@ -842,14 +843,14 @@ bool AsmPrinter::doFinalization(Module &M) {
   if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty())
     if (const MCSection *S = MAI->getNonexecutableStackSection(OutContext))
       OutStreamer.SwitchSection(S);
-  
+
   // Allow the target to emit any magic that it wants at the end of the file,
   // after everything else has gone out.
   EmitEndOfAsmFile(M);
-  
+
   delete Mang; Mang = 0;
   MMI = 0;
-  
+
   OutStreamer.Finish();
   return false;
 }
@@ -889,7 +890,7 @@ void AsmPrinter::EmitConstantPool() {
   for (unsigned i = 0, e = CP.size(); i != e; ++i) {
     const MachineConstantPoolEntry &CPE = CP[i];
     unsigned Align = CPE.getAlignment();
-    
+
     SectionKind Kind;
     switch (CPE.getRelocationInfo()) {
     default: llvm_unreachable("Unknown section kind");
@@ -907,7 +908,7 @@ void AsmPrinter::EmitConstantPool() {
     }
 
     const MCSection *S = getObjFileLowering().getSectionForConstant(Kind);
-    
+
     // The number of sections are small, just do a linear search from the
     // last section to the first.
     bool Found = false;
@@ -956,7 +957,7 @@ void AsmPrinter::EmitConstantPool() {
 }
 
 /// EmitJumpTableInfo - Print assembly representations of the jump tables used
-/// by the current function to the current output stream.  
+/// by the current function to the current output stream.
 ///
 void AsmPrinter::EmitJumpTableInfo() {
   const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
@@ -965,7 +966,7 @@ void AsmPrinter::EmitJumpTableInfo() {
   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
   if (JT.empty()) return;
 
-  // Pick the directive to use to print the jump table entries, and switch to 
+  // Pick the directive to use to print the jump table entries, and switch to
   // the appropriate section.
   const Function *F = MF->getFunction();
   bool JTInDiffSection = false;
@@ -981,18 +982,18 @@ void AsmPrinter::EmitJumpTableInfo() {
     OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F,Mang,TM));
   } else {
     // Otherwise, drop it in the readonly section.
-    const MCSection *ReadOnlySection = 
+    const MCSection *ReadOnlySection =
       getObjFileLowering().getSectionForConstant(SectionKind::getReadOnly());
     OutStreamer.SwitchSection(ReadOnlySection);
     JTInDiffSection = true;
   }
 
   EmitAlignment(Log2_32(MJTI->getEntryAlignment(*TM.getTargetData())));
-  
+
   for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) {
     const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
-    
-    // If this jump table was deleted, ignore it. 
+
+    // If this jump table was deleted, ignore it.
     if (JTBBs.empty()) continue;
 
     // For the EK_LabelDifference32 entry, if the target supports .set, emit a
@@ -1006,15 +1007,15 @@ void AsmPrinter::EmitJumpTableInfo() {
       for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) {
         const MachineBasicBlock *MBB = JTBBs[ii];
         if (!EmittedSets.insert(MBB)) continue;
-        
+
         // .set LJTSet, LBB32-base
         const MCExpr *LHS =
           MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
         OutStreamer.EmitAssignment(GetJTSetSymbol(JTI, MBB->getNumber()),
                                 MCBinaryExpr::CreateSub(LHS, Base, OutContext));
       }
-    }          
-    
+    }
+
     // On some targets (e.g. Darwin) we want to emit two consecutive labels
     // before each jump table.  The first label is never referenced, but tells
     // the assembler and linker the extents of the jump table object.  The
@@ -1067,8 +1068,8 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo \
*MJTI,  // If the .set directive is supported, this is emitted as:
     //      .set L4_5_set_123, LBB123 - LJTI1_2
     //      .word L4_5_set_123
-    
-    // If we have emitted set directives for the jump table entries, print 
+
+    // If we have emitted set directives for the jump table entries, print
     // them rather than the entries themselves.  If we're emitting PIC, then
     // emit the table entries as differences between two text section labels.
     if (MAI->hasSetDirective()) {
@@ -1084,9 +1085,9 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo \
*MJTI,  break;
   }
   }
-  
+
   assert(Value && "Unknown entry kind!");
- 
+
   unsigned EntrySize = MJTI->getEntrySize(*TM.getTargetData());
   OutStreamer.EmitValue(Value, EntrySize, /*addrspace*/0);
 }
@@ -1106,18 +1107,18 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable \
*GV) {  if (GV->getSection() == "llvm.metadata" ||
       GV->hasAvailableExternallyLinkage())
     return true;
-  
+
   if (!GV->hasAppendingLinkage()) return false;
 
   assert(GV->hasInitializer() && "Not a special LLVM global!");
-  
+
   const TargetData *TD = TM.getTargetData();
   unsigned Align = Log2_32(TD->getPointerPrefAlignment());
   if (GV->getName() == "llvm.global_ctors") {
     OutStreamer.SwitchSection(getObjFileLowering().getStaticCtorSection());
     EmitAlignment(Align);
     EmitXXStructorList(GV->getInitializer());
-    
+
     if (TM.getRelocationModel() == Reloc::Static &&
         MAI->hasStaticCtorDtorReferenceInStaticMode()) {
       StringRef Sym(".constructors_used");
@@ -1125,8 +1126,8 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable \
*GV) {  MCSA_Reference);
     }
     return true;
-  } 
-  
+  }
+
   if (GV->getName() == "llvm.global_dtors") {
     OutStreamer.SwitchSection(getObjFileLowering().getStaticDtorSection());
     EmitAlignment(Align);
@@ -1140,7 +1141,7 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable \
*GV) {  }
     return true;
   }
-  
+
   return false;
 }
 
@@ -1151,7 +1152,7 @@ void AsmPrinter::EmitLLVMUsedList(Constant *List) {
   // Should be an array of 'i8*'.
   ConstantArray *InitList = dyn_cast<ConstantArray>(List);
   if (InitList == 0) return;
-  
+
   for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
     const GlobalValue *GV =
       dyn_cast<GlobalValue>(InitList->getOperand(i)->stripPointerCasts());
@@ -1160,7 +1161,7 @@ void AsmPrinter::EmitLLVMUsedList(Constant *List) {
   }
 }
 
-/// EmitXXStructorList - Emit the ctor or dtor list.  This just prints out the 
+/// EmitXXStructorList - Emit the ctor or dtor list.  This just prints out the
 /// function pointers, ignoring the init priority.
 void AsmPrinter::EmitXXStructorList(Constant *List) {
   // Should be an array of '{ int, void ()* }' structs.  The first value is the
@@ -1206,11 +1207,11 @@ void AsmPrinter::EmitInt32(int Value) const {
 void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
                                      unsigned Size) const {
   // Get the Hi-Lo expression.
-  const MCExpr *Diff = 
+  const MCExpr *Diff =
     MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(Hi, OutContext),
                             MCSymbolRefExpr::Create(Lo, OutContext),
                             OutContext);
-  
+
   if (!MAI->hasSetDirective()) {
     OutStreamer.EmitValue(Diff, Size, 0/*AddrSpace*/);
     return;
@@ -1222,27 +1223,27 @@ void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, \
const MCSymbol *Lo,  OutStreamer.EmitSymbolValue(SetLabel, Size, 0/*AddrSpace*/);
 }
 
-/// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo" 
+/// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo"
 /// where the size in bytes of the directive is specified by Size and Hi/Lo
 /// specify the labels.  This implicitly uses .set if it is available.
 void AsmPrinter::EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset,
-                                           const MCSymbol *Lo, unsigned Size) 
+                                           const MCSymbol *Lo, unsigned Size)
   const {
-  
+
   // Emit Hi+Offset - Lo
   // Get the Hi+Offset expression.
   const MCExpr *Plus =
-    MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Hi, OutContext), 
+    MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Hi, OutContext),
                             MCConstantExpr::Create(Offset, OutContext),
                             OutContext);
-  
+
   // Get the Hi+Offset-Lo expression.
-  const MCExpr *Diff = 
+  const MCExpr *Diff =
     MCBinaryExpr::CreateSub(Plus,
                             MCSymbolRefExpr::Create(Lo, OutContext),
                             OutContext);
-  
-  if (!MAI->hasSetDirective()) 
+
+  if (!MAI->hasSetDirective())
     OutStreamer.EmitValue(Diff, 4, 0/*AddrSpace*/);
   else {
     // Otherwise, emit with .set (aka assignment).
@@ -1252,22 +1253,22 @@ void AsmPrinter::EmitLabelOffsetDifference(const MCSymbol \
*Hi, uint64_t Offset,  }
 }
 
-/// EmitLabelPlusOffset - Emit something like ".long Label+Offset" 
+/// EmitLabelPlusOffset - Emit something like ".long Label+Offset"
 /// where the size in bytes of the directive is specified by Size and Label
 /// specifies the label.  This implicitly uses .set if it is available.
 void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
-                                      unsigned Size) 
+                                      unsigned Size)
   const {
-  
+
   // Emit Label+Offset
   const MCExpr *Plus =
-    MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Label, OutContext), 
+    MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Label, OutContext),
                             MCConstantExpr::Create(Offset, OutContext),
                             OutContext);
-  
+
   OutStreamer.EmitValue(Plus, 4, 0/*AddrSpace*/);
 }
-    
+
 
 //===----------------------------------------------------------------------===//
 
@@ -1279,9 +1280,9 @@ void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, \
uint64_t Offset,  //
 void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV) const {
   if (GV) NumBits = getGVAlignmentLog2(GV, *TM.getTargetData(), NumBits);
-  
+
   if (NumBits == 0) return;   // 1-byte aligned: no need to emit alignment.
-  
+
   if (getCurrentSection()->getKind().isText())
     OutStreamer.EmitCodeAlignment(1 << NumBits);
   else
@@ -1296,25 +1297,25 @@ void AsmPrinter::EmitAlignment(unsigned NumBits, const \
GlobalValue *GV) const {  ///
 static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) {
   MCContext &Ctx = AP.OutContext;
-  
+
   if (CV->isNullValue() || isa<UndefValue>(CV))
     return MCConstantExpr::Create(0, Ctx);
 
   if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV))
     return MCConstantExpr::Create(CI->getZExtValue(), Ctx);
-  
+
   if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV))
     return MCSymbolRefExpr::Create(AP.Mang->getSymbol(GV), Ctx);
 
   if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV))
     return MCSymbolRefExpr::Create(AP.GetBlockAddressSymbol(BA), Ctx);
-  
+
   const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV);
   if (CE == 0) {
     llvm_unreachable("Unknown constant value to lower!");
     return MCConstantExpr::Create(0, Ctx);
   }
-  
+
   switch (CE->getOpcode()) {
   default:
     // If the code isn't optimized, there may be outstanding folding
@@ -1342,21 +1343,21 @@ static const MCExpr *LowerConstant(const Constant *CV, \
AsmPrinter &AP) {  SmallVector<Value*, 8> IdxVec(CE->op_begin()+1, CE->op_end());
     int64_t Offset = TD.getIndexedOffset(PtrVal->getType(), &IdxVec[0],
                                          IdxVec.size());
-    
+
     const MCExpr *Base = LowerConstant(CE->getOperand(0), AP);
     if (Offset == 0)
       return Base;
-    
+
     // Truncate/sext the offset to the pointer size.
     if (TD.getPointerSizeInBits() != 64) {
       int SExtAmount = 64-TD.getPointerSizeInBits();
       Offset = (Offset << SExtAmount) >> SExtAmount;
     }
-    
+
     return MCBinaryExpr::CreateAdd(Base, MCConstantExpr::Create(Offset, Ctx),
                                    Ctx);
   }
-      
+
   case Instruction::Trunc:
     // We emit the value and depend on the assembler to truncate the generated
     // expression properly.  This is important for differences between
@@ -1375,7 +1376,7 @@ static const MCExpr *LowerConstant(const Constant *CV, \
AsmPrinter &AP) {  false/*ZExt*/);
     return LowerConstant(Op, AP);
   }
-    
+
   case Instruction::PtrToInt: {
     const TargetData &TD = *AP.TM.getTargetData();
     // Support only foldable casts to/from pointers that can be eliminated by
@@ -1397,7 +1398,7 @@ static const MCExpr *LowerConstant(const Constant *CV, \
                AsmPrinter &AP) {
     const MCExpr *MaskExpr = MCConstantExpr::Create(~0ULL >> (64-InBits), Ctx);
     return MCBinaryExpr::CreateAnd(OpExpr, MaskExpr, Ctx);
   }
-      
+
   // The MC library also has a right-shift operator, but it isn't consistently
   // signed or unsigned between different targets.
   case Instruction::Add:
@@ -1438,7 +1439,7 @@ static void EmitGlobalConstantArray(const ConstantArray *CA, \
unsigned AddrSpace,  EmitGlobalConstantImpl(CA->getOperand(i), AddrSpace, AP);
     return;
   }
-  
+
   // Otherwise, it can be emitted as .ascii.
   SmallVector<char, 128> TmpVec;
   TmpVec.reserve(CA->getNumOperands());
@@ -1496,7 +1497,7 @@ static void EmitGlobalConstantFP(const ConstantFP *CFP, \
unsigned AddrSpace,  AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace);
     return;
   }
-  
+
   if (CFP->getType()->isFloatTy()) {
     if (AP.isVerbose()) {
       float Val = CFP->getValueAPF().convertToFloat();
@@ -1506,7 +1507,7 @@ static void EmitGlobalConstantFP(const ConstantFP *CFP, \
unsigned AddrSpace,  AP.OutStreamer.EmitIntValue(Val, 4, AddrSpace);
     return;
   }
-  
+
   if (CFP->getType()->isX86_FP80Ty()) {
     // all long double variants are printed as hex
     // API needed to prevent premature destruction
@@ -1521,7 +1522,7 @@ static void EmitGlobalConstantFP(const ConstantFP *CFP, \
unsigned AddrSpace,  AP.OutStreamer.GetCommentOS() << "x86_fp80 ~= "
         << DoubleVal.convertToDouble() << '\n';
     }
-    
+
     if (AP.TM.getTargetData()->isBigEndian()) {
       AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace);
       AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace);
@@ -1529,14 +1530,14 @@ static void EmitGlobalConstantFP(const ConstantFP *CFP, \
unsigned AddrSpace,  AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace);
       AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace);
     }
-    
+
     // Emit the tail padding for the long double.
     const TargetData &TD = *AP.TM.getTargetData();
     AP.OutStreamer.EmitZeros(TD.getTypeAllocSize(CFP->getType()) -
                              TD.getTypeStoreSize(CFP->getType()), AddrSpace);
     return;
   }
-  
+
   assert(CFP->getType()->isPPC_FP128Ty() &&
          "Floating point constant type not handled");
   // All long double variants are printed as hex
@@ -1591,10 +1592,10 @@ static void EmitGlobalConstantImpl(const Constant *CV, \
unsigned AddrSpace,  return;
     }
   }
-  
+
   if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV))
     return EmitGlobalConstantArray(CVA, AddrSpace, AP);
-  
+
   if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))
     return EmitGlobalConstantStruct(CVS, AddrSpace, AP);
 
@@ -1606,10 +1607,10 @@ static void EmitGlobalConstantImpl(const Constant *CV, \
unsigned AddrSpace,  AP.OutStreamer.EmitIntValue(0, Size, AddrSpace);
     return;
   }
-  
+
   if (const ConstantVector *V = dyn_cast<ConstantVector>(CV))
     return EmitGlobalConstantVector(V, AddrSpace, AP);
-  
+
   // Otherwise, it must be a ConstantExpr.  Lower it to an MCExpr, then emit it
   // thread the streamer with EmitValue.
   AP.OutStreamer.EmitValue(LowerConstant(CV, AP),
@@ -1706,7 +1707,7 @@ MCSymbol *AsmPrinter::GetExternalSymbolSymbol(StringRef Sym) \
const {  SmallString<60> NameStr;
   Mang->getNameWithPrefix(NameStr, Sym);
   return OutContext.GetOrCreateSymbol(NameStr.str());
-}  
+}
 
 
 
@@ -1743,10 +1744,10 @@ static void EmitBasicBlockLoopComments(const \
MachineBasicBlock &MBB,  // Add loop depth information
   const MachineLoop *Loop = LI->getLoopFor(&MBB);
   if (Loop == 0) return;
-  
+
   MachineBasicBlock *Header = Loop->getHeader();
   assert(Header && "No header for loop");
-  
+
   // If this block is not a loop header, just print out what is the loop header
   // and return.
   if (Header != &MBB) {
@@ -1756,21 +1757,21 @@ static void EmitBasicBlockLoopComments(const \
MachineBasicBlock &MBB,  " Depth="+Twine(Loop->getLoopDepth()));
     return;
   }
-  
+
   // Otherwise, it is a loop header.  Print out information about child and
   // parent loops.
   raw_ostream &OS = AP.OutStreamer.GetCommentOS();
-  
-  PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber()); 
-  
+
+  PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber());
+
   OS << "=>";
   OS.indent(Loop->getLoopDepth()*2-2);
-  
+
   OS << "This ";
   if (Loop->empty())
     OS << "Inner ";
   OS << "Loop Header: Depth=" + Twine(Loop->getLoopDepth()) << '\n';
-  
+
   PrintChildLoopComment(OS, Loop, AP.getFunctionNumber());
 }
 
@@ -1791,7 +1792,7 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock \
*MBB) const {  const BasicBlock *BB = MBB->getBasicBlock();
     if (isVerbose())
       OutStreamer.AddComment("Block address taken");
-    
+
     std::vector<MCSymbol*> Syms = MMI->getAddrLabelSymbolToEmit(BB);
 
     for (unsigned i = 0, e = Syms.size(); i != e; ++i)
@@ -1804,9 +1805,9 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock \
*MBB) const {  if (const BasicBlock *BB = MBB->getBasicBlock())
         if (BB->hasName())
           OutStreamer.AddComment("%" + BB->getName());
-      
+
       EmitBasicBlockLoopComments(*MBB, LI, *this);
-      
+
       // NOTE: Want this comment at start of line, don't emit with AddComment.
       OutStreamer.EmitRawText(Twine(MAI->getCommentString()) + " BB#" +
                               Twine(MBB->getNumber()) + ":");
@@ -1826,7 +1827,7 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock \
*MBB) const {  void AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility,
                                 bool IsDefinition) const {
   MCSymbolAttr Attr = MCSA_Invalid;
-  
+
   switch (Visibility) {
   default: break;
   case GlobalValue::HiddenVisibility:
@@ -1853,23 +1854,23 @@ isBlockOnlyReachableByFallthrough(const MachineBasicBlock \
*MBB) const {  // then nothing falls through to it.
   if (MBB->isLandingPad() || MBB->pred_empty())
     return false;
-  
+
   // If there isn't exactly one predecessor, it can't be a fall through.
   MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI;
   ++PI2;
   if (PI2 != MBB->pred_end())
     return false;
-  
+
   // The predecessor has to be immediately before this block.
   const MachineBasicBlock *Pred = *PI;
-  
+
   if (!Pred->isLayoutSuccessor(MBB))
     return false;
-  
+
   // If the block is completely empty, then it definitely does fall through.
   if (Pred->empty())
     return true;
-  
+
   // Otherwise, check the last instruction.
   const MachineInstr &LastInst = Pred->back();
   return !LastInst.getDesc().isBarrier();
@@ -1885,9 +1886,9 @@ GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy \
*S) {  gcp_map_type::iterator GCPI = GCMap.find(S);
   if (GCPI != GCMap.end())
     return GCPI->second;
-  
+
   const char *Name = S->getName().c_str();
-  
+
   for (GCMetadataPrinterRegistry::iterator
          I = GCMetadataPrinterRegistry::begin(),
          E = GCMetadataPrinterRegistry::end(); I != E; ++I)
@@ -1897,7 +1898,7 @@ GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy \
*S) {  GCMap.insert(std::make_pair(S, GMP));
       return GMP;
     }
-  
+
   report_fatal_error("no GCMetadataPrinter registered for GC: " + Twine(Name));
   return 0;
 }


   Commit: 54ab30b1239743c888f845da29ee1b5b1b9eb12a
   Author: Bill Wendling <isanbard@gmail.com>
     Date: 03/29/2011 19:28:02
      URL: https://github.com/mono/llvm/commit/54ab30b1239743c888f845da29ee1b5b1b9eb12a


Revert r128501. It caused test failures.


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

Changed paths:
 M lib/Linker/LinkModules.cpp

Modified: lib/Linker/LinkModules.cpp
===================================================================
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -352,7 +352,6 @@ static void CopyGVAttributes(GlobalValue *DestGV, const \
GlobalValue *SrcGV) {  unsigned Alignment = std::max(DestGV->getAlignment(), \
SrcGV->getAlignment());  DestGV->copyAttributesFrom(SrcGV);
   DestGV->setAlignment(Alignment);
-  DestGV->setUnnamedAddr(SrcGV->hasUnnamedAddr());
 }
 
 /// GetLinkageResult - This analyzes the two global values and determines what


   Commit: 2d6728b997f560c9b3ee03d420af79facfa136a3
   Author: Bill Wendling <isanbard@gmail.com>
     Date: 03/29/2011 19:31:06
      URL: https://github.com/mono/llvm/commit/2d6728b997f560c9b3ee03d420af79facfa136a3


Set the unnamed_addr only when we're creating a new GV in the dest module.

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

Changed paths:
 M lib/Linker/LinkModules.cpp

Modified: lib/Linker/LinkModules.cpp
===================================================================
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -505,6 +505,7 @@ static bool LinkGlobals(Module *Dest, const Module *Src,
                            SGV->getType()->getAddressSpace());
       // Propagate alignment, visibility and section info.
       CopyGVAttributes(NewDGV, SGV);
+      NewDGV->setUnnamedAddr(SGV->hasUnnamedAddr());
 
       // If the LLVM runtime renamed the global, but it is an externally visible
       // symbol, DGV must be an existing global with internal linkage.  Rename


   Commit: a79a989123b33ab051b4ac8f4d8ff688e3f34679
   Author: Argyrios Kyrtzidis <akyrtzi@gmail.com>
     Date: 03/29/2011 20:22:00
      URL: https://github.com/mono/llvm/commit/a79a989123b33ab051b4ac8f4d8ff688e3f34679


ClangSAEmClangSACheckersEmitter, emit info about groups.


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

Changed paths:
 M utils/TableGen/ClangSACheckersEmitter.cpp

Modified: utils/TableGen/ClangSACheckersEmitter.cpp
===================================================================
--- a/utils/TableGen/ClangSACheckersEmitter.cpp
+++ b/utils/TableGen/ClangSACheckersEmitter.cpp
@@ -98,28 +98,6 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) {
   llvm::DenseMap<const Record *, unsigned> checkerRecIndexMap;
   for (unsigned i = 0, e = checkers.size(); i != e; ++i)
     checkerRecIndexMap[checkers[i]] = i;
-  
-  OS << "\n#ifdef GET_CHECKERS\n";
-  for (unsigned i = 0, e = checkers.size(); i != e; ++i) {
-    const Record &R = *checkers[i];
-
-    OS << "CHECKER(" << "\"";
-    std::string name;
-    if (isCheckerNamed(&R))
-      name = getCheckerFullName(&R);
-    OS.write_escaped(name) << "\", ";
-    OS << R.getName() << ", ";
-    OS << getStringValue(R, "DescFile") << ", ";
-    OS << "\"";
-    OS.write_escaped(getStringValue(R, "HelpText")) << "\", ";
-    // Hidden bit
-    if (isHidden(R))
-      OS << "true";
-    else
-      OS << "false";
-    OS << ")\n";
-  }
-  OS << "#endif // GET_CHECKERS\n\n";
 
   // Invert the mapping of checkers to package/group into a one to many
   // mapping of packages/groups to checkers.
@@ -148,48 +126,6 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) {
     }
   }
 
-  typedef std::map<std::string, const Record *> SortedRecords;
-
-  OS << "\n#ifdef GET_PACKAGES\n";
-  {
-    SortedRecords sortedPackages;
-    for (unsigned i = 0, e = packages.size(); i != e; ++i)
-      sortedPackages[getPackageFullName(packages[i])] = packages[i];
-  
-    for (SortedRecords::iterator
-           I = sortedPackages.begin(), E = sortedPackages.end(); I != E; ++I) {
-      const Record &R = *I->second;
-  
-      OS << "PACKAGE(" << "\"";
-      OS.write_escaped(getPackageFullName(&R)) << "\", ";
-      // Hidden bit
-      if (isHidden(R))
-        OS << "true";
-      else
-        OS << "false";
-      OS << ")\n";
-    }
-  }
-  OS << "#endif // GET_PACKAGES\n\n";
-
-  OS << "\n#ifdef GET_GROUPS\n";
-  {
-    SortedRecords sortedGroups;
-    for (unsigned i = 0, e = checkerGroups.size(); i != e; ++i)
-      sortedGroups[checkerGroups[i]->getValueAsString("GroupName")]
-                   = checkerGroups[i];
-
-    for (SortedRecords::iterator
-           I = sortedGroups.begin(), E = sortedGroups.end(); I != E; ++I) {
-      const Record &R = *I->second;
-  
-      OS << "GROUP(" << "\"";
-      OS.write_escaped(R.getValueAsString("GroupName")) << "\"";
-      OS << ")\n";
-    }
-  }
-  OS << "#endif // GET_GROUPS\n\n";
-
   for (unsigned i = 0, e = checkers.size(); i != e; ++i) {
     Record *R = checkers[i];
     Record *package = 0;
@@ -230,6 +166,85 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) {
     if (DefInit *DI = dynamic_cast<DefInit*>(packages[i]->getValueInit("Group")))
       addPackageToCheckerGroup(packages[i], DI->getDef(), recordGroupMap);
 
+  typedef std::map<std::string, const Record *> SortedRecords;
+  typedef llvm::DenseMap<const Record *, unsigned> RecToSortIndex;
+
+  SortedRecords sortedGroups;
+  RecToSortIndex groupToSortIndex;
+  OS << "\n#ifdef GET_GROUPS\n";
+  {
+    for (unsigned i = 0, e = checkerGroups.size(); i != e; ++i)
+      sortedGroups[checkerGroups[i]->getValueAsString("GroupName")]
+                   = checkerGroups[i];
+
+    unsigned sortIndex = 0;
+    for (SortedRecords::iterator
+           I = sortedGroups.begin(), E = sortedGroups.end(); I != E; ++I) {
+      const Record *R = I->second;
+  
+      OS << "GROUP(" << "\"";
+      OS.write_escaped(R->getValueAsString("GroupName")) << "\"";
+      OS << ")\n";
+
+      groupToSortIndex[R] = sortIndex++;
+    }
+  }
+  OS << "#endif // GET_GROUPS\n\n";
+
+  OS << "\n#ifdef GET_PACKAGES\n";
+  {
+    SortedRecords sortedPackages;
+    for (unsigned i = 0, e = packages.size(); i != e; ++i)
+      sortedPackages[getPackageFullName(packages[i])] = packages[i];
+  
+    for (SortedRecords::iterator
+           I = sortedPackages.begin(), E = sortedPackages.end(); I != E; ++I) {
+      const Record &R = *I->second;
+  
+      OS << "PACKAGE(" << "\"";
+      OS.write_escaped(getPackageFullName(&R)) << "\", ";
+      // Group index
+      if (DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Group")))
+        OS << groupToSortIndex[DI->getDef()] << ", ";
+      else
+        OS << "-1, ";
+      // Hidden bit
+      if (isHidden(R))
+        OS << "true";
+      else
+        OS << "false";
+      OS << ")\n";
+    }
+  }
+  OS << "#endif // GET_PACKAGES\n\n";
+  
+  OS << "\n#ifdef GET_CHECKERS\n";
+  for (unsigned i = 0, e = checkers.size(); i != e; ++i) {
+    const Record &R = *checkers[i];
+
+    OS << "CHECKER(" << "\"";
+    std::string name;
+    if (isCheckerNamed(&R))
+      name = getCheckerFullName(&R);
+    OS.write_escaped(name) << "\", ";
+    OS << R.getName() << ", ";
+    OS << getStringValue(R, "DescFile") << ", ";
+    OS << "\"";
+    OS.write_escaped(getStringValue(R, "HelpText")) << "\", ";
+    // Group index
+    if (DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Group")))
+      OS << groupToSortIndex[DI->getDef()] << ", ";
+    else
+      OS << "-1, ";
+    // Hidden bit
+    if (isHidden(R))
+      OS << "true";
+    else
+      OS << "false";
+    OS << ")\n";
+  }
+  OS << "#endif // GET_CHECKERS\n\n";
+
   unsigned index = 0;
   for (std::map<std::string, GroupInfo>::iterator
          I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I)


   Commit: 5abee58ac739eda6ae9835e0204c72f40b5d5649
   Author: Johnny Chen <johnny.chen@apple.com>
     Date: 03/29/2011 21:02:06
      URL: https://github.com/mono/llvm/commit/5abee58ac739eda6ae9835e0204c72f40b5d5649


Add a test case for thumb stc2 instruction.


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

Changed paths:
 M test/MC/Disassembler/ARM/thumb-tests.txt

Modified: test/MC/Disassembler/ARM/thumb-tests.txt
===================================================================
--- a/test/MC/Disassembler/ARM/thumb-tests.txt
+++ b/test/MC/Disassembler/ARM/thumb-tests.txt
@@ -196,3 +196,6 @@
 
 # CHECK:	pld	[pc, #-16]
 0x1f 0xf8 0x10 0xf0
+
+# CHECK:	stc2	p12, cr15, [r9], {137}
+0x89 0xfc 0x89 0xfc


   Commit: 04ebd8a7696631cb5dda67158585b13511ae69f5
   Author: Bill Wendling <isanbard@gmail.com>
     Date: 03/29/2011 21:03:48
      URL: https://github.com/mono/llvm/commit/04ebd8a7696631cb5dda67158585b13511ae69f5


Remove dead code.

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

Changed paths:
 M lib/VMCore/AutoUpgrade.cpp

Modified: lib/VMCore/AutoUpgrade.cpp
===================================================================
--- a/lib/VMCore/AutoUpgrade.cpp
+++ b/lib/VMCore/AutoUpgrade.cpp
@@ -1179,74 +1179,6 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) \
{  break;
   }
 
-#if 0
-  case Intrinsic::x86_mmx_cvtsi32_si64: {
-    // The return type needs to be changed.
-    Value *Operands[1];
-    Operands[0] = CI->getArgOperand(0);
-    ConstructNewCallInst(NewFn, CI, Operands, 1);
-    break;
-  }
-  case Intrinsic::x86_mmx_cvtsi64_si32: {
-    Value *Operands[1];
-
-    // Cast the operand to the X86 MMX type.
-    Operands[0] = new BitCastInst(CI->getArgOperand(0),
-                                  NewFn->getFunctionType()->getParamType(0),
-                                  "upgraded.", CI);
-
-    ConstructNewCallInst(NewFn, CI, Operands, 1);
-    break;
-  }
-  case Intrinsic::x86_mmx_vec_init_b:
-  case Intrinsic::x86_mmx_vec_init_w:
-  case Intrinsic::x86_mmx_vec_init_d: {
-    // The return type needs to be changed.
-    Value *Operands[8];
-    unsigned NumOps = 0;
-
-    switch (NewFn->getIntrinsicID()) {
-    default: break;
-    case Intrinsic::x86_mmx_vec_init_b: NumOps = 8; break;
-    case Intrinsic::x86_mmx_vec_init_w: NumOps = 4; break;
-    case Intrinsic::x86_mmx_vec_init_d: NumOps = 2; break;
-    }
-
-    switch (NewFn->getIntrinsicID()) {
-    default: break;
-    case Intrinsic::x86_mmx_vec_init_b:
-      Operands[7] = CI->getArgOperand(7);
-      Operands[6] = CI->getArgOperand(6);
-      Operands[5] = CI->getArgOperand(5);
-      Operands[4] = CI->getArgOperand(4);
-      // FALLTHRU
-    case Intrinsic::x86_mmx_vec_init_w:
-      Operands[3] = CI->getArgOperand(3);
-      Operands[2] = CI->getArgOperand(2);
-      // FALLTHRU
-    case Intrinsic::x86_mmx_vec_init_d:
-      Operands[1] = CI->getArgOperand(1);
-      Operands[0] = CI->getArgOperand(0);
-      break;
-    }
-
-    ConstructNewCallInst(NewFn, CI, Operands, NumOps);
-    break;
-  }
-  case Intrinsic::x86_mmx_vec_ext_d: {
-    Value *Operands[2];
-
-    // Cast the operand to the X86 MMX type.
-    Operands[0] = new BitCastInst(CI->getArgOperand(0),
-                                  NewFn->getFunctionType()->getParamType(0),
-                                  "upgraded.", CI);
-    Operands[1] = CI->getArgOperand(1);
-
-    ConstructNewCallInst(NewFn, CI, Operands, 2);
-    break;
-  }
-#endif
-
   case Intrinsic::ctlz:
   case Intrinsic::ctpop:
   case Intrinsic::cttz: {


   Commit: 53fa96b282b5a4c932aabf56f03c2723805f944e
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/29/2011 22:52:39
      URL: https://github.com/mono/llvm/commit/53fa96b282b5a4c932aabf56f03c2723805f944e


Treat clones the same as their origin.

When DCE clones a live range because it separates into connected components,
make sure that the clones enter the same register allocator stage as the
register they were cloned from.

For instance, clones may be split even when they where created during spilling.
Other registers created during spilling are not candidates for splitting or even
(re-)spilling.

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

Changed paths:
 M lib/CodeGen/LiveRangeEdit.cpp
 M lib/CodeGen/LiveRangeEdit.h
 M lib/CodeGen/RegAllocGreedy.cpp

Modified: lib/CodeGen/LiveRangeEdit.cpp
===================================================================
--- a/lib/CodeGen/LiveRangeEdit.cpp
+++ b/lib/CodeGen/LiveRangeEdit.cpp
@@ -231,8 +231,11 @@ void \
LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,  continue;
     DEBUG(dbgs() << NumComp << " components: " << *LI << '\n');
     SmallVector<LiveInterval*, 8> Dups(1, LI);
-    for (unsigned i = 1; i != NumComp; ++i)
+    for (unsigned i = 1; i != NumComp; ++i) {
       Dups.push_back(&createFrom(LI->reg, LIS, VRM));
+      if (delegate_)
+        delegate_->LRE_DidCloneVirtReg(Dups.back()->reg, LI->reg);
+    }
     ConEQ.Distribute(&Dups[0], VRM.getRegInfo());
   }
 }
Modified: lib/CodeGen/LiveRangeEdit.h
===================================================================
--- a/lib/CodeGen/LiveRangeEdit.h
+++ b/lib/CodeGen/LiveRangeEdit.h
@@ -43,6 +43,10 @@ public:
     /// Called before shrinking the live range of a virtual register.
     virtual void LRE_WillShrinkVirtReg(unsigned) {}
 
+    /// Called after cloning a virtual register.
+    /// This is used for new registers representing connected components of Old.
+    virtual void LRE_DidCloneVirtReg(unsigned New, unsigned Old) {}
+
     virtual ~Delegate() {}
   };
 
Modified: lib/CodeGen/RegAllocGreedy.cpp
===================================================================
--- a/lib/CodeGen/RegAllocGreedy.cpp
+++ b/lib/CodeGen/RegAllocGreedy.cpp
@@ -90,7 +90,8 @@ class RAGreedy : public MachineFunctionPass,
   // range splitting algorithm terminates, something that is otherwise hard to
   // ensure.
   enum LiveRangeStage {
-    RS_Original, ///< Never seen before, never split.
+    RS_New,      ///< Never seen before.
+    RS_First,    ///< First time in the queue.
     RS_Second,   ///< Second time in the queue.
     RS_Region,   ///< Produced by region splitting.
     RS_Block,    ///< Produced by per-block splitting.
@@ -107,8 +108,11 @@ class RAGreedy : public MachineFunctionPass,
   template<typename Iterator>
   void setStage(Iterator Begin, Iterator End, LiveRangeStage NewStage) {
     LRStage.resize(MRI->getNumVirtRegs());
-    for (;Begin != End; ++Begin)
-      LRStage[(*Begin)->reg] = NewStage;
+    for (;Begin != End; ++Begin) {
+      unsigned Reg = (*Begin)->reg;
+      if (LRStage[Reg] == RS_New)
+        LRStage[Reg] = NewStage;
+    }
   }
 
   // splitting state.
@@ -162,6 +166,7 @@ private:
   void LRE_WillEraseInstruction(MachineInstr*);
   bool LRE_CanEraseVirtReg(unsigned);
   void LRE_WillShrinkVirtReg(unsigned);
+  void LRE_DidCloneVirtReg(unsigned, unsigned);
 
   void mapGlobalInterference(unsigned, SmallVectorImpl<IndexPair>&);
   float calcSplitConstraints(const SmallVectorImpl<IndexPair>&);
@@ -192,7 +197,7 @@ FunctionPass* llvm::createGreedyRegisterAllocator() {
   return new RAGreedy();
 }
 
-RAGreedy::RAGreedy(): MachineFunctionPass(ID), LRStage(RS_Original) {
+RAGreedy::RAGreedy(): MachineFunctionPass(ID), LRStage(RS_New) {
   initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
   initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
   initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
@@ -265,6 +270,14 @@ void RAGreedy::LRE_WillShrinkVirtReg(unsigned VirtReg) {
   enqueue(&LI);
 }
 
+void RAGreedy::LRE_DidCloneVirtReg(unsigned New, unsigned Old) {
+  // LRE may clone a virtual register because dead code elimination causes it to
+  // be split into connected components. Ensure that the new register gets the
+  // same stage as the parent.
+  LRStage.grow(New);
+  LRStage[New] = LRStage[Old];
+}
+
 void RAGreedy::releaseMemory() {
   SpillerInstance.reset(0);
   LRStage.clear();
@@ -281,6 +294,9 @@ void RAGreedy::enqueue(LiveInterval *LI) {
   unsigned Prio;
 
   LRStage.grow(Reg);
+  if (LRStage[Reg] == RS_New)
+    LRStage[Reg] = RS_First;
+
   if (LRStage[Reg] == RS_Second)
     // Unsplit ranges that couldn't be allocated immediately are deferred until
     // everything else has been allocated. Long ranges are allocated last so
@@ -1146,7 +1162,7 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg,
   // Wait until the second time, when all smaller ranges have been allocated.
   // This gives a better picture of the interference to split around.
   LiveRangeStage Stage = getStage(VirtReg);
-  if (Stage == RS_Original) {
+  if (Stage == RS_First) {
     LRStage[VirtReg.reg] = RS_Second;
     DEBUG(dbgs() << "wait for second round\n");
     NewVRegs.push_back(&VirtReg);


   Commit: 738ab9043c27e70c085520b70b2a581fb00347b5
   Author: Bob Wilson <bob.wilson@apple.com>
     Date: 03/30/2011 01:26:51
      URL: https://github.com/mono/llvm/commit/738ab9043c27e70c085520b70b2a581fb00347b5


Revert a minor comment change inadvertently included with r128502.

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

Changed paths:
 M include/llvm/IntrinsicsARM.td

Modified: include/llvm/IntrinsicsARM.td
===================================================================
--- a/include/llvm/IntrinsicsARM.td
+++ b/include/llvm/IntrinsicsARM.td
@@ -296,7 +296,7 @@ def int_arm_neon_vcvtfp2hf
 def int_arm_neon_vcvthf2fp
     : Intrinsic<[llvm_v4f32_ty], [llvm_v4i16_ty], [IntrNoMem]>;
 
-// Narrowing and Lengthening Vector Moves.
+// Narrowing Saturating Vector Moves.
 def int_arm_neon_vqmovns : Neon_1Arg_Narrow_Intrinsic;
 def int_arm_neon_vqmovnu : Neon_1Arg_Narrow_Intrinsic;
 def int_arm_neon_vqmovnsu : Neon_1Arg_Narrow_Intrinsic;


   Commit: 3baaf42e0e900c43ed0604f677138e669c5d7202
   Author: Jay Foad <jay.foad@gmail.com>
     Date: 03/30/2011 07:19:20
      URL: https://github.com/mono/llvm/commit/3baaf42e0e900c43ed0604f677138e669c5d7202


(Almost) always call reserveOperandSpace() on newly created PHINodes.

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

Changed paths:
 M examples/Kaleidoscope/Chapter5/toy.cpp
 M examples/Kaleidoscope/Chapter6/toy.cpp
 M examples/Kaleidoscope/Chapter7/toy.cpp
 M lib/Analysis/ScalarEvolutionExpander.cpp
 M lib/CodeGen/DwarfEHPrepare.cpp
 M lib/Transforms/IPO/GlobalOpt.cpp
 M lib/Transforms/IPO/LowerSetJmp.cpp
 M lib/Transforms/IPO/PartialInlining.cpp
 M lib/Transforms/InstCombine/InstCombineCasts.cpp
 M lib/Transforms/InstCombine/InstCombinePHI.cpp
 M lib/Transforms/Instrumentation/PathProfiling.cpp
 M lib/Transforms/Scalar/GVN.cpp
 M lib/Transforms/Scalar/IndVarSimplify.cpp
 M lib/Transforms/Scalar/JumpThreading.cpp
 M lib/Transforms/Scalar/LoopStrengthReduce.cpp
 M lib/Transforms/Scalar/ScalarReplAggregates.cpp
 M lib/Transforms/Scalar/SimplifyCFGPass.cpp
 M lib/Transforms/Scalar/TailRecursionElimination.cpp
 M lib/Transforms/Utils/BasicBlockUtils.cpp
 M lib/Transforms/Utils/BreakCriticalEdges.cpp
 M lib/Transforms/Utils/CodeExtractor.cpp
 M lib/Transforms/Utils/InlineFunction.cpp
 M lib/Transforms/Utils/SimplifyCFG.cpp
 M lib/Transforms/Utils/UnifyFunctionExitNodes.cpp
 M tools/bugpoint/Miscompilation.cpp
 M unittests/Transforms/Utils/Local.cpp

Modified: examples/Kaleidoscope/Chapter5/toy.cpp
===================================================================
--- a/examples/Kaleidoscope/Chapter5/toy.cpp
+++ b/examples/Kaleidoscope/Chapter5/toy.cpp
@@ -552,6 +552,7 @@ Value *IfExprAST::Codegen() {
   Builder.SetInsertPoint(MergeBB);
   PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
                                   "iftmp");
+  PN->reserveOperandSpace(2);
   
   PN->addIncoming(ThenV, ThenBB);
   PN->addIncoming(ElseV, ElseBB);
@@ -593,6 +594,7 @@ Value *ForExprAST::Codegen() {
   
   // Start the PHI node with an entry for Start.
   PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), \
VarName.c_str()); +  Variable->reserveOperandSpace(2);
   Variable->addIncoming(StartVal, PreheaderBB);
   
   // Within the loop, the variable is defined equal to the PHI node.  If it
Modified: examples/Kaleidoscope/Chapter6/toy.cpp
===================================================================
--- a/examples/Kaleidoscope/Chapter6/toy.cpp
+++ b/examples/Kaleidoscope/Chapter6/toy.cpp
@@ -656,6 +656,7 @@ Value *IfExprAST::Codegen() {
   Builder.SetInsertPoint(MergeBB);
   PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
                                   "iftmp");
+  PN->reserveOperandSpace(2);
   
   PN->addIncoming(ThenV, ThenBB);
   PN->addIncoming(ElseV, ElseBB);
@@ -697,6 +698,7 @@ Value *ForExprAST::Codegen() {
   
   // Start the PHI node with an entry for Start.
   PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), \
VarName.c_str()); +  Variable->reserveOperandSpace(2);
   Variable->addIncoming(StartVal, PreheaderBB);
   
   // Within the loop, the variable is defined equal to the PHI node.  If it
Modified: examples/Kaleidoscope/Chapter7/toy.cpp
===================================================================
--- a/examples/Kaleidoscope/Chapter7/toy.cpp
+++ b/examples/Kaleidoscope/Chapter7/toy.cpp
@@ -752,6 +752,7 @@ Value *IfExprAST::Codegen() {
   Builder.SetInsertPoint(MergeBB);
   PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
                                   "iftmp");
+  PN->reserveOperandSpace(2);
   
   PN->addIncoming(ThenV, ThenBB);
   PN->addIncoming(ElseV, ElseBB);
Modified: lib/Analysis/ScalarEvolutionExpander.cpp
===================================================================
--- a/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -932,14 +932,15 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr \
*Normalized,  Value *StepV = expandCodeFor(Step, IntTy, L->getHeader()->begin());
 
   // Create the PHI.
-  Builder.SetInsertPoint(L->getHeader(), L->getHeader()->begin());
+  BasicBlock *Header = L->getHeader();
+  Builder.SetInsertPoint(Header, Header->begin());
+  pred_iterator HPB = pred_begin(Header), HPE = pred_end(Header);
   PHINode *PN = Builder.CreatePHI(ExpandTy, "lsr.iv");
+  PN->reserveOperandSpace(std::distance(HPB, HPE));
   rememberInstruction(PN);
 
   // Create the step instructions and populate the PHI.
-  BasicBlock *Header = L->getHeader();
-  for (pred_iterator HPI = pred_begin(Header), HPE = pred_end(Header);
-       HPI != HPE; ++HPI) {
+  for (pred_iterator HPI = HPB; HPI != HPE; ++HPI) {
     BasicBlock *Pred = *HPI;
 
     // Add a start value.
@@ -1141,12 +1142,13 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) \
{  // Create and insert the PHI node for the induction variable in the
     // specified loop.
     BasicBlock *Header = L->getHeader();
+    pred_iterator HPB = pred_begin(Header), HPE = pred_end(Header);
     CanonicalIV = PHINode::Create(Ty, "indvar", Header->begin());
+    CanonicalIV->reserveOperandSpace(std::distance(HPB, HPE));
     rememberInstruction(CanonicalIV);
 
     Constant *One = ConstantInt::get(Ty, 1);
-    for (pred_iterator HPI = pred_begin(Header), HPE = pred_end(Header);
-         HPI != HPE; ++HPI) {
+    for (pred_iterator HPI = HPB; HPI != HPE; ++HPI) {
       BasicBlock *HP = *HPI;
       if (L->contains(HP)) {
         // Insert a unit add instruction right before the terminator
Modified: lib/CodeGen/DwarfEHPrepare.cpp
===================================================================
--- a/lib/CodeGen/DwarfEHPrepare.cpp
+++ b/lib/CodeGen/DwarfEHPrepare.cpp
@@ -441,6 +441,7 @@ bool DwarfEHPrepare::NormalizeLandingPads() {
         // in NewBB.
         PHINode *NewPN = PHINode::Create(PN->getType(), PN->getName()+".unwind",
                                          NewBB);
+        NewPN->reserveOperandSpace(PN->getNumIncomingValues());
         // Add an entry for each unwind edge, using the value from the old PHI.
         for (pred_iterator PI = PB; PI != PE; ++PI)
           NewPN->addIncoming(PN->getIncomingValueForBlock(*PI), *PI);
Modified: lib/Transforms/IPO/GlobalOpt.cpp
===================================================================
--- a/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/lib/Transforms/IPO/GlobalOpt.cpp
@@ -1193,9 +1193,11 @@ static Value *GetHeapSROAValue(Value *V, unsigned FieldNo,
     const StructType *ST =
       cast<StructType>(cast<PointerType>(PN->getType())->getElementType());
 
-    Result =
+    PHINode *NewPN =
      PHINode::Create(PointerType::getUnqual(ST->getElementType(FieldNo)),
                      PN->getName()+".f"+Twine(FieldNo), PN);
+    NewPN->reserveOperandSpace(PN->getNumIncomingValues());
+    Result = NewPN;
     PHIsToRewrite.push_back(std::make_pair(PN, FieldNo));
   } else {
     llvm_unreachable("Unknown usable value");
Modified: lib/Transforms/IPO/LowerSetJmp.cpp
===================================================================
--- a/lib/Transforms/IPO/LowerSetJmp.cpp
+++ b/lib/Transforms/IPO/LowerSetJmp.cpp
@@ -432,6 +432,7 @@ void LowerSetJmp::TransformSetJmpCall(CallInst* Inst)
   // splitBasicBlock call.
   PHINode* PHI = PHINode::Create(Type::getInt32Ty(Inst->getContext()),
                                  "SetJmpReturn", Inst);
+  PHI->reserveOperandSpace(2);
 
   // Coming from a call to setjmp, the return is 0.
   PHI->addIncoming(Constant::getNullValue(Type::getInt32Ty(Inst->getContext())),
Modified: lib/Transforms/IPO/PartialInlining.cpp
===================================================================
--- a/lib/Transforms/IPO/PartialInlining.cpp
+++ b/lib/Transforms/IPO/PartialInlining.cpp
@@ -96,6 +96,7 @@ Function* PartialInliner::unswitchFunction(Function* F) {
     if (!OldPhi) break;
     
     PHINode* retPhi = PHINode::Create(OldPhi->getType(), "", Ins);
+    retPhi->reserveOperandSpace(2);
     OldPhi->replaceAllUsesWith(retPhi);
     Ins = newReturnBlock->getFirstNonPHI();
     
Modified: lib/Transforms/InstCombine/InstCombineCasts.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -197,6 +197,7 @@ Value *InstCombiner::EvaluateInDifferentType(Value *V, const Type \
*Ty,  case Instruction::PHI: {
     PHINode *OPN = cast<PHINode>(I);
     PHINode *NPN = PHINode::Create(Ty);
+    NPN->reserveOperandSpace(OPN->getNumIncomingValues());
     for (unsigned i = 0, e = OPN->getNumIncomingValues(); i != e; ++i) {
       Value *V =EvaluateInDifferentType(OPN->getIncomingValue(i), Ty, isSigned);
       NPN->addIncoming(V, OPN->getIncomingBlock(i));
Modified: lib/Transforms/InstCombine/InstCombinePHI.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ b/lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -700,6 +700,7 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode \
&FirstPhi) {  
       // Otherwise, Create the new PHI node for this user.
       EltPHI = PHINode::Create(Ty, PN->getName()+".off"+Twine(Offset), PN);
+      EltPHI->reserveOperandSpace(PN->getNumIncomingValues());
       assert(EltPHI->getType() != PN->getType() &&
              "Truncate didn't shrink phi?");
     
Modified: lib/Transforms/Instrumentation/PathProfiling.cpp
===================================================================
--- a/lib/Transforms/Instrumentation/PathProfiling.cpp
+++ b/lib/Transforms/Instrumentation/PathProfiling.cpp
@@ -929,14 +929,16 @@ BasicBlock::iterator \
PathProfiler::getInsertionPoint(BasicBlock* block, Value*  void \
PathProfiler::preparePHI(BLInstrumentationNode* node) {  BasicBlock* block = \
node->getBlock();  BasicBlock::iterator insertPoint = block->getFirstNonPHI();
+  pred_iterator PB = pred_begin(node->getBlock()),
+          PE = pred_end(node->getBlock());
   PHINode* phi = PHINode::Create(Type::getInt32Ty(*Context), "pathNumber",
                                  insertPoint );
+  phi->reserveOperandSpace(std::distance(PB, PE));
   node->setPathPHI(phi);
   node->setStartingPathNumber(phi);
   node->setEndingPathNumber(phi);
 
-  for(pred_iterator predIt = pred_begin(node->getBlock()),
-        end = pred_end(node->getBlock()); predIt != end; predIt++) {
+  for(pred_iterator predIt = PB; predIt != PE; predIt++) {
     BasicBlock* pred = (*predIt);
 
     if(pred != NULL)
Modified: lib/Transforms/Scalar/GVN.cpp
===================================================================
--- a/lib/Transforms/Scalar/GVN.cpp
+++ b/lib/Transforms/Scalar/GVN.cpp
@@ -1944,11 +1944,12 @@ bool GVN::performPRE(Function &F) {
       addToLeaderTable(ValNo, PREInstr, PREPred);
 
       // Create a PHI to make the value available in this block.
+      pred_iterator PB = pred_begin(CurrentBlock), PE = pred_end(CurrentBlock);
       PHINode* Phi = PHINode::Create(CurInst->getType(),
                                      CurInst->getName() + ".pre-phi",
                                      CurrentBlock->begin());
-      for (pred_iterator PI = pred_begin(CurrentBlock),
-           PE = pred_end(CurrentBlock); PI != PE; ++PI) {
+      Phi->reserveOperandSpace(std::distance(PB, PE));
+      for (pred_iterator PI = PB; PI != PE; ++PI) {
         BasicBlock *P = *PI;
         Phi->addIncoming(predMap[P], P);
       }
Modified: lib/Transforms/Scalar/IndVarSimplify.cpp
===================================================================
--- a/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -1039,6 +1039,7 @@ void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode \
*PN) {  
   // Insert new integer induction variable.
   PHINode *NewPHI = PHINode::Create(Int32Ty, PN->getName()+".int", PN);
+  NewPHI->reserveOperandSpace(2);
   NewPHI->addIncoming(ConstantInt::get(Int32Ty, InitValue),
                       PN->getIncomingBlock(IncomingEdge));
 
Modified: lib/Transforms/Scalar/JumpThreading.cpp
===================================================================
--- a/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/lib/Transforms/Scalar/JumpThreading.cpp
@@ -928,13 +928,14 @@ bool JumpThreading::SimplifyPartiallyRedundantLoad(LoadInst \
*LI) {  array_pod_sort(AvailablePreds.begin(), AvailablePreds.end());
 
   // Create a PHI node at the start of the block for the PRE'd load value.
+  pred_iterator PB = pred_begin(LoadBB), PE = pred_end(LoadBB);
   PHINode *PN = PHINode::Create(LI->getType(), "", LoadBB->begin());
+  PN->reserveOperandSpace(std::distance(PB, PE));
   PN->takeName(LI);
 
   // Insert new entries into the PHI for each predecessor.  A single block may
   // have multiple entries here.
-  for (pred_iterator PI = pred_begin(LoadBB), E = pred_end(LoadBB); PI != E;
-       ++PI) {
+  for (pred_iterator PI = PB; PI != PE; ++PI) {
     BasicBlock *P = *PI;
     AvailablePredsTy::iterator I =
       std::lower_bound(AvailablePreds.begin(), AvailablePreds.end(),
Modified: lib/Transforms/Scalar/LoopStrengthReduce.cpp
===================================================================
--- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -1492,6 +1492,7 @@ void LSRInstance::OptimizeShadowIV() {
 
     /* Add new PHINode. */
     PHINode *NewPH = PHINode::Create(DestTy, "IV.S.", PH);
+    NewPH->reserveOperandSpace(2);
 
     /* create new increment. '++d' in above example. */
     Constant *CFP = ConstantFP::get(DestTy, C->getZExtValue());
Modified: lib/Transforms/Scalar/ScalarReplAggregates.cpp
===================================================================
--- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp
+++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
@@ -1228,6 +1228,7 @@ static bool tryToMakeAllocaBePromotable(AllocaInst *AI, const \
TargetData *TD) {  
     const Type *LoadTy = cast<PointerType>(PN->getType())->getElementType();
     PHINode *NewPN = PHINode::Create(LoadTy, PN->getName()+".ld", PN);
+    NewPN->reserveOperandSpace(PN->getNumIncomingValues());
 
     // Get the TBAA tag and alignment to use from one of the loads.  It doesn't
     // matter which one we get and if any differ, it doesn't matter.
Modified: lib/Transforms/Scalar/SimplifyCFGPass.cpp
===================================================================
--- a/lib/Transforms/Scalar/SimplifyCFGPass.cpp
+++ b/lib/Transforms/Scalar/SimplifyCFGPass.cpp
@@ -259,11 +259,12 @@ static bool MergeEmptyReturnBlocks(Function &F) {
     PHINode *RetBlockPHI = dyn_cast<PHINode>(RetBlock->begin());
     if (RetBlockPHI == 0) {
       Value *InVal = cast<ReturnInst>(RetBlock->getTerminator())->getOperand(0);
+      pred_iterator PB = pred_begin(RetBlock), PE = pred_end(RetBlock);
       RetBlockPHI = PHINode::Create(Ret->getOperand(0)->getType(), "merge",
                                     &RetBlock->front());
+      RetBlockPHI->reserveOperandSpace(std::distance(PB, PE));
       
-      for (pred_iterator PI = pred_begin(RetBlock), E = pred_end(RetBlock);
-           PI != E; ++PI)
+      for (pred_iterator PI = PB; PI != PE; ++PI)
         RetBlockPHI->addIncoming(InVal, *PI);
       RetBlock->getTerminator()->setOperand(0, RetBlockPHI);
     }
Modified: lib/Transforms/Scalar/TailRecursionElimination.cpp
===================================================================
--- a/lib/Transforms/Scalar/TailRecursionElimination.cpp
+++ b/lib/Transforms/Scalar/TailRecursionElimination.cpp
@@ -498,6 +498,7 @@ bool TailCallElim::EliminateRecursiveTailCall(CallInst *CI, \
ReturnInst *Ret,  I != E; ++I) {
       PHINode *PN = PHINode::Create(I->getType(),
                                     I->getName() + ".tr", InsertPos);
+      PN->reserveOperandSpace(2);
       I->replaceAllUsesWith(PN); // Everyone use the PHI node now!
       PN->addIncoming(I, NewEntry);
       ArgumentPHIs.push_back(PN);
@@ -527,9 +528,11 @@ bool TailCallElim::EliminateRecursiveTailCall(CallInst *CI, \
ReturnInst *Ret,  if (AccumulatorRecursionEliminationInitVal) {
     Instruction *AccRecInstr = AccumulatorRecursionInstr;
     // Start by inserting a new PHI node for the accumulator.
+    pred_iterator PB = pred_begin(OldEntry), PE = pred_end(OldEntry);
     PHINode *AccPN =
       PHINode::Create(AccumulatorRecursionEliminationInitVal->getType(),
                       "accumulator.tr", OldEntry->begin());
+    AccPN->reserveOperandSpace(std::distance(PB, PE) + 1);
 
     // Loop over all of the predecessors of the tail recursion block.  For the
     // real entry into the function we seed the PHI with the initial value,
@@ -537,8 +540,7 @@ bool TailCallElim::EliminateRecursiveTailCall(CallInst *CI, \
ReturnInst *Ret,  // other tail recursions eliminated) the accumulator is not \
                modified.
     // Because we haven't added the branch in the current block to OldEntry yet,
     // it will not show up as a predecessor.
-    for (pred_iterator PI = pred_begin(OldEntry), PE = pred_end(OldEntry);
-         PI != PE; ++PI) {
+    for (pred_iterator PI = PB; PI != PE; ++PI) {
       BasicBlock *P = *PI;
       if (P == &F->getEntryBlock())
         AccPN->addIncoming(AccumulatorRecursionEliminationInitVal, P);
Modified: lib/Transforms/Utils/BasicBlockUtils.cpp
===================================================================
--- a/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -448,6 +448,7 @@ BasicBlock *llvm::SplitBlockPredecessors(BasicBlock *BB,
       // Create the new PHI node, insert it into NewBB at the end of the block
       PHINode *NewPHI =
         PHINode::Create(PN->getType(), PN->getName()+".ph", BI);
+      NewPHI->reserveOperandSpace(NumPreds);
       if (AA) AA->copyValue(PN, NewPHI);
       
       // Move all of the PHI values for 'Preds' to the new PHI.
Modified: lib/Transforms/Utils/BreakCriticalEdges.cpp
===================================================================
--- a/lib/Transforms/Utils/BreakCriticalEdges.cpp
+++ b/lib/Transforms/Utils/BreakCriticalEdges.cpp
@@ -142,6 +142,7 @@ static void CreatePHIsForSplitLoopExit(SmallVectorImpl<BasicBlock \
*> &Preds,  // Otherwise a new PHI is needed. Create one and populate it.
     PHINode *NewPN = PHINode::Create(PN->getType(), "split",
                                      SplitBB->getTerminator());
+    NewPN->reserveOperandSpace(Preds.size());
     for (unsigned i = 0, e = Preds.size(); i != e; ++i)
       NewPN->addIncoming(V, Preds[i]);
     // Update the original PHI.
Modified: lib/Transforms/Utils/CodeExtractor.cpp
===================================================================
--- a/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/lib/Transforms/Utils/CodeExtractor.cpp
@@ -104,7 +104,7 @@ namespace {
 /// region, we need to split the entry block of the region so that the PHI node
 /// is easier to deal with.
 void CodeExtractor::severSplitPHINodes(BasicBlock *&Header) {
-  bool HasPredsFromRegion = false;
+  unsigned NumPredsFromRegion = 0;
   unsigned NumPredsOutsideRegion = 0;
 
   if (Header != &Header->getParent()->getEntryBlock()) {
@@ -116,7 +116,7 @@ void CodeExtractor::severSplitPHINodes(BasicBlock *&Header) {
     // header block into two.
     for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
       if (BlocksToExtract.count(PN->getIncomingBlock(i)))
-        HasPredsFromRegion = true;
+        ++NumPredsFromRegion;
       else
         ++NumPredsOutsideRegion;
 
@@ -147,7 +147,7 @@ void CodeExtractor::severSplitPHINodes(BasicBlock *&Header) {
 
   // Okay, now we need to adjust the PHI nodes and any branches from within the
   // region to go to the new header block instead of the old header block.
-  if (HasPredsFromRegion) {
+  if (NumPredsFromRegion) {
     PHINode *PN = cast<PHINode>(OldPred->begin());
     // Loop over all of the predecessors of OldPred that are in the region,
     // changing them to branch to NewBB instead.
@@ -165,6 +165,7 @@ void CodeExtractor::severSplitPHINodes(BasicBlock *&Header) {
       // from OldPred of PN.
       PHINode *NewPN = PHINode::Create(PN->getType(), PN->getName()+".ce",
                                        NewBB->begin());
+      NewPN->reserveOperandSpace(1+NumPredsFromRegion);
       NewPN->addIncoming(PN, OldPred);
 
       // Loop over all of the incoming value in PN, moving them to NewPN if they
Modified: lib/Transforms/Utils/InlineFunction.cpp
===================================================================
--- a/lib/Transforms/Utils/InlineFunction.cpp
+++ b/lib/Transforms/Utils/InlineFunction.cpp
@@ -626,6 +626,7 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI) {
     if (!TheCall->use_empty()) {
       PHI = PHINode::Create(RTy, TheCall->getName(),
                             AfterCallBB->begin());
+      PHI->reserveOperandSpace(Returns.size());
       // Anything that used the result of the function call should now use the
       // PHI node as their operand.
       TheCall->replaceAllUsesWith(PHI);
Modified: lib/Transforms/Utils/SimplifyCFG.cpp
===================================================================
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -1598,13 +1598,15 @@ static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, \
                BranchInst *BI) {
     // in the constant and simplify the block result.  Subsequent passes of
     // simplifycfg will thread the block.
     if (BlockIsSimpleEnoughToThreadThrough(BB)) {
+      pred_iterator PB = pred_begin(BB), PE = pred_end(BB);
       PHINode *NewPN = PHINode::Create(Type::getInt1Ty(BB->getContext()),
                                        BI->getCondition()->getName() + ".pr",
                                        BB->begin());
+      NewPN->reserveOperandSpace(std::distance(PB, PE));
       // Okay, we're going to insert the PHI node.  Since PBI is not the only
       // predecessor, compute the PHI'd conditional value for all of the preds.
       // Any predecessor where the condition is not computable we keep symbolic.
-      for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
+      for (pred_iterator PI = PB; PI != PE; ++PI) {
         BasicBlock *P = *PI;
         if ((PBI = dyn_cast<BranchInst>(P->getTerminator())) &&
             PBI != BI && PBI->isConditional() &&
Modified: lib/Transforms/Utils/UnifyFunctionExitNodes.cpp
===================================================================
--- a/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp
+++ b/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp
@@ -117,6 +117,7 @@ bool UnifyFunctionExitNodes::runOnFunction(Function &F) {
   } else {
     // If the function doesn't return void... add a PHI node to the block...
     PN = PHINode::Create(F.getReturnType(), "UnifiedRetVal");
+    PN->reserveOperandSpace(ReturningBlocks.size());
     NewRetBlock->getInstList().push_back(PN);
     ReturnInst::Create(F.getContext(), PN, NewRetBlock);
   }
Modified: tools/bugpoint/Miscompilation.cpp
===================================================================
--- a/tools/bugpoint/Miscompilation.cpp
+++ b/tools/bugpoint/Miscompilation.cpp
@@ -887,6 +887,7 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module \
*&Test,  
           PHINode *FuncPtr = PHINode::Create(NullPtr->getType(),
                                              "fp", DoCallBB);
+          FuncPtr->reserveOperandSpace(2);
           FuncPtr->addIncoming(CastedResolver, LookupBB);
           FuncPtr->addIncoming(CachedVal, EntryBB);
 
Modified: unittests/Transforms/Utils/Local.cpp
===================================================================
--- a/unittests/Transforms/Utils/Local.cpp
+++ b/unittests/Transforms/Utils/Local.cpp
@@ -27,6 +27,7 @@ TEST(Local, RecursivelyDeleteDeadPHINodes) {
 
   builder.SetInsertPoint(bb0);
   PHINode    *phi = builder.CreatePHI(Type::getInt32Ty(C));
+  phi->reserveOperandSpace(2);
   BranchInst *br0 = builder.CreateCondBr(builder.getTrue(), bb0, bb1);
 
   builder.SetInsertPoint(bb1);


   Commit: 97ebdafb893485774cd6c2f36a6f5a0d6107548a
   Author: Jay Foad <jay.foad@gmail.com>
     Date: 03/30/2011 07:28:46
      URL: https://github.com/mono/llvm/commit/97ebdafb893485774cd6c2f36a6f5a0d6107548a


Remove PHINode::reserveOperandSpace(). Instead, add a parameter to
PHINode::Create() giving the (known or expected) number of operands.

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

Changed paths:
 M docs/tutorial/LangImpl5.html
 M docs/tutorial/LangImpl6.html
 M docs/tutorial/LangImpl7.html
 M examples/BrainF/BrainF.cpp
 M examples/Kaleidoscope/Chapter5/toy.cpp
 M examples/Kaleidoscope/Chapter6/toy.cpp
 M examples/Kaleidoscope/Chapter7/toy.cpp
 M include/llvm/Instructions.h
 M include/llvm/Support/IRBuilder.h
 M lib/Analysis/ScalarEvolutionExpander.cpp
 M lib/AsmParser/LLParser.cpp
 M lib/Bitcode/Reader/BitcodeReader.cpp
 M lib/CodeGen/DwarfEHPrepare.cpp
 M lib/Target/CppBackend/CPPBackend.cpp
 M lib/Transforms/IPO/GlobalOpt.cpp
 M lib/Transforms/IPO/LowerSetJmp.cpp
 M lib/Transforms/IPO/PartialInlining.cpp
 M lib/Transforms/InstCombine/InstCombineCasts.cpp
 M lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
 M lib/Transforms/InstCombine/InstCombinePHI.cpp
 M lib/Transforms/InstCombine/InstructionCombining.cpp
 M lib/Transforms/Instrumentation/PathProfiling.cpp
 M lib/Transforms/Scalar/GVN.cpp
 M lib/Transforms/Scalar/IndVarSimplify.cpp
 M lib/Transforms/Scalar/JumpThreading.cpp
 M lib/Transforms/Scalar/LoopStrengthReduce.cpp
 M lib/Transforms/Scalar/ScalarReplAggregates.cpp
 M lib/Transforms/Scalar/SimplifyCFGPass.cpp
 M lib/Transforms/Scalar/TailRecursionElimination.cpp
 M lib/Transforms/Utils/BasicBlockUtils.cpp
 M lib/Transforms/Utils/BreakCriticalEdges.cpp
 M lib/Transforms/Utils/CodeExtractor.cpp
 M lib/Transforms/Utils/InlineFunction.cpp
 M lib/Transforms/Utils/LCSSA.cpp
 M lib/Transforms/Utils/LoopSimplify.cpp
 M lib/Transforms/Utils/PromoteMemoryToRegister.cpp
 M lib/Transforms/Utils/SSAUpdater.cpp
 M lib/Transforms/Utils/SimplifyCFG.cpp
 M lib/Transforms/Utils/UnifyFunctionExitNodes.cpp
 M lib/VMCore/Core.cpp
 M tools/bugpoint/Miscompilation.cpp
 M unittests/Transforms/Utils/Local.cpp

Modified: docs/tutorial/LangImpl5.html
===================================================================
--- a/docs/tutorial/LangImpl5.html
+++ b/docs/tutorial/LangImpl5.html
@@ -472,7 +472,7 @@ are emitted, we can finish up with the merge code:</p>
   // Emit merge block.
   TheFunction->getBasicBlockList().push_back(MergeBB);
   Builder.SetInsertPoint(MergeBB);
-  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
+  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
                                   "iftmp");
   
   PN->addIncoming(ThenV, ThenBB);
@@ -746,7 +746,7 @@ create an unconditional branch for the fall-through between the \
two blocks.</p>  Builder.SetInsertPoint(LoopBB);
   
   // Start the PHI node with an entry for Start.
-  PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), \
VarName.c_str()); +  PHINode *Variable = \
Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, VarName.c_str());  \
Variable-&gt;addIncoming(StartVal, PreheaderBB);  </pre>
 </div>
@@ -1452,7 +1452,7 @@ Value *IfExprAST::Codegen() {
   // Emit merge block.
   TheFunction-&gt;getBasicBlockList().push_back(MergeBB);
   Builder.SetInsertPoint(MergeBB);
-  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
+  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
                                   "iftmp");
   
   PN-&gt;addIncoming(ThenV, ThenBB);
@@ -1494,7 +1494,7 @@ Value *ForExprAST::Codegen() {
   Builder.SetInsertPoint(LoopBB);
   
   // Start the PHI node with an entry for Start.
-  PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), \
VarName.c_str()); +  PHINode *Variable = \
Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, VarName.c_str());  \
Variable-&gt;addIncoming(StartVal, PreheaderBB);  
   // Within the loop, the variable is defined equal to the PHI node.  If it
Modified: docs/tutorial/LangImpl6.html
===================================================================
--- a/docs/tutorial/LangImpl6.html
+++ b/docs/tutorial/LangImpl6.html
@@ -1475,7 +1475,7 @@ Value *IfExprAST::Codegen() {
   // Emit merge block.
   TheFunction-&gt;getBasicBlockList().push_back(MergeBB);
   Builder.SetInsertPoint(MergeBB);
-  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
+  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
                                   "iftmp");
   
   PN-&gt;addIncoming(ThenV, ThenBB);
@@ -1517,7 +1517,7 @@ Value *ForExprAST::Codegen() {
   Builder.SetInsertPoint(LoopBB);
   
   // Start the PHI node with an entry for Start.
-  PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), \
VarName.c_str()); +  PHINode *Variable = \
Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, VarName.c_str());  \
Variable-&gt;addIncoming(StartVal, PreheaderBB);  
   // Within the loop, the variable is defined equal to the PHI node.  If it
Modified: docs/tutorial/LangImpl7.html
===================================================================
--- a/docs/tutorial/LangImpl7.html
+++ b/docs/tutorial/LangImpl7.html
@@ -1755,7 +1755,7 @@ Value *IfExprAST::Codegen() {
   // Emit merge block.
   TheFunction-&gt;getBasicBlockList().push_back(MergeBB);
   Builder.SetInsertPoint(MergeBB);
-  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
+  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
                                   "iftmp");
   
   PN-&gt;addIncoming(ThenV, ThenBB);
Modified: examples/BrainF/BrainF.cpp
===================================================================
--- a/examples/BrainF/BrainF.cpp
+++ b/examples/BrainF/BrainF.cpp
@@ -294,8 +294,7 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock \
                *testbb,
           // Make part of PHI instruction now, wait until end of loop to finish
           PHINode *phi_0 =
             PHINode::Create(PointerType::getUnqual(IntegerType::getInt8Ty(C)),
-                            headreg, testbb);
-          phi_0->reserveOperandSpace(2);
+                            2, headreg, testbb);
           phi_0->addIncoming(curhead, bb_0);
           curhead = phi_0;
 
@@ -449,8 +448,8 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock \
*testbb,  
       //%head.%d = phi i8 *[%head.%d, %main.%d]
       PHINode *phi_1 = builder->
-        CreatePHI(PointerType::getUnqual(IntegerType::getInt8Ty(C)), headreg);
-      phi_1->reserveOperandSpace(1);
+        CreatePHI(PointerType::getUnqual(IntegerType::getInt8Ty(C)), 1,
+                  headreg);
       phi_1->addIncoming(head_0, testbb);
       curhead = phi_1;
     }
Modified: examples/Kaleidoscope/Chapter5/toy.cpp
===================================================================
--- a/examples/Kaleidoscope/Chapter5/toy.cpp
+++ b/examples/Kaleidoscope/Chapter5/toy.cpp
@@ -550,9 +550,8 @@ Value *IfExprAST::Codegen() {
   // Emit merge block.
   TheFunction->getBasicBlockList().push_back(MergeBB);
   Builder.SetInsertPoint(MergeBB);
-  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
+  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
                                   "iftmp");
-  PN->reserveOperandSpace(2);
   
   PN->addIncoming(ThenV, ThenBB);
   PN->addIncoming(ElseV, ElseBB);
@@ -593,8 +592,7 @@ Value *ForExprAST::Codegen() {
   Builder.SetInsertPoint(LoopBB);
   
   // Start the PHI node with an entry for Start.
-  PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), \
                VarName.c_str());
-  Variable->reserveOperandSpace(2);
+  PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, \
VarName.c_str());  Variable->addIncoming(StartVal, PreheaderBB);
   
   // Within the loop, the variable is defined equal to the PHI node.  If it
Modified: examples/Kaleidoscope/Chapter6/toy.cpp
===================================================================
--- a/examples/Kaleidoscope/Chapter6/toy.cpp
+++ b/examples/Kaleidoscope/Chapter6/toy.cpp
@@ -654,9 +654,8 @@ Value *IfExprAST::Codegen() {
   // Emit merge block.
   TheFunction->getBasicBlockList().push_back(MergeBB);
   Builder.SetInsertPoint(MergeBB);
-  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
+  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
                                   "iftmp");
-  PN->reserveOperandSpace(2);
   
   PN->addIncoming(ThenV, ThenBB);
   PN->addIncoming(ElseV, ElseBB);
@@ -697,8 +696,7 @@ Value *ForExprAST::Codegen() {
   Builder.SetInsertPoint(LoopBB);
   
   // Start the PHI node with an entry for Start.
-  PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), \
                VarName.c_str());
-  Variable->reserveOperandSpace(2);
+  PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, \
VarName.c_str());  Variable->addIncoming(StartVal, PreheaderBB);
   
   // Within the loop, the variable is defined equal to the PHI node.  If it
Modified: examples/Kaleidoscope/Chapter7/toy.cpp
===================================================================
--- a/examples/Kaleidoscope/Chapter7/toy.cpp
+++ b/examples/Kaleidoscope/Chapter7/toy.cpp
@@ -750,9 +750,8 @@ Value *IfExprAST::Codegen() {
   // Emit merge block.
   TheFunction->getBasicBlockList().push_back(MergeBB);
   Builder.SetInsertPoint(MergeBB);
-  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
+  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
                                   "iftmp");
-  PN->reserveOperandSpace(2);
   
   PN->addIncoming(ThenV, ThenBB);
   PN->addIncoming(ElseV, ElseBB);
Modified: include/llvm/Instructions.h
===================================================================
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -1811,39 +1811,35 @@ class PHINode : public Instruction {
   void *operator new(size_t s) {
     return User::operator new(s, 0);
   }
-  explicit PHINode(const Type *Ty, const Twine &NameStr = "",
-                   Instruction *InsertBefore = 0)
+  explicit PHINode(const Type *Ty, unsigned NumReservedValues,
+                   const Twine &NameStr = "", Instruction *InsertBefore = 0)
     : Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore),
-      ReservedSpace(0) {
+      ReservedSpace(NumReservedValues * 2) {
     setName(NameStr);
+    OperandList = allocHungoffUses(ReservedSpace);
   }
 
-  PHINode(const Type *Ty, const Twine &NameStr, BasicBlock *InsertAtEnd)
+  PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr,
+          BasicBlock *InsertAtEnd)
     : Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd),
-      ReservedSpace(0) {
+      ReservedSpace(NumReservedValues * 2) {
     setName(NameStr);
+    OperandList = allocHungoffUses(ReservedSpace);
   }
 protected:
   virtual PHINode *clone_impl() const;
 public:
-  static PHINode *Create(const Type *Ty, const Twine &NameStr = "",
+  static PHINode *Create(const Type *Ty, unsigned NumReservedValues,
+                         const Twine &NameStr = "",
                          Instruction *InsertBefore = 0) {
-    return new PHINode(Ty, NameStr, InsertBefore);
+    return new PHINode(Ty, NumReservedValues, NameStr, InsertBefore);
   }
-  static PHINode *Create(const Type *Ty, const Twine &NameStr,
-                         BasicBlock *InsertAtEnd) {
-    return new PHINode(Ty, NameStr, InsertAtEnd);
+  static PHINode *Create(const Type *Ty, unsigned NumReservedValues, 
+                         const Twine &NameStr, BasicBlock *InsertAtEnd) {
+    return new PHINode(Ty, NumReservedValues, NameStr, InsertAtEnd);
   }
   ~PHINode();
 
-  /// reserveOperandSpace - This method can be used to avoid repeated
-  /// reallocation of PHI operand lists by reserving space for the correct
-  /// number of operands before adding them.  Unlike normal vector reserves,
-  /// this method can also be used to trim the operand space.
-  void reserveOperandSpace(unsigned NumValues) {
-    resizeOperands(NumValues*2);
-  }
-
   /// Provide fast operand accessors
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
 
Modified: include/llvm/Support/IRBuilder.h
===================================================================
--- a/include/llvm/Support/IRBuilder.h
+++ b/include/llvm/Support/IRBuilder.h
@@ -1070,8 +1070,9 @@ public:
   // Instruction creation methods: Other Instructions
   //===--------------------------------------------------------------------===//
 
-  PHINode *CreatePHI(const Type *Ty, const Twine &Name = "") {
-    return Insert(PHINode::Create(Ty), Name);
+  PHINode *CreatePHI(const Type *Ty, unsigned NumReservedValues,
+                     const Twine &Name = "") {
+    return Insert(PHINode::Create(Ty, NumReservedValues), Name);
   }
 
   CallInst *CreateCall(Value *Callee, const Twine &Name = "") {
Modified: lib/Analysis/ScalarEvolutionExpander.cpp
===================================================================
--- a/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -935,8 +935,7 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr \
*Normalized,  BasicBlock *Header = L->getHeader();
   Builder.SetInsertPoint(Header, Header->begin());
   pred_iterator HPB = pred_begin(Header), HPE = pred_end(Header);
-  PHINode *PN = Builder.CreatePHI(ExpandTy, "lsr.iv");
-  PN->reserveOperandSpace(std::distance(HPB, HPE));
+  PHINode *PN = Builder.CreatePHI(ExpandTy, std::distance(HPB, HPE), "lsr.iv");
   rememberInstruction(PN);
 
   // Create the step instructions and populate the PHI.
@@ -1143,8 +1142,8 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
     // specified loop.
     BasicBlock *Header = L->getHeader();
     pred_iterator HPB = pred_begin(Header), HPE = pred_end(Header);
-    CanonicalIV = PHINode::Create(Ty, "indvar", Header->begin());
-    CanonicalIV->reserveOperandSpace(std::distance(HPB, HPE));
+    CanonicalIV = PHINode::Create(Ty, std::distance(HPB, HPE), "indvar",
+                                  Header->begin());
     rememberInstruction(CanonicalIV);
 
     Constant *One = ConstantInt::get(Ty, 1);
Modified: lib/AsmParser/LLParser.cpp
===================================================================
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -3634,8 +3634,7 @@ int LLParser::ParsePHI(Instruction *&Inst, PerFunctionState \
&PFS) {  if (!Ty->isFirstClassType())
     return Error(TypeLoc, "phi node must have first class type");
 
-  PHINode *PN = PHINode::Create(Ty);
-  PN->reserveOperandSpace(PHIVals.size());
+  PHINode *PN = PHINode::Create(Ty, PHIVals.size());
   for (unsigned i = 0, e = PHIVals.size(); i != e; ++i)
     PN->addIncoming(PHIVals[i].first, PHIVals[i].second);
   Inst = PN;
Modified: lib/Bitcode/Reader/BitcodeReader.cpp
===================================================================
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -2288,9 +2288,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
       const Type *Ty = getTypeByID(Record[0]);
       if (!Ty) return Error("Invalid PHI record");
 
-      PHINode *PN = PHINode::Create(Ty);
+      PHINode *PN = PHINode::Create(Ty, (Record.size()-1)/2);
       InstructionList.push_back(PN);
-      PN->reserveOperandSpace((Record.size()-1)/2);
 
       for (unsigned i = 0, e = Record.size()-1; i != e; i += 2) {
         Value *V = getFnValueByID(Record[1+i], Ty);
Modified: lib/CodeGen/DwarfEHPrepare.cpp
===================================================================
--- a/lib/CodeGen/DwarfEHPrepare.cpp
+++ b/lib/CodeGen/DwarfEHPrepare.cpp
@@ -439,9 +439,9 @@ bool DwarfEHPrepare::NormalizeLandingPads() {
       if (InVal == 0) {
         // Different unwind edges have different values.  Create a new PHI node
         // in NewBB.
-        PHINode *NewPN = PHINode::Create(PN->getType(), PN->getName()+".unwind",
-                                         NewBB);
-        NewPN->reserveOperandSpace(PN->getNumIncomingValues());
+        PHINode *NewPN = PHINode::Create(PN->getType(),
+                                         PN->getNumIncomingValues(),
+                                         PN->getName()+".unwind", NewBB);
         // Add an entry for each unwind edge, using the value from the old PHI.
         for (pred_iterator PI = PB; PI != PE; ++PI)
           NewPN->addIncoming(PN->getIncomingValueForBlock(*PI), *PI);
Modified: lib/Target/CppBackend/CPPBackend.cpp
===================================================================
--- a/lib/Target/CppBackend/CPPBackend.cpp
+++ b/lib/Target/CppBackend/CPPBackend.cpp
@@ -1348,12 +1348,10 @@ void CppWriter::printInstruction(const Instruction *I,
     const PHINode* phi = cast<PHINode>(I);
 
     Out << "PHINode* " << iName << " = PHINode::Create("
-        << getCppName(phi->getType()) << ", \"";
+        << getCppName(phi->getType()) << ", \""
+        << phi->getNumIncomingValues() << ", \"";
     printEscapedString(phi->getName());
     Out << "\", " << bbname << ");";
-    nl(Out) << iName << "->reserveOperandSpace("
-      << phi->getNumIncomingValues()
-        << ");";
     nl(Out);
     for (unsigned i = 0; i < phi->getNumOperands(); i+=2) {
       Out << iName << "->addIncoming("
Modified: lib/Transforms/IPO/GlobalOpt.cpp
===================================================================
--- a/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/lib/Transforms/IPO/GlobalOpt.cpp
@@ -1195,8 +1195,8 @@ static Value *GetHeapSROAValue(Value *V, unsigned FieldNo,
 
     PHINode *NewPN =
      PHINode::Create(PointerType::getUnqual(ST->getElementType(FieldNo)),
+                     PN->getNumIncomingValues(),
                      PN->getName()+".f"+Twine(FieldNo), PN);
-    NewPN->reserveOperandSpace(PN->getNumIncomingValues());
     Result = NewPN;
     PHIsToRewrite.push_back(std::make_pair(PN, FieldNo));
   } else {
Modified: lib/Transforms/IPO/LowerSetJmp.cpp
===================================================================
--- a/lib/Transforms/IPO/LowerSetJmp.cpp
+++ b/lib/Transforms/IPO/LowerSetJmp.cpp
@@ -430,9 +430,8 @@ void LowerSetJmp::TransformSetJmpCall(CallInst* Inst)
 
   // This PHI node will be in the new block created from the
   // splitBasicBlock call.
-  PHINode* PHI = PHINode::Create(Type::getInt32Ty(Inst->getContext()),
+  PHINode* PHI = PHINode::Create(Type::getInt32Ty(Inst->getContext()), 2,
                                  "SetJmpReturn", Inst);
-  PHI->reserveOperandSpace(2);
 
   // Coming from a call to setjmp, the return is 0.
   PHI->addIncoming(Constant::getNullValue(Type::getInt32Ty(Inst->getContext())),
Modified: lib/Transforms/IPO/PartialInlining.cpp
===================================================================
--- a/lib/Transforms/IPO/PartialInlining.cpp
+++ b/lib/Transforms/IPO/PartialInlining.cpp
@@ -95,8 +95,7 @@ Function* PartialInliner::unswitchFunction(Function* F) {
     PHINode* OldPhi = dyn_cast<PHINode>(I);
     if (!OldPhi) break;
     
-    PHINode* retPhi = PHINode::Create(OldPhi->getType(), "", Ins);
-    retPhi->reserveOperandSpace(2);
+    PHINode* retPhi = PHINode::Create(OldPhi->getType(), 2, "", Ins);
     OldPhi->replaceAllUsesWith(retPhi);
     Ins = newReturnBlock->getFirstNonPHI();
     
Modified: lib/Transforms/InstCombine/InstCombineCasts.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -196,8 +196,7 @@ Value *InstCombiner::EvaluateInDifferentType(Value *V, const Type \
*Ty,  }
   case Instruction::PHI: {
     PHINode *OPN = cast<PHINode>(I);
-    PHINode *NPN = PHINode::Create(Ty);
-    NPN->reserveOperandSpace(OPN->getNumIncomingValues());
+    PHINode *NPN = PHINode::Create(Ty, OPN->getNumIncomingValues());
     for (unsigned i = 0, e = OPN->getNumIncomingValues(); i != e; ++i) {
       Value *V =EvaluateInDifferentType(OPN->getIncomingValue(i), Ty, isSigned);
       NPN->addIncoming(V, OPN->getIncomingBlock(i));
Modified: lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -591,8 +591,7 @@ bool InstCombiner::SimplifyStoreAtEndOfBlock(StoreInst &SI) {
   // Insert a PHI node now if we need it.
   Value *MergedVal = OtherStore->getOperand(0);
   if (MergedVal != SI.getOperand(0)) {
-    PHINode *PN = PHINode::Create(MergedVal->getType(), "storemerge");
-    PN->reserveOperandSpace(2);
+    PHINode *PN = PHINode::Create(MergedVal->getType(), 2, "storemerge");
     PN->addIncoming(SI.getOperand(0), SI.getParent());
     PN->addIncoming(OtherStore->getOperand(0), OtherBB);
     MergedVal = InsertNewInstBefore(PN, DestBB->front());
Modified: lib/Transforms/InstCombine/InstCombinePHI.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ b/lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -80,18 +80,16 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
   Value *InRHS = FirstInst->getOperand(1);
   PHINode *NewLHS = 0, *NewRHS = 0;
   if (LHSVal == 0) {
-    NewLHS = PHINode::Create(LHSType,
+    NewLHS = PHINode::Create(LHSType, PN.getNumIncomingValues(),
                              FirstInst->getOperand(0)->getName() + ".pn");
-    NewLHS->reserveOperandSpace(PN.getNumIncomingValues());
     NewLHS->addIncoming(InLHS, PN.getIncomingBlock(0));
     InsertNewInstBefore(NewLHS, PN);
     LHSVal = NewLHS;
   }
   
   if (RHSVal == 0) {
-    NewRHS = PHINode::Create(RHSType,
+    NewRHS = PHINode::Create(RHSType, PN.getNumIncomingValues(),
                              FirstInst->getOperand(1)->getName() + ".pn");
-    NewRHS->reserveOperandSpace(PN.getNumIncomingValues());
     NewRHS->addIncoming(InRHS, PN.getIncomingBlock(0));
     InsertNewInstBefore(NewRHS, PN);
     RHSVal = NewRHS;
@@ -202,11 +200,10 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
   for (unsigned i = 0, e = FixedOperands.size(); i != e; ++i) {
     if (FixedOperands[i]) continue;  // operand doesn't need a phi.
     Value *FirstOp = FirstInst->getOperand(i);
-    PHINode *NewPN = PHINode::Create(FirstOp->getType(),
+    PHINode *NewPN = PHINode::Create(FirstOp->getType(), e,
                                      FirstOp->getName()+".pn");
     InsertNewInstBefore(NewPN, PN);
     
-    NewPN->reserveOperandSpace(e);
     NewPN->addIncoming(FirstOp, PN.getIncomingBlock(0));
     OperandPhis[i] = NewPN;
     FixedOperands[i] = NewPN;
@@ -340,8 +337,8 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) {
   // Okay, they are all the same operation.  Create a new PHI node of the
   // correct type, and PHI together all of the LHS's of the instructions.
   PHINode *NewPN = PHINode::Create(FirstLI->getOperand(0)->getType(),
+                                   PN.getNumIncomingValues(),
                                    PN.getName()+".in");
-  NewPN->reserveOperandSpace(PN.getNumIncomingValues());
   
   Value *InVal = FirstLI->getOperand(0);
   NewPN->addIncoming(InVal, PN.getIncomingBlock(0));
@@ -446,8 +443,8 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
   // Okay, they are all the same operation.  Create a new PHI node of the
   // correct type, and PHI together all of the LHS's of the instructions.
   PHINode *NewPN = PHINode::Create(FirstInst->getOperand(0)->getType(),
+                                   PN.getNumIncomingValues(),
                                    PN.getName()+".in");
-  NewPN->reserveOperandSpace(PN.getNumIncomingValues());
 
   Value *InVal = FirstInst->getOperand(0);
   NewPN->addIncoming(InVal, PN.getIncomingBlock(0));
@@ -699,8 +696,8 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode \
                &FirstPhi) {
     if ((EltPHI = ExtractedVals[LoweredPHIRecord(PN, Offset, Ty)]) == 0) {
       
       // Otherwise, Create the new PHI node for this user.
-      EltPHI = PHINode::Create(Ty, PN->getName()+".off"+Twine(Offset), PN);
-      EltPHI->reserveOperandSpace(PN->getNumIncomingValues());
+      EltPHI = PHINode::Create(Ty, PN->getNumIncomingValues(),
+                               PN->getName()+".off"+Twine(Offset), PN);
       assert(EltPHI->getType() != PN->getType() &&
              "Truncate didn't shrink phi?");
     
Modified: lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -600,8 +600,7 @@ Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) {
   }
 
   // Okay, we can do the transformation: create the new PHI node.
-  PHINode *NewPN = PHINode::Create(I.getType(), "");
-  NewPN->reserveOperandSpace(PN->getNumIncomingValues());
+  PHINode *NewPN = PHINode::Create(I.getType(), PN->getNumIncomingValues(), "");
   InsertNewInstBefore(NewPN, *PN);
   NewPN->takeName(PN);
   
Modified: lib/Transforms/Instrumentation/PathProfiling.cpp
===================================================================
--- a/lib/Transforms/Instrumentation/PathProfiling.cpp
+++ b/lib/Transforms/Instrumentation/PathProfiling.cpp
@@ -931,9 +931,9 @@ void PathProfiler::preparePHI(BLInstrumentationNode* node) {
   BasicBlock::iterator insertPoint = block->getFirstNonPHI();
   pred_iterator PB = pred_begin(node->getBlock()),
           PE = pred_end(node->getBlock());
-  PHINode* phi = PHINode::Create(Type::getInt32Ty(*Context), "pathNumber",
+  PHINode* phi = PHINode::Create(Type::getInt32Ty(*Context),
+                                 std::distance(PB, PE), "pathNumber",
                                  insertPoint );
-  phi->reserveOperandSpace(std::distance(PB, PE));
   node->setPathPHI(phi);
   node->setStartingPathNumber(phi);
   node->setEndingPathNumber(phi);
Modified: lib/Transforms/Scalar/GVN.cpp
===================================================================
--- a/lib/Transforms/Scalar/GVN.cpp
+++ b/lib/Transforms/Scalar/GVN.cpp
@@ -1945,10 +1945,9 @@ bool GVN::performPRE(Function &F) {
 
       // Create a PHI to make the value available in this block.
       pred_iterator PB = pred_begin(CurrentBlock), PE = pred_end(CurrentBlock);
-      PHINode* Phi = PHINode::Create(CurInst->getType(),
+      PHINode* Phi = PHINode::Create(CurInst->getType(), std::distance(PB, PE),
                                      CurInst->getName() + ".pre-phi",
                                      CurrentBlock->begin());
-      Phi->reserveOperandSpace(std::distance(PB, PE));
       for (pred_iterator PI = PB; PI != PE; ++PI) {
         BasicBlock *P = *PI;
         Phi->addIncoming(predMap[P], P);
Modified: lib/Transforms/Scalar/IndVarSimplify.cpp
===================================================================
--- a/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -1038,8 +1038,7 @@ void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode \
*PN) {  const IntegerType *Int32Ty = Type::getInt32Ty(PN->getContext());
 
   // Insert new integer induction variable.
-  PHINode *NewPHI = PHINode::Create(Int32Ty, PN->getName()+".int", PN);
-  NewPHI->reserveOperandSpace(2);
+  PHINode *NewPHI = PHINode::Create(Int32Ty, 2, PN->getName()+".int", PN);
   NewPHI->addIncoming(ConstantInt::get(Int32Ty, InitValue),
                       PN->getIncomingBlock(IncomingEdge));
 
Modified: lib/Transforms/Scalar/JumpThreading.cpp
===================================================================
--- a/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/lib/Transforms/Scalar/JumpThreading.cpp
@@ -929,8 +929,8 @@ bool JumpThreading::SimplifyPartiallyRedundantLoad(LoadInst *LI) \
{  
   // Create a PHI node at the start of the block for the PRE'd load value.
   pred_iterator PB = pred_begin(LoadBB), PE = pred_end(LoadBB);
-  PHINode *PN = PHINode::Create(LI->getType(), "", LoadBB->begin());
-  PN->reserveOperandSpace(std::distance(PB, PE));
+  PHINode *PN = PHINode::Create(LI->getType(), std::distance(PB, PE), "",
+                                LoadBB->begin());
   PN->takeName(LI);
 
   // Insert new entries into the PHI for each predecessor.  A single block may
Modified: lib/Transforms/Scalar/LoopStrengthReduce.cpp
===================================================================
--- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -1491,8 +1491,7 @@ void LSRInstance::OptimizeShadowIV() {
     if (!C->getValue().isStrictlyPositive()) continue;
 
     /* Add new PHINode. */
-    PHINode *NewPH = PHINode::Create(DestTy, "IV.S.", PH);
-    NewPH->reserveOperandSpace(2);
+    PHINode *NewPH = PHINode::Create(DestTy, 2, "IV.S.", PH);
 
     /* create new increment. '++d' in above example. */
     Constant *CFP = ConstantFP::get(DestTy, C->getZExtValue());
Modified: lib/Transforms/Scalar/ScalarReplAggregates.cpp
===================================================================
--- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp
+++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
@@ -1227,8 +1227,8 @@ static bool tryToMakeAllocaBePromotable(AllocaInst *AI, const \
TargetData *TD) {  }
     
     const Type *LoadTy = cast<PointerType>(PN->getType())->getElementType();
-    PHINode *NewPN = PHINode::Create(LoadTy, PN->getName()+".ld", PN);
-    NewPN->reserveOperandSpace(PN->getNumIncomingValues());
+    PHINode *NewPN = PHINode::Create(LoadTy, PN->getNumIncomingValues(),
+                                     PN->getName()+".ld", PN);
 
     // Get the TBAA tag and alignment to use from one of the loads.  It doesn't
     // matter which one we get and if any differ, it doesn't matter.
Modified: lib/Transforms/Scalar/SimplifyCFGPass.cpp
===================================================================
--- a/lib/Transforms/Scalar/SimplifyCFGPass.cpp
+++ b/lib/Transforms/Scalar/SimplifyCFGPass.cpp
@@ -260,9 +260,9 @@ static bool MergeEmptyReturnBlocks(Function &F) {
     if (RetBlockPHI == 0) {
       Value *InVal = cast<ReturnInst>(RetBlock->getTerminator())->getOperand(0);
       pred_iterator PB = pred_begin(RetBlock), PE = pred_end(RetBlock);
-      RetBlockPHI = PHINode::Create(Ret->getOperand(0)->getType(), "merge",
+      RetBlockPHI = PHINode::Create(Ret->getOperand(0)->getType(),
+                                    std::distance(PB, PE), "merge",
                                     &RetBlock->front());
-      RetBlockPHI->reserveOperandSpace(std::distance(PB, PE));
       
       for (pred_iterator PI = PB; PI != PE; ++PI)
         RetBlockPHI->addIncoming(InVal, *PI);
Modified: lib/Transforms/Scalar/TailRecursionElimination.cpp
===================================================================
--- a/lib/Transforms/Scalar/TailRecursionElimination.cpp
+++ b/lib/Transforms/Scalar/TailRecursionElimination.cpp
@@ -496,9 +496,8 @@ bool TailCallElim::EliminateRecursiveTailCall(CallInst *CI, \
ReturnInst *Ret,  Instruction *InsertPos = OldEntry->begin();
     for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end();
          I != E; ++I) {
-      PHINode *PN = PHINode::Create(I->getType(),
+      PHINode *PN = PHINode::Create(I->getType(), 2,
                                     I->getName() + ".tr", InsertPos);
-      PN->reserveOperandSpace(2);
       I->replaceAllUsesWith(PN); // Everyone use the PHI node now!
       PN->addIncoming(I, NewEntry);
       ArgumentPHIs.push_back(PN);
@@ -531,8 +530,8 @@ bool TailCallElim::EliminateRecursiveTailCall(CallInst *CI, \
ReturnInst *Ret,  pred_iterator PB = pred_begin(OldEntry), PE = pred_end(OldEntry);
     PHINode *AccPN =
       PHINode::Create(AccumulatorRecursionEliminationInitVal->getType(),
+                      std::distance(PB, PE) + 1,
                       "accumulator.tr", OldEntry->begin());
-    AccPN->reserveOperandSpace(std::distance(PB, PE) + 1);
 
     // Loop over all of the predecessors of the tail recursion block.  For the
     // real entry into the function we seed the PHI with the initial value,
Modified: lib/Transforms/Utils/BasicBlockUtils.cpp
===================================================================
--- a/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -447,8 +447,7 @@ BasicBlock *llvm::SplitBlockPredecessors(BasicBlock *BB,
       // If the values coming into the block are not the same, we need a PHI.
       // Create the new PHI node, insert it into NewBB at the end of the block
       PHINode *NewPHI =
-        PHINode::Create(PN->getType(), PN->getName()+".ph", BI);
-      NewPHI->reserveOperandSpace(NumPreds);
+        PHINode::Create(PN->getType(), NumPreds, PN->getName()+".ph", BI);
       if (AA) AA->copyValue(PN, NewPHI);
       
       // Move all of the PHI values for 'Preds' to the new PHI.
Modified: lib/Transforms/Utils/BreakCriticalEdges.cpp
===================================================================
--- a/lib/Transforms/Utils/BreakCriticalEdges.cpp
+++ b/lib/Transforms/Utils/BreakCriticalEdges.cpp
@@ -140,9 +140,8 @@ static void CreatePHIsForSplitLoopExit(SmallVectorImpl<BasicBlock \
*> &Preds,  if (VP->getParent() == SplitBB)
         continue;
     // Otherwise a new PHI is needed. Create one and populate it.
-    PHINode *NewPN = PHINode::Create(PN->getType(), "split",
+    PHINode *NewPN = PHINode::Create(PN->getType(), Preds.size(), "split",
                                      SplitBB->getTerminator());
-    NewPN->reserveOperandSpace(Preds.size());
     for (unsigned i = 0, e = Preds.size(); i != e; ++i)
       NewPN->addIncoming(V, Preds[i]);
     // Update the original PHI.
Modified: lib/Transforms/Utils/CodeExtractor.cpp
===================================================================
--- a/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/lib/Transforms/Utils/CodeExtractor.cpp
@@ -163,9 +163,8 @@ void CodeExtractor::severSplitPHINodes(BasicBlock *&Header) {
       PHINode *PN = cast<PHINode>(AfterPHIs);
       // Create a new PHI node in the new region, which has an incoming value
       // from OldPred of PN.
-      PHINode *NewPN = PHINode::Create(PN->getType(), PN->getName()+".ce",
-                                       NewBB->begin());
-      NewPN->reserveOperandSpace(1+NumPredsFromRegion);
+      PHINode *NewPN = PHINode::Create(PN->getType(), 1 + NumPredsFromRegion,
+                                       PN->getName()+".ce", NewBB->begin());
       NewPN->addIncoming(PN, OldPred);
 
       // Loop over all of the incoming value in PN, moving them to NewPN if they
Modified: lib/Transforms/Utils/InlineFunction.cpp
===================================================================
--- a/lib/Transforms/Utils/InlineFunction.cpp
+++ b/lib/Transforms/Utils/InlineFunction.cpp
@@ -624,9 +624,8 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI) {
     // The PHI node should go at the front of the new basic block to merge all
     // possible incoming values.
     if (!TheCall->use_empty()) {
-      PHI = PHINode::Create(RTy, TheCall->getName(),
+      PHI = PHINode::Create(RTy, Returns.size(), TheCall->getName(),
                             AfterCallBB->begin());
-      PHI->reserveOperandSpace(Returns.size());
       // Anything that used the result of the function call should now use the
       // PHI node as their operand.
       TheCall->replaceAllUsesWith(PHI);
Modified: lib/Transforms/Utils/LCSSA.cpp
===================================================================
--- a/lib/Transforms/Utils/LCSSA.cpp
+++ b/lib/Transforms/Utils/LCSSA.cpp
@@ -222,9 +222,10 @@ bool LCSSA::ProcessInstruction(Instruction *Inst,
     // If we already inserted something for this BB, don't reprocess it.
     if (SSAUpdate.HasValueForBlock(ExitBB)) continue;
     
-    PHINode *PN = PHINode::Create(Inst->getType(), Inst->getName()+".lcssa",
+    PHINode *PN = PHINode::Create(Inst->getType(),
+                                  PredCache.GetNumPreds(ExitBB),
+                                  Inst->getName()+".lcssa",
                                   ExitBB->begin());
-    PN->reserveOperandSpace(PredCache.GetNumPreds(ExitBB));
 
     // Add inputs from inside the loop for this PHI.
     for (BasicBlock **PI = PredCache.GetPreds(ExitBB); *PI; ++PI) {
Modified: lib/Transforms/Utils/LoopSimplify.cpp
===================================================================
--- a/lib/Transforms/Utils/LoopSimplify.cpp
+++ b/lib/Transforms/Utils/LoopSimplify.cpp
@@ -648,9 +648,8 @@ LoopSimplify::InsertUniqueBackedgeBlock(Loop *L, BasicBlock \
*Preheader) {  // the backedge block which correspond to any PHI nodes in the header \
block.  for (BasicBlock::iterator I = Header->begin(); isa<PHINode>(I); ++I) {
     PHINode *PN = cast<PHINode>(I);
-    PHINode *NewPN = PHINode::Create(PN->getType(), PN->getName()+".be",
-                                     BETerminator);
-    NewPN->reserveOperandSpace(BackedgeBlocks.size());
+    PHINode *NewPN = PHINode::Create(PN->getType(), BackedgeBlocks.size(),
+                                     PN->getName()+".be", BETerminator);
     if (AA) AA->copyValue(PN, NewPN);
 
     // Loop over the PHI node, moving all entries except the one for the
Modified: lib/Transforms/Utils/PromoteMemoryToRegister.cpp
===================================================================
--- a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
+++ b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
@@ -961,12 +961,11 @@ bool PromoteMem2Reg::QueuePhiNode(BasicBlock *BB, unsigned \
AllocaNo,  
   // Create a PhiNode using the dereferenced type... and add the phi-node to the
   // BasicBlock.
-  PN = PHINode::Create(Allocas[AllocaNo]->getAllocatedType(),
+  PN = PHINode::Create(Allocas[AllocaNo]->getAllocatedType(), getNumPreds(BB),
                        Allocas[AllocaNo]->getName() + "." + Twine(Version++), 
                        BB->begin());
   ++NumPHIInsert;
   PhiToAllocaMap[PN] = AllocaNo;
-  PN->reserveOperandSpace(getNumPreds(BB));
 
   if (AST && PN->getType()->isPointerTy())
     AST->copyValue(PointerAllocaValues[AllocaNo], PN);
Modified: lib/Transforms/Utils/SSAUpdater.cpp
===================================================================
--- a/lib/Transforms/Utils/SSAUpdater.cpp
+++ b/lib/Transforms/Utils/SSAUpdater.cpp
@@ -170,8 +170,8 @@ Value *SSAUpdater::GetValueInMiddleOfBlock(BasicBlock *BB) {
   }
 
   // Ok, we have no way out, insert a new one now.
-  PHINode *InsertedPHI = PHINode::Create(ProtoType, ProtoName, &BB->front());
-  InsertedPHI->reserveOperandSpace(PredValues.size());
+  PHINode *InsertedPHI = PHINode::Create(ProtoType, PredValues.size(),
+                                         ProtoName, &BB->front());
 
   // Fill in all the predecessors of the PHI.
   for (unsigned i = 0, e = PredValues.size(); i != e; ++i)
@@ -289,9 +289,8 @@ public:
   /// Reserve space for the operands but do not fill them in yet.
   static Value *CreateEmptyPHI(BasicBlock *BB, unsigned NumPreds,
                                SSAUpdater *Updater) {
-    PHINode *PHI = PHINode::Create(Updater->ProtoType, Updater->ProtoName,
-                                   &BB->front());
-    PHI->reserveOperandSpace(NumPreds);
+    PHINode *PHI = PHINode::Create(Updater->ProtoType, NumPreds,
+                                   Updater->ProtoName, &BB->front());
     return PHI;
   }
 
Modified: lib/Transforms/Utils/SimplifyCFG.cpp
===================================================================
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -1600,9 +1600,9 @@ static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, \
BranchInst *BI) {  if (BlockIsSimpleEnoughToThreadThrough(BB)) {
       pred_iterator PB = pred_begin(BB), PE = pred_end(BB);
       PHINode *NewPN = PHINode::Create(Type::getInt1Ty(BB->getContext()),
+                                       std::distance(PB, PE),
                                        BI->getCondition()->getName() + ".pr",
                                        BB->begin());
-      NewPN->reserveOperandSpace(std::distance(PB, PE));
       // Okay, we're going to insert the PHI node.  Since PBI is not the only
       // predecessor, compute the PHI'd conditional value for all of the preds.
       // Any predecessor where the condition is not computable we keep symbolic.
Modified: lib/Transforms/Utils/UnifyFunctionExitNodes.cpp
===================================================================
--- a/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp
+++ b/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp
@@ -116,8 +116,8 @@ bool UnifyFunctionExitNodes::runOnFunction(Function &F) {
     ReturnInst::Create(F.getContext(), NULL, NewRetBlock);
   } else {
     // If the function doesn't return void... add a PHI node to the block...
-    PN = PHINode::Create(F.getReturnType(), "UnifiedRetVal");
-    PN->reserveOperandSpace(ReturningBlocks.size());
+    PN = PHINode::Create(F.getReturnType(), ReturningBlocks.size(),
+                         "UnifiedRetVal");
     NewRetBlock->getInstList().push_back(PN);
     ReturnInst::Create(F.getContext(), PN, NewRetBlock);
   }
Modified: lib/VMCore/Core.cpp
===================================================================
--- a/lib/VMCore/Core.cpp
+++ b/lib/VMCore/Core.cpp
@@ -2082,7 +2082,7 @@ LLVMValueRef LLVMBuildFCmp(LLVMBuilderRef B, LLVMRealPredicate \
Op,  /*--.. Miscellaneous instructions ..........................................--*/
 
 LLVMValueRef LLVMBuildPhi(LLVMBuilderRef B, LLVMTypeRef Ty, const char *Name) {
-  return wrap(unwrap(B)->CreatePHI(unwrap(Ty), Name));
+  return wrap(unwrap(B)->CreatePHI(unwrap(Ty), 0, Name));
 }
 
 LLVMValueRef LLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
Modified: tools/bugpoint/Miscompilation.cpp
===================================================================
--- a/tools/bugpoint/Miscompilation.cpp
+++ b/tools/bugpoint/Miscompilation.cpp
@@ -885,9 +885,8 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module \
*&Test,  new StoreInst(CastedResolver, Cache, LookupBB);
           BranchInst::Create(DoCallBB, LookupBB);
 
-          PHINode *FuncPtr = PHINode::Create(NullPtr->getType(),
+          PHINode *FuncPtr = PHINode::Create(NullPtr->getType(), 2,
                                              "fp", DoCallBB);
-          FuncPtr->reserveOperandSpace(2);
           FuncPtr->addIncoming(CastedResolver, LookupBB);
           FuncPtr->addIncoming(CachedVal, EntryBB);
 
Modified: unittests/Transforms/Utils/Local.cpp
===================================================================
--- a/unittests/Transforms/Utils/Local.cpp
+++ b/unittests/Transforms/Utils/Local.cpp
@@ -26,8 +26,7 @@ TEST(Local, RecursivelyDeleteDeadPHINodes) {
   BasicBlock *bb1 = BasicBlock::Create(C);
 
   builder.SetInsertPoint(bb0);
-  PHINode    *phi = builder.CreatePHI(Type::getInt32Ty(C));
-  phi->reserveOperandSpace(2);
+  PHINode    *phi = builder.CreatePHI(Type::getInt32Ty(C), 2);
   BranchInst *br0 = builder.CreateCondBr(builder.getTrue(), bb0, bb1);
 
   builder.SetInsertPoint(bb1);
@@ -44,12 +43,12 @@ TEST(Local, RecursivelyDeleteDeadPHINodes) {
   EXPECT_EQ(&bb1->front(), br1);
 
   builder.SetInsertPoint(bb0);
-  phi = builder.CreatePHI(Type::getInt32Ty(C));
+  phi = builder.CreatePHI(Type::getInt32Ty(C), 0);
 
   EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi));
 
   builder.SetInsertPoint(bb0);
-  phi = builder.CreatePHI(Type::getInt32Ty(C));
+  phi = builder.CreatePHI(Type::getInt32Ty(C), 0);
   builder.CreateAdd(phi, phi);
 
   EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi));


   Commit: 86ae8a7500ce8183546c077a9d35818a15e4ef41
   Author: Jay Foad <jay.foad@gmail.com>
     Date: 03/30/2011 09:29:06
      URL: https://github.com/mono/llvm/commit/86ae8a7500ce8183546c077a9d35818a15e4ef41


Add a comment on PHINode::Create().

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

Changed paths:
 M include/llvm/Instructions.h

Modified: include/llvm/Instructions.h
===================================================================
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -1829,6 +1829,8 @@ class PHINode : public Instruction {
 protected:
   virtual PHINode *clone_impl() const;
 public:
+  /// Constructors - NumReservedValues is a hint for the number of incoming
+  /// edges that this phi node will have (use 0 if you really have no idea).
   static PHINode *Create(const Type *Ty, unsigned NumReservedValues,
                          const Twine &NameStr = "",
                          Instruction *InsertBefore = 0) {


   Commit: 2d9c731def88af1d36f4ddad46e1664b4e940f3b
   Author: Jay Foad <jay.foad@gmail.com>
     Date: 03/30/2011 11:31:02
      URL: https://github.com/mono/llvm/commit/2d9c731def88af1d36f4ddad46e1664b4e940f3b


Fix more zero length memset warnings.

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

Changed paths:
 M include/llvm/ADT/DenseMap.h

Modified: include/llvm/ADT/DenseMap.h
===================================================================
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -422,7 +422,8 @@ private:
     }
 
 #ifndef NDEBUG
-    memset(OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets);
+    if (OldNumBuckets)
+      memset(OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets);
 #endif
     // Free the old table.
     operator delete(OldBuckets);


   Commit: fc8c2b35f5731f34f816d65b5c350ff73518880d
   Author: Benjamin Kramer <benny.kra@googlemail.com>
     Date: 03/30/2011 11:42:27
      URL: https://github.com/mono/llvm/commit/fc8c2b35f5731f34f816d65b5c350ff73518880d


Add APFloat::getExactInverse.

The idea is, that if an ieee 754 float is divided by a power of two, we can
turn the division into a cheaper multiplication. This function sees if we can
get an exact multiplicative inverse for a divisor and returns it if possible.

This is the hard part of PR9587.

I tested many inputs against llvm-gcc's frotend implementation of this
optimization and didn't find any difference. However, floating point is the
land of weird edge cases, so any review would be appreciated.

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

Changed paths:
 M include/llvm/ADT/APFloat.h
 M lib/Support/APFloat.cpp
 M unittests/ADT/APFloatTest.cpp

Modified: include/llvm/ADT/APFloat.h
===================================================================
--- a/include/llvm/ADT/APFloat.h
+++ b/include/llvm/ADT/APFloat.h
@@ -353,6 +353,10 @@ namespace llvm {
                   unsigned FormatPrecision = 0,
                   unsigned FormatMaxPadding = 3) const;
 
+    /// getExactInverse - If this value has an exact multiplicative inverse,
+    /// store it in inv and return true.
+    bool getExactInverse(APFloat *inv) const;
+
   private:
 
     /* Trivial queries.  */
Modified: lib/Support/APFloat.cpp
===================================================================
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -3562,3 +3562,29 @@ void APFloat::toString(SmallVectorImpl<char> &Str,
   for (; I != NDigits; ++I)
     Str.push_back(buffer[NDigits-I-1]);
 }
+
+bool APFloat::getExactInverse(APFloat *inv) const {
+  // We can only guarantee the existance of an exact inverse for IEEE floats.
+  if (semantics != &IEEEhalf && semantics != &IEEEsingle &&
+      semantics != &IEEEdouble && semantics != &IEEEquad)
+    return false;
+
+  // Special floats and denormals have no exact inverse.
+  if (category != fcNormal)
+    return false;
+
+  // Check that the number is a power of two by making sure that only the
+  // integer bit is set in the significand.
+  if (significandLSB() != semantics->precision - 1)
+    return false;
+
+  // Get the inverse.
+  APFloat reciprocal(*semantics, 1ULL);
+  if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK)
+    return false;
+
+  if (inv)
+    *inv = reciprocal;
+
+  return true;
+}
Modified: unittests/ADT/APFloatTest.cpp
===================================================================
--- a/unittests/ADT/APFloatTest.cpp
+++ b/unittests/ADT/APFloatTest.cpp
@@ -576,4 +576,27 @@ TEST(APFloatTest, StringHexadecimalExponentDeath) {
 #endif
 #endif
 
+TEST(APFloatTest, exactInverse) {
+  APFloat inv(0.0f);
+
+  // Trivial operation.
+  EXPECT_TRUE(APFloat(2.0).getExactInverse(&inv));
+  EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5)));
+  EXPECT_TRUE(APFloat(2.0f).getExactInverse(&inv));
+  EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5f)));
+
+  // FLT_MIN
+  EXPECT_TRUE(APFloat(1.17549435e-38f).getExactInverse(&inv));
+  EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(8.5070592e+37f)));
+
+  // Large float
+  EXPECT_TRUE(APFloat(1.7014118e38f).getExactInverse(&inv));
+  EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(5.8774718e-39f)));
+
+  // Zero
+  EXPECT_FALSE(APFloat(0.0).getExactInverse(0));
+  // Denormalized float
+  EXPECT_FALSE(APFloat(1.40129846e-45f).getExactInverse(0));
+}
+
 }


   Commit: 11d00f3b154dd7b5ee82a19869caa6c6878d31ec
   Author: Benjamin Kramer <benny.kra@googlemail.com>
     Date: 03/30/2011 11:42:35
      URL: https://github.com/mono/llvm/commit/11d00f3b154dd7b5ee82a19869caa6c6878d31ec


InstCombine: If the divisor of an fdiv has an exact inverse, turn it into an fmul.

Fixes PR9587.

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

Changed paths:
 M lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
Added paths:
 A test/Transforms/InstCombine/fdiv.ll

Modified: lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -452,6 +452,18 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) {
   if (Value *V = SimplifyFDivInst(Op0, Op1, TD))
     return ReplaceInstUsesWith(I, V);
 
+  if (ConstantFP *Op1C = dyn_cast<ConstantFP>(Op1)) {
+    const APFloat &Op1F = Op1C->getValueAPF();
+
+    // If the divisor has an exact multiplicative inverse we can turn the fdiv
+    // into a cheaper fmul.
+    APFloat Reciprocal(Op1F.getSemantics());
+    if (Op1F.getExactInverse(&Reciprocal)) {
+      ConstantFP *RFP = ConstantFP::get(Builder->getContext(), Reciprocal);
+      return BinaryOperator::CreateFMul(Op0, RFP);
+    }
+  }
+
   return 0;
 }
 

Added: test/Transforms/InstCombine/fdiv.ll
===================================================================
--- /dev/null
+++ b/test/Transforms/InstCombine/fdiv.ll
@@ -0,0 +1,26 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+
+define float @test1(float %x) nounwind readnone ssp {
+  %div = fdiv float %x, 0x3810000000000000
+  ret float %div
+
+; CHECK: @test1
+; CHECK-NEXT: fmul float %x, 0x47D0000000000000
+}
+
+define float @test2(float %x) nounwind readnone ssp {
+  %div = fdiv float %x, 0x47E0000000000000
+  ret float %div
+
+; CHECK: @test2
+; CHECK-NEXT: fmul float %x, 0x3800000000000000
+}
+
+define float @test3(float %x) nounwind readnone ssp {
+  %div = fdiv float %x, 0x36A0000000000000
+  ret float %div
+
+; CHECK: @test3
+; CHECK-NEXT: fdiv float %x, 0x36A0000000000000
+}
+



   Commit: e2a69d0eb7bc34a37e0862383c5a435caf52978e
   Author: Benjamin Kramer <benny.kra@googlemail.com>
     Date: 03/30/2011 13:02:54
      URL: https://github.com/mono/llvm/commit/e2a69d0eb7bc34a37e0862383c5a435caf52978e


Avoid turning a floating point division with a constant power of two into a denormal \
multiplication.

Some platforms may treat denormals as zero, on other platforms multiplication
with a subnormal is slower than dividing by a normal.

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

Changed paths:
 M lib/Support/APFloat.cpp
 M test/Transforms/InstCombine/fdiv.ll
 M unittests/ADT/APFloatTest.cpp

Modified: lib/Support/APFloat.cpp
===================================================================
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -3583,6 +3583,14 @@ bool APFloat::getExactInverse(APFloat *inv) const {
   if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK)
     return false;
 
+  // Avoid multiplication with a denormal, it is not safe on all platforms and
+  // may be slower than a normal division.
+  if (reciprocal.significandMSB() + 1 < reciprocal.semantics->precision)
+    return false;
+
+  assert(reciprocal.category == fcNormal &&
+         reciprocal.significandLSB() == reciprocal.semantics->precision - 1);
+
   if (inv)
     *inv = reciprocal;
 
Modified: test/Transforms/InstCombine/fdiv.ll
===================================================================
--- a/test/Transforms/InstCombine/fdiv.ll
+++ b/test/Transforms/InstCombine/fdiv.ll
@@ -13,7 +13,7 @@ define float @test2(float %x) nounwind readnone ssp {
   ret float %div
 
 ; CHECK: @test2
-; CHECK-NEXT: fmul float %x, 0x3800000000000000
+; CHECK-NEXT: fdiv float %x, 0x47E0000000000000
 }
 
 define float @test3(float %x) nounwind readnone ssp {
Modified: unittests/ADT/APFloatTest.cpp
===================================================================
--- a/unittests/ADT/APFloatTest.cpp
+++ b/unittests/ADT/APFloatTest.cpp
@@ -589,10 +589,8 @@ TEST(APFloatTest, exactInverse) {
   EXPECT_TRUE(APFloat(1.17549435e-38f).getExactInverse(&inv));
   EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(8.5070592e+37f)));
 
-  // Large float
-  EXPECT_TRUE(APFloat(1.7014118e38f).getExactInverse(&inv));
-  EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(5.8774718e-39f)));
-
+  // Large float, inverse is a denormal.
+  EXPECT_FALSE(APFloat(1.7014118e38f).getExactInverse(0));
   // Zero
   EXPECT_FALSE(APFloat(0.0).getExactInverse(0));
   // Denormalized float


   Commit: e8c6e713ce08d23a591c7ebd35dccf50019a54df
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/30/2011 14:14:04
      URL: https://github.com/mono/llvm/commit/e8c6e713ce08d23a591c7ebd35dccf50019a54df


Teach VirtRegRewriter about the new virtual register numbers. No functional change.

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

Changed paths:
 M lib/CodeGen/VirtRegRewriter.cpp

Modified: lib/CodeGen/VirtRegRewriter.cpp
===================================================================
--- a/lib/CodeGen/VirtRegRewriter.cpp
+++ b/lib/CodeGen/VirtRegRewriter.cpp
@@ -1791,8 +1791,8 @@ bool LocalRewriter::InsertRestores(MachineInstr *MI,
       else
         DEBUG(dbgs() << "Reusing SS#" << SSorRMId);
       DEBUG(dbgs() << " from physreg "
-                   << TRI->getName(InReg) << " for vreg"
-                   << VirtReg <<" instead of reloading into physreg "
+                   << TRI->getName(InReg) << " for " << PrintReg(VirtReg)
+                   <<" instead of reloading into physreg "
                    << TRI->getName(Phys) << '\n');
 
       // Reusing a physreg may resurrect it. But we expect ProcessUses to update
@@ -1807,8 +1807,8 @@ bool LocalRewriter::InsertRestores(MachineInstr *MI,
       else
         DEBUG(dbgs() << "Reusing SS#" << SSorRMId);
       DEBUG(dbgs() << " from physreg "
-                   << TRI->getName(InReg) << " for vreg"
-                   << VirtReg <<" by copying it into physreg "
+                   << TRI->getName(InReg) << " for " << PrintReg(VirtReg)
+                   <<" by copying it into physreg "
                    << TRI->getName(Phys) << '\n');
 
       // If the reloaded / remat value is available in another register,
@@ -2025,7 +2025,8 @@ void LocalRewriter::ProcessUses(MachineInstr &MI, \
AvailableSpills &Spills,  TRI->regsOverlap(MOk.getReg(), PhysReg)) {
             CanReuse = false;
             DEBUG(dbgs() << "Not reusing physreg " << TRI->getName(PhysReg)
-                         << " for vreg" << VirtReg << ": " << MOk << '\n');
+                         << " for " << PrintReg(VirtReg) << ": " << MOk
+                         << '\n');
             break;
           }
         }
@@ -2039,9 +2040,9 @@ void LocalRewriter::ProcessUses(MachineInstr &MI, \
AvailableSpills &Spills,  else
           DEBUG(dbgs() << "Reusing SS#" << ReuseSlot);
         DEBUG(dbgs() << " from physreg "
-              << TRI->getName(PhysReg) << " for vreg"
-              << VirtReg <<" instead of reloading into physreg "
-              << TRI->getName(VRM->getPhys(VirtReg)) << '\n');
+              << TRI->getName(PhysReg) << " for " << PrintReg(VirtReg)
+              << " instead of reloading into "
+              << PrintReg(VRM->getPhys(VirtReg), TRI) << '\n');
         unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
         MI.getOperand(i).setReg(RReg);
         MI.getOperand(i).setSubReg(0);
@@ -2126,7 +2127,7 @@ void LocalRewriter::ProcessUses(MachineInstr &MI, \
AvailableSpills &Spills,  else
           DEBUG(dbgs() << "Reusing SS#" << ReuseSlot);
         DEBUG(dbgs() << " from physreg " << TRI->getName(PhysReg)
-              << " for vreg" << VirtReg
+              << " for " << PrintReg(VirtReg)
               << " instead of reloading into same physreg.\n");
         unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
         MI.getOperand(i).setReg(RReg);
@@ -2315,7 +2316,7 @@ LocalRewriter::RewriteMBB(LiveIntervals *LIs,
     for (unsigned FVI = 0, FVE = FoldedVirts.size(); FVI != FVE; ++FVI) {
       unsigned VirtReg = FoldedVirts[FVI].first;
       VirtRegMap::ModRef MR = FoldedVirts[FVI].second;
-      DEBUG(dbgs() << "Folded vreg: " << VirtReg << "  MR: " << MR);
+      DEBUG(dbgs() << "Folded " << PrintReg(VirtReg) << "  MR: " << MR);
 
       int SS = VRM->getStackSlot(VirtReg);
       if (SS == VirtRegMap::NO_STACK_SLOT)


   Commit: eef1caf4e0f8414ccf41a41ea023c91ef04bbd7b
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/30/2011 14:14:07
      URL: https://github.com/mono/llvm/commit/eef1caf4e0f8414ccf41a41ea023c91ef04bbd7b


Fix evil VirtRegRewriter bug.

The rewriter can keep track of multiple stack slots in the same register if they
happen to have the same value. When an instruction modifies a stack slot by
defining a register that is mapped to a stack slot, other stack slots in that
register are no longer valid.

This is a very rare problem, and I don't have a simple test case. I get the
impression that VirtRegRewriter knows it is about to be deleted, inventing a
last opaque problem.

<rdar://problem/9204040>

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

Changed paths:
 M lib/CodeGen/VirtRegRewriter.cpp

Modified: lib/CodeGen/VirtRegRewriter.cpp
===================================================================
--- a/lib/CodeGen/VirtRegRewriter.cpp
+++ b/lib/CodeGen/VirtRegRewriter.cpp
@@ -261,6 +261,10 @@ public:
   /// now).
   void ModifyStackSlotOrReMat(int SlotOrReMat);
 
+  /// ClobberSharingStackSlots - When a register mapped to a stack slot changes,
+  /// other stack slots sharing the same register are no longer valid.
+  void ClobberSharingStackSlots(int StackSlot);
+
   /// AddAvailableRegsToLiveIn - Availability information is being kept coming
   /// into the specified MBB. Add available physical registers as potential
   /// live-in's. If they are reused in the MBB, they will be added to the
@@ -831,6 +835,26 @@ void AvailableSpills::ModifyStackSlotOrReMat(int SlotOrReMat) {
   PhysRegsAvailable.erase(I);
 }
 
+void AvailableSpills::ClobberSharingStackSlots(int StackSlot) {
+  std::map<int, unsigned>::iterator It =
+    SpillSlotsOrReMatsAvailable.find(StackSlot);
+  if (It == SpillSlotsOrReMatsAvailable.end()) return;
+  unsigned Reg = It->second >> 1;
+
+  // Erase entries in PhysRegsAvailable for other stack slots.
+  std::multimap<unsigned, int>::iterator I = PhysRegsAvailable.lower_bound(Reg);
+  while (I != PhysRegsAvailable.end() && I->first == Reg) {
+    std::multimap<unsigned, int>::iterator NextI = llvm::next(I);
+    if (I->second != StackSlot) {
+      DEBUG(dbgs() << "Clobbered sharing SS#" << I->second << " in "
+                   << PrintReg(Reg, TRI) << '\n');
+      SpillSlotsOrReMatsAvailable.erase(I->second);
+      PhysRegsAvailable.erase(I);
+    }
+    I = NextI;
+  }
+}
+
 // ************************** //
 // Reuse Info Implementation  //
 // ************************** //
@@ -2550,6 +2574,10 @@ LocalRewriter::RewriteMBB(LiveIntervals *LIs,
         }
       }
 
+      // If StackSlot is available in a register that also holds other stack
+      // slots, clobber those stack slots now.
+      Spills.ClobberSharingStackSlots(StackSlot);
+
       assert(PhysReg && "VR not assigned a physical register?");
       MRI->setPhysRegUsed(PhysReg);
       unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;


   Commit: 6363c56ef0e0b68a11b3e98ee45b77dd168c304f
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/30/2011 14:32:41
      URL: https://github.com/mono/llvm/commit/6363c56ef0e0b68a11b3e98ee45b77dd168c304f


Prevent infinite growth of the DenseMap.

When the hash function uses object pointers all free entries eventually
become tombstones as they are used at least once, regardless of the size.

DenseMap cannot function with zero empty keys, so it double size to get
get ridof the tombstones.

However DenseMap never shrinks automatically unless it is cleared, so
the net result is that certain tables grow infinitely.

The solution is to make a fresh copy of the table without tombstones
instead of doubling size, by simply calling grow with the current size.

Patch by José Fonseca!

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

Changed paths:
 M include/llvm/ADT/DenseMap.h

Modified: include/llvm/ADT/DenseMap.h
===================================================================
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -289,11 +289,14 @@ private:
     // table completely filled with tombstones, no lookup would ever succeed,
     // causing infinite loops in lookup.
     ++NumEntries;
-    if (NumEntries*4 >= NumBuckets*3 ||
-        NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {
+    if (NumEntries*4 >= NumBuckets*3) {
       this->grow(NumBuckets * 2);
       LookupBucketFor(Key, TheBucket);
     }
+    if (NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {
+      this->grow(NumBuckets);
+      LookupBucketFor(Key, TheBucket);
+    }
 
     // If we are writing over a tombstone, remember this.
     if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey()))


   Commit: 8f39a20cd45f46913026ad39ecba55a993f09e70
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/30/2011 14:32:44
      URL: https://github.com/mono/llvm/commit/8f39a20cd45f46913026ad39ecba55a993f09e70


Prevent infinite growth of SmallMap instances.

Rehash but don't grow when full of tombstones.

Patch by José Fonseca!

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

Changed paths:
 M include/llvm/ADT/StringMap.h
 M lib/Support/StringMap.cpp

Modified: include/llvm/ADT/StringMap.h
===================================================================
--- a/include/llvm/ADT/StringMap.h
+++ b/include/llvm/ADT/StringMap.h
@@ -81,16 +81,6 @@ protected:
   StringMapImpl(unsigned InitSize, unsigned ItemSize);
   void RehashTable();
 
-  /// ShouldRehash - Return true if the table should be rehashed after a new
-  /// element was recently inserted.
-  bool ShouldRehash() const {
-    // If the hash table is now more than 3/4 full, or if fewer than 1/8 of
-    // the buckets are empty (meaning that many are filled with tombstones),
-    // grow the table.
-    return NumItems*4 > NumBuckets*3 ||
-           NumBuckets-(NumItems+NumTombstones) < NumBuckets/8;
-  }
-
   /// LookupBucketFor - Look up the bucket that the specified string should end
   /// up in.  If it already exists as a key in the map, the Item pointer for the
   /// specified bucket will be non-null.  Otherwise, it will be null.  In either
@@ -340,8 +330,7 @@ public:
     Bucket.Item = KeyValue;
     ++NumItems;
 
-    if (ShouldRehash())
-      RehashTable();
+    RehashTable();
     return true;
   }
 
@@ -383,8 +372,7 @@ public:
     // filled in by LookupBucketFor.
     Bucket.Item = NewItem;
 
-    if (ShouldRehash())
-      RehashTable();
+    RehashTable();
     return *NewItem;
   }
 
Modified: lib/Support/StringMap.cpp
===================================================================
--- a/lib/Support/StringMap.cpp
+++ b/lib/Support/StringMap.cpp
@@ -177,7 +177,19 @@ StringMapEntryBase *StringMapImpl::RemoveKey(StringRef Key) {
 /// RehashTable - Grow the table, redistributing values into the buckets with
 /// the appropriate mod-of-hashtable-size.
 void StringMapImpl::RehashTable() {
-  unsigned NewSize = NumBuckets*2;
+  unsigned NewSize;
+
+  // If the hash table is now more than 3/4 full, or if fewer than 1/8 of
+  // the buckets are empty (meaning that many are filled with tombstones),
+  // grow/rehash the table.
+  if (NumItems*4 > NumBuckets*3) {
+    NewSize = NumBuckets*2;
+  } else if (NumBuckets-(NumItems+NumTombstones) < NumBuckets/8) {
+    NewSize = NumBuckets;
+  } else {
+    return;
+  }
+
   // Allocate one extra bucket which will always be non-empty.  This allows the
   // iterators to stop at end.
   ItemBucket *NewTableArray =(ItemBucket*)calloc(NewSize+1, sizeof(ItemBucket));


   Commit: 28a26b9b7878847b4137b28340f079238e313b63
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/30/2011 14:32:48
      URL: https://github.com/mono/llvm/commit/28a26b9b7878847b4137b28340f079238e313b63


Prevent infinite growth of SmallPtrSet instances.

Rehash but don't grow when full of tombstones.

Patch by José Fonseca!

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

Changed paths:
 M include/llvm/ADT/SmallPtrSet.h
 M lib/Support/SmallPtrSet.cpp

Modified: include/llvm/ADT/SmallPtrSet.h
===================================================================
--- a/include/llvm/ADT/SmallPtrSet.h
+++ b/include/llvm/ADT/SmallPtrSet.h
@@ -133,7 +133,7 @@ private:
   void shrink_and_clear();
 
   /// Grow - Allocate a larger backing store for the buckets and move it over.
-  void Grow();
+  void Grow(unsigned NewSize);
 
   void operator=(const SmallPtrSetImpl &RHS);  // DO NOT IMPLEMENT.
 protected:
Modified: lib/Support/SmallPtrSet.cpp
===================================================================
--- a/lib/Support/SmallPtrSet.cpp
+++ b/lib/Support/SmallPtrSet.cpp
@@ -52,10 +52,14 @@ bool SmallPtrSetImpl::insert_imp(const void * Ptr) {
     // Otherwise, hit the big set case, which will call grow.
   }
   
-  // If more than 3/4 of the array is full, grow.
-  if (NumElements*4 >= CurArraySize*3 ||
-      CurArraySize-(NumElements+NumTombstones) < CurArraySize/8)
-    Grow();
+  if (NumElements*4 >= CurArraySize*3) {
+    // If more than 3/4 of the array is full, grow.
+    Grow(CurArraySize < 64 ? 128 : CurArraySize*2);
+  } else if (CurArraySize-(NumElements+NumTombstones) < CurArraySize/8) {
+    // If fewer of 1/8 of the array is empty (meaning that many are filled with
+    // tombstones), rehash.
+    Grow(CurArraySize);
+  }
   
   // Okay, we know we have space.  Find a hash bucket.
   const void **Bucket = const_cast<const void**>(FindBucketFor(Ptr));
@@ -125,10 +129,9 @@ const void * const *SmallPtrSetImpl::FindBucketFor(const void \
*Ptr) const {  
 /// Grow - Allocate a larger backing store for the buckets and move it over.
 ///
-void SmallPtrSetImpl::Grow() {
+void SmallPtrSetImpl::Grow(unsigned NewSize) {
   // Allocate at twice as many buckets, but at least 128.
   unsigned OldSize = CurArraySize;
-  unsigned NewSize = OldSize < 64 ? 128 : OldSize*2;
   
   const void **OldBuckets = CurArray;
   bool WasSmall = isSmall();


   Commit: 471ce1e7588862da7b2e3a9b61be81219f4425f6
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/30/2011 14:32:51
      URL: https://github.com/mono/llvm/commit/471ce1e7588862da7b2e3a9b61be81219f4425f6


Reset StringMap's NumTombstones on clears and rehashes.

StringMap was not properly updating NumTombstones after a clear or rehash.

This was not fatal until now because the table was growing faster than
NumTombstones could, but with the previous change of preventing infinite
growth of the table the invariant (NumItems + NumTombstones <= NumBuckets)
stopped being observed, causing infinite loops in certain situations.

Patch by José Fonseca!

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

Changed paths:
 M include/llvm/ADT/StringMap.h
 M lib/Support/StringMap.cpp

Modified: include/llvm/ADT/StringMap.h
===================================================================
--- a/include/llvm/ADT/StringMap.h
+++ b/include/llvm/ADT/StringMap.h
@@ -329,6 +329,7 @@ public:
       --NumTombstones;
     Bucket.Item = KeyValue;
     ++NumItems;
+    assert(NumItems + NumTombstones <= NumBuckets);
 
     RehashTable();
     return true;
@@ -348,6 +349,7 @@ public:
     }
 
     NumItems = 0;
+    NumTombstones = 0;
   }
 
   /// GetOrCreateValue - Look up the specified key in the table.  If a value
@@ -367,6 +369,7 @@ public:
     if (Bucket.Item == getTombstoneVal())
       --NumTombstones;
     ++NumItems;
+    assert(NumItems + NumTombstones <= NumBuckets);
 
     // Fill in the bucket for the hash table.  The FullHashValue was already
     // filled in by LookupBucketFor.
Modified: lib/Support/StringMap.cpp
===================================================================
--- a/lib/Support/StringMap.cpp
+++ b/lib/Support/StringMap.cpp
@@ -169,6 +169,8 @@ StringMapEntryBase *StringMapImpl::RemoveKey(StringRef Key) {
   TheTable[Bucket].Item = getTombstoneVal();
   --NumItems;
   ++NumTombstones;
+  assert(NumItems + NumTombstones <= NumBuckets);
+
   return Result;
 }
 
@@ -224,4 +226,5 @@ void StringMapImpl::RehashTable() {
   
   TheTable = NewTableArray;
   NumBuckets = NewSize;
+  NumTombstones = 0;
 }


   Commit: a3f949df05c38f366fed42003ab7157406fb99c6
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/30/2011 14:32:53
      URL: https://github.com/mono/llvm/commit/a3f949df05c38f366fed42003ab7157406fb99c6


Don't add the same analysis implementation pair twice.

Prevent infinite growth of the list.

Patch by José Fonseca!

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

Changed paths:
 M include/llvm/PassAnalysisSupport.h

Modified: include/llvm/PassAnalysisSupport.h
===================================================================
--- a/include/llvm/PassAnalysisSupport.h
+++ b/include/llvm/PassAnalysisSupport.h
@@ -142,6 +142,8 @@ public:
   Pass *findImplPass(Pass *P, AnalysisID PI, Function &F);
 
   void addAnalysisImplsPair(AnalysisID PI, Pass *P) {
+    if (findImplPass(PI) == P)
+      return;
     std::pair<AnalysisID, Pass*> pir = std::make_pair(PI,P);
     AnalysisImpls.push_back(pir);
   }


   Commit: af294b94e7a51f1be2aff0254f5e03eaa0fa32ff
   Author: Akira Hatanaka <ahatanak@gmail.com>
     Date: 03/30/2011 17:15:35
      URL: https://github.com/mono/llvm/commit/af294b94e7a51f1be2aff0254f5e03eaa0fa32ff


fixed typo

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

Changed paths:
 M lib/Target/Mips/MipsISelLowering.cpp

Modified: lib/Target/Mips/MipsISelLowering.cpp
===================================================================
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -197,7 +197,7 @@ unsigned MipsTargetLowering::getFunctionAlignment(const Function \
*) const {  //  multHi/Lo: product of multiplication
 //  Lo0: initial value of Lo register
 //  Hi0: initial value of Hi register
-// Return true if mattern matching was successful.
+// Return true if pattern matching was successful.
 static bool SelectMadd(SDNode* ADDENode, SelectionDAG* CurDAG) {
   // ADDENode's second operand must be a flag output of an ADDC node in order
   // for the matching to be successful.
@@ -271,7 +271,7 @@ static bool SelectMadd(SDNode* ADDENode, SelectionDAG* CurDAG) {
 //  multHi/Lo: product of multiplication
 //  Lo0: initial value of Lo register
 //  Hi0: initial value of Hi register
-// Return true if mattern matching was successful.
+// Return true if pattern matching was successful.
 static bool SelectMsub(SDNode* SUBENode, SelectionDAG* CurDAG) {
   // SUBENode's second operand must be a flag output of an SUBC node in order
   // for the matching to be successful.


   Commit: e2afd51b1c31e5fce82620dedea67bc36c99903c
   Author: Bill Wendling <isanbard@gmail.com>
     Date: 03/30/2011 17:37:19
      URL: https://github.com/mono/llvm/commit/e2afd51b1c31e5fce82620dedea67bc36c99903c


* The DSE code that tested for overlapping needed to take into account the fact
  that one of the numbers is signed while the other is unsigned. This could lead
  to a wrong result when the signed was promoted to an unsigned int.

* Add the data layout line to the testcase so that it will test the appropriate
  thing.

Patch by David Terei!


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

Changed paths:
 M lib/Transforms/Scalar/DeadStoreElimination.cpp
 M test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll

Modified: lib/Transforms/Scalar/DeadStoreElimination.cpp
===================================================================
--- a/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -361,8 +361,10 @@ static bool isCompleteOverwrite(const AliasAnalysis::Location \
&Later,  //
   //        |--earlier--|
   //    |-----  later  ------|
+  //
+  // We have to be careful here as *Off is signed while *.Size is unsigned.
   if (EarlierOff >= LaterOff &&
-      EarlierOff + Earlier.Size <= LaterOff + Later.Size)
+      uint64_t(EarlierOff - LaterOff) + Earlier.Size <= Later.Size)
     return true;
 
   // Otherwise, they don't completely overlap.
Modified: test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll
===================================================================
--- a/test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll
+++ b/test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll
@@ -1,5 +1,6 @@
 ; RUN: opt < %s -basicaa -dse -S | FileCheck %s
 ; PR9561
+target datalayout = \
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32"
  target triple = "i386-apple-darwin9.8"
 
 @A = external global [0 x i32]


   Commit: 88aa891f31ac05bd1786764c176480c71e208cf1
   Author: Jim Grosbach <grosbach@apple.com>
     Date: 03/30/2011 18:38:13
      URL: https://github.com/mono/llvm/commit/88aa891f31ac05bd1786764c176480c71e208cf1


Tidy up. Whitespace and 80-columns.

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

Changed paths:
 M include/llvm/ExecutionEngine/ExecutionEngine.h
 M include/llvm/ExecutionEngine/JITMemoryManager.h

Modified: include/llvm/ExecutionEngine/ExecutionEngine.h
===================================================================
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -118,11 +118,11 @@ protected:
   /// The list of Modules that we are JIT'ing from.  We use a SmallVector to
   /// optimize for the case where there is only one module.
   SmallVector<Module*, 1> Modules;
-  
+
   void setTargetData(const TargetData *td) {
     TD = td;
   }
-  
+
   /// getMemoryforGV - Allocate memory for a global variable.
   virtual char *getMemoryForGV(const GlobalVariable *GV);
 
@@ -156,7 +156,7 @@ protected:
   /// pointer is invoked to create it.  If this returns null, the JIT will
   /// abort.
   void *(*LazyFunctionCreator)(const std::string &);
-  
+
   /// ExceptionTableRegister - If Exception Handling is set, the JIT will
   /// register dwarf tables with this function.
   typedef void (*EERegisterFn)(void*);
@@ -216,7 +216,7 @@ public:
   virtual void addModule(Module *M) {
     Modules.push_back(M);
   }
-  
+
   //===--------------------------------------------------------------------===//
 
   const TargetData *getTargetData() const { return TD; }
@@ -229,7 +229,7 @@ public:
   /// defines FnName.  This is very slow operation and shouldn't be used for
   /// general code.
   Function *FindFunctionNamed(const char *FnName);
-  
+
   /// runFunction - Execute the specified function with the specified arguments,
   /// and return the result.
   virtual GenericValue runFunction(Function *F,
@@ -246,8 +246,8 @@ public:
   ///
   /// \param isDtors - Run the destructors instead of constructors.
   void runStaticConstructorsDestructors(Module *module, bool isDtors);
-  
-  
+
+
   /// runFunctionAsMain - This is a helper function which wraps runFunction to
   /// handle the common task of starting up main with the specified argc, argv,
   /// and envp parameters.
@@ -262,21 +262,21 @@ public:
   /// existing data in memory.  Mappings are automatically removed when their
   /// GlobalValue is destroyed.
   void addGlobalMapping(const GlobalValue *GV, void *Addr);
-  
+
   /// clearAllGlobalMappings - Clear all global mappings and start over again,
   /// for use in dynamic compilation scenarios to move globals.
   void clearAllGlobalMappings();
-  
+
   /// clearGlobalMappingsFromModule - Clear all global mappings that came from a
   /// particular module, because it has been removed from the JIT.
   void clearGlobalMappingsFromModule(Module *M);
-  
+
   /// updateGlobalMapping - Replace an existing mapping for GV with a new
   /// address.  This updates both maps as required.  If "Addr" is null, the
   /// entry for the global is removed from the mappings.  This returns the old
   /// value of the pointer, or null if it was not in the map.
   void *updateGlobalMapping(const GlobalValue *GV, void *Addr);
-  
+
   /// getPointerToGlobalIfAvailable - This returns the address of the specified
   /// global value if it is has already been codegen'd, otherwise it returns
   /// null.
@@ -297,7 +297,7 @@ public:
   /// different ways.  Return the representation for a blockaddress of the
   /// specified block.
   virtual void *getPointerToBasicBlock(BasicBlock *BB) = 0;
-  
+
   /// getPointerToFunctionOrStub - If the specified function has been
   /// code-gen'd, return a pointer to the function.  If not, compile it, or use
   /// a stub to implement lazy compilation if available.  See
@@ -401,7 +401,7 @@ public:
   void InstallLazyFunctionCreator(void* (*P)(const std::string &)) {
     LazyFunctionCreator = P;
   }
-  
+
   /// InstallExceptionTableRegister - The JIT will use the given function
   /// to register the exception tables it generates.
   void InstallExceptionTableRegister(EERegisterFn F) {
@@ -410,7 +410,7 @@ public:
   void InstallExceptionTableDeregister(EERegisterFn F) {
     ExceptionTableDeregister = F;
   }
-  
+
   /// RegisterTable - Registers the given pointer as an exception table.  It
   /// uses the ExceptionTableRegister function.
   void RegisterTable(const Function *fn, void* res) {
@@ -420,10 +420,12 @@ public:
     }
   }
 
-  /// DeregisterTable - Deregisters the exception frame previously registered for \
the given function. +  /// DeregisterTable - Deregisters the exception frame \
previously registered +  /// for the given function.
   void DeregisterTable(const Function *Fn) {
     if (ExceptionTableDeregister) {
-      DenseMap<const Function*, void*>::iterator frame = \
AllExceptionTables.find(Fn); +      DenseMap<const Function*, void*>::iterator frame \
= +        AllExceptionTables.find(Fn);
       if(frame != AllExceptionTables.end()) {
         ExceptionTableDeregister(frame->second);
         AllExceptionTables.erase(frame);
@@ -443,7 +445,7 @@ protected:
   void EmitGlobalVariable(const GlobalVariable *GV);
 
   GenericValue getConstantValue(const Constant *C);
-  void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr, 
+  void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr,
                            const Type *Ty);
 };
 
Modified: include/llvm/ExecutionEngine/JITMemoryManager.h
===================================================================
--- a/include/llvm/ExecutionEngine/JITMemoryManager.h
+++ b/include/llvm/ExecutionEngine/JITMemoryManager.h
@@ -29,11 +29,11 @@ protected:
 public:
   JITMemoryManager() : HasGOT(false) {}
   virtual ~JITMemoryManager();
-  
+
   /// CreateDefaultMemManager - This is used to create the default
   /// JIT Memory Manager if the client does not provide one to the JIT.
   static JITMemoryManager *CreateDefaultMemManager();
-  
+
   /// setMemoryWritable - When code generation is in progress,
   /// the code pages may need permissions changed.
   virtual void setMemoryWritable() = 0;
@@ -55,16 +55,16 @@ public:
   /// method is invoked to allocate it.  This method is required to set HasGOT
   /// to true.
   virtual void AllocateGOT() = 0;
-  
+
   /// isManagingGOT - Return true if the AllocateGOT method is called.
   bool isManagingGOT() const {
     return HasGOT;
   }
-  
+
   /// getGOTBase - If this is managing a Global Offset Table, this method should
   /// return a pointer to its base.
   virtual uint8_t *getGOTBase() const = 0;
-  
+
   //===--------------------------------------------------------------------===//
   // Main Allocation Functions
   //===--------------------------------------------------------------------===//
@@ -91,11 +91,11 @@ public:
   /// startFunctionBody.
   virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
                                 unsigned Alignment) = 0;
-  
+
   /// endFunctionBody - This method is called when the JIT is done codegen'ing
   /// the specified function.  At this point we know the size of the JIT
   /// compiled function.  This passes in FunctionStart (which was returned by
-  /// the startFunctionBody method) and FunctionEnd which is a pointer to the 
+  /// the startFunctionBody method) and FunctionEnd which is a pointer to the
   /// actual end of the function.  This method should mark the space allocated
   /// and remember where it is in case the client wants to deallocate it.
   virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
@@ -113,12 +113,12 @@ public:
   /// been deallocated yet.  This is never called when the JIT is currently
   /// emitting a function.
   virtual void deallocateFunctionBody(void *Body) = 0;
-  
+
   /// startExceptionTable - When we finished JITing the function, if exception
   /// handling is set, we emit the exception table.
   virtual uint8_t* startExceptionTable(const Function* F,
                                        uintptr_t &ActualSize) = 0;
-  
+
   /// endExceptionTable - This method is called when the JIT is done emitting
   /// the exception table.
   virtual void endExceptionTable(const Function *F, uint8_t *TableStart,


   Commit: d086c5578368e3455af4fec7d318f590def4e106
   Author: Cameron Zwarich <zwarich@apple.com>
     Date: 03/30/2011 19:01:21
      URL: https://github.com/mono/llvm/commit/d086c5578368e3455af4fec7d318f590def4e106


Add a ARM-specific SD node for VBSL so that forms with a constant first operand
can be recognized. This fixes <rdar://problem/9183078>.

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

Changed paths:
 M lib/Target/ARM/ARMFastISel.cpp
 M lib/Target/ARM/ARMISelLowering.cpp
 M lib/Target/ARM/ARMISelLowering.h
 M lib/Target/ARM/ARMInstrNEON.td
Added paths:
 A test/CodeGen/ARM/vbsl-constant.ll

Modified: lib/Target/ARM/ARMFastISel.cpp
===================================================================
--- a/lib/Target/ARM/ARMFastISel.cpp
+++ b/lib/Target/ARM/ARMFastISel.cpp
@@ -115,6 +115,11 @@ class ARMFastISel : public FastISel {
                                      const TargetRegisterClass *RC,
                                      unsigned Op0, bool Op0IsKill,
                                      unsigned Op1, bool Op1IsKill);
+    virtual unsigned FastEmitInst_rrr(unsigned MachineInstOpcode,
+                                      const TargetRegisterClass *RC,
+                                      unsigned Op0, bool Op0IsKill,
+                                      unsigned Op1, bool Op1IsKill,
+                                      unsigned Op2, bool Op2IsKill);
     virtual unsigned FastEmitInst_ri(unsigned MachineInstOpcode,
                                      const TargetRegisterClass *RC,
                                      unsigned Op0, bool Op0IsKill,
@@ -315,6 +320,31 @@ unsigned ARMFastISel::FastEmitInst_rr(unsigned \
MachineInstOpcode,  return ResultReg;
 }
 
+unsigned ARMFastISel::FastEmitInst_rrr(unsigned MachineInstOpcode,
+                                       const TargetRegisterClass *RC,
+                                       unsigned Op0, bool Op0IsKill,
+                                       unsigned Op1, bool Op1IsKill,
+                                       unsigned Op2, bool Op2IsKill) {
+  unsigned ResultReg = createResultReg(RC);
+  const TargetInstrDesc &II = TII.get(MachineInstOpcode);
+
+  if (II.getNumDefs() >= 1)
+    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
+                   .addReg(Op0, Op0IsKill * RegState::Kill)
+                   .addReg(Op1, Op1IsKill * RegState::Kill)
+                   .addReg(Op2, Op2IsKill * RegState::Kill));
+  else {
+    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
+                   .addReg(Op0, Op0IsKill * RegState::Kill)
+                   .addReg(Op1, Op1IsKill * RegState::Kill)
+                   .addReg(Op2, Op2IsKill * RegState::Kill));
+    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
+                           TII.get(TargetOpcode::COPY), ResultReg)
+                   .addReg(II.ImplicitDefs[0]));
+  }
+  return ResultReg;
+}
+
 unsigned ARMFastISel::FastEmitInst_ri(unsigned MachineInstOpcode,
                                       const TargetRegisterClass *RC,
                                       unsigned Op0, bool Op0IsKill,
Modified: lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -866,6 +866,7 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) \
const {  case ARMISD::BFI:           return "ARMISD::BFI";
   case ARMISD::VORRIMM:       return "ARMISD::VORRIMM";
   case ARMISD::VBICIMM:       return "ARMISD::VBICIMM";
+  case ARMISD::VBSL:          return "ARMISD::VBSL";
   case ARMISD::VLD2DUP:       return "ARMISD::VLD2DUP";
   case ARMISD::VLD3DUP:       return "ARMISD::VLD3DUP";
   case ARMISD::VLD4DUP:       return "ARMISD::VLD4DUP";
@@ -5336,6 +5337,37 @@ static SDValue PerformORCombine(SDNode *N,
     }
   }
 
+  SDValue N0 = N->getOperand(0);
+  if (N0.getOpcode() != ISD::AND)
+    return SDValue();
+  SDValue N1 = N->getOperand(1);
+
+  // (or (and B, A), (and C, ~A)) => (VBSL A, B, C) when A is a constant.
+  if (Subtarget->hasNEON() && N1.getOpcode() == ISD::AND && VT.isVector() &&
+      DAG.getTargetLoweringInfo().isTypeLegal(VT)) {
+    APInt SplatUndef;
+    unsigned SplatBitSize;
+    bool HasAnyUndefs;
+
+    BuildVectorSDNode *BVN0 = dyn_cast<BuildVectorSDNode>(N0->getOperand(1));
+    APInt SplatBits0;
+    if (BVN0 && BVN0->isConstantSplat(SplatBits0, SplatUndef, SplatBitSize,
+                                  HasAnyUndefs) && !HasAnyUndefs) {
+      BuildVectorSDNode *BVN1 = dyn_cast<BuildVectorSDNode>(N1->getOperand(1));
+      APInt SplatBits1;
+      if (BVN1 && BVN1->isConstantSplat(SplatBits1, SplatUndef, SplatBitSize,
+                                    HasAnyUndefs) && !HasAnyUndefs &&
+          SplatBits0 == ~SplatBits1) {
+        // Canonicalize the vector type to make instruction selection simpler.
+        EVT CanonicalVT = VT.is128BitVector() ? MVT::v4i32 : MVT::v2i32;
+        SDValue Result = DAG.getNode(ARMISD::VBSL, dl, CanonicalVT,
+                                     N0->getOperand(1), N0->getOperand(0),
+                                     N1->getOperand(1));
+        return DAG.getNode(ISD::BITCAST, dl, VT, Result);
+      }
+    }
+  }
+
   // Try to use the ARM/Thumb2 BFI (bitfield insert) instruction when
   // reasonable.
 
@@ -5343,7 +5375,6 @@ static SDValue PerformORCombine(SDNode *N,
   if (Subtarget->isThumb1Only() || !Subtarget->hasV6T2Ops())
     return SDValue();
 
-  SDValue N0 = N->getOperand(0), N1 = N->getOperand(1);
   DebugLoc DL = N->getDebugLoc();
   // 1) or (and A, mask), val => ARMbfi A, val, mask
   //      iff (val & mask) == val
@@ -5354,8 +5385,6 @@ static SDValue PerformORCombine(SDNode *N,
   //  2b) iff isBitFieldInvertedMask(~mask) && isBitFieldInvertedMask(mask2)
   //          && ~mask == mask2
   //  (i.e., copy a bitfield value into another bitfield of the same width)
-  if (N0.getOpcode() != ISD::AND)
-    return SDValue();
 
   if (VT != MVT::i32)
     return SDValue();
Modified: lib/Target/ARM/ARMISelLowering.h
===================================================================
--- a/lib/Target/ARM/ARMISelLowering.h
+++ b/lib/Target/ARM/ARMISelLowering.h
@@ -179,6 +179,9 @@ namespace llvm {
       // Vector AND with NOT of immediate
       VBICIMM,
 
+      // Vector bitwise select
+      VBSL,
+
       // Vector load N-element structure to all lanes:
       VLD2DUP = ISD::FIRST_TARGET_MEMORY_OPCODE,
       VLD3DUP,
Modified: lib/Target/ARM/ARMInstrNEON.td
===================================================================
--- a/lib/Target/ARM/ARMInstrNEON.td
+++ b/lib/Target/ARM/ARMInstrNEON.td
@@ -80,6 +80,12 @@ def SDTARMVORRIMM : SDTypeProfile<1, 2, [SDTCisVec<0>, \
SDTCisSameAs<0, 1>,  def NEONvorrImm   : SDNode<"ARMISD::VORRIMM", SDTARMVORRIMM>;
 def NEONvbicImm   : SDNode<"ARMISD::VBICIMM", SDTARMVORRIMM>;
 
+def NEONvbsl      : SDNode<"ARMISD::VBSL",
+                           SDTypeProfile<1, 3, [SDTCisVec<0>,
+                                                SDTCisSameAs<0, 1>,
+                                                SDTCisSameAs<0, 2>,
+                                                SDTCisSameAs<0, 3>]>>;
+
 def NEONvdup      : SDNode<"ARMISD::VDUP", SDTypeProfile<1, 1, [SDTCisVec<0>]>>;
 
 // VDUPLANE can produce a quad-register result from a double-register source,
@@ -3767,16 +3773,21 @@ def  VBSLd    : N3VX<1, 0, 0b01, 0b0001, 0, 1, (outs \
DPR:$Vd),  (ins DPR:$src1, DPR:$Vn, DPR:$Vm),
                      N3RegFrm, IIC_VCNTiD,
                      "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd",
-                     [(set DPR:$Vd,
-                       (v2i32 (or (and DPR:$Vn, DPR:$src1),
-                                  (and DPR:$Vm, (vnotd DPR:$src1)))))]>;
+                     [(set DPR:$Vd, (v2i32 (NEONvbsl DPR:$src1, DPR:$Vn, \
DPR:$Vm)))]>; +
+def : Pat<(v2i32 (or (and DPR:$Vn, DPR:$Vd),
+                     (and DPR:$Vm, (vnotd DPR:$Vd)))),
+          (VBSLd DPR:$Vd, DPR:$Vn, DPR:$Vm)>;
+
 def  VBSLq    : N3VX<1, 0, 0b01, 0b0001, 1, 1, (outs QPR:$Vd),
                      (ins QPR:$src1, QPR:$Vn, QPR:$Vm),
                      N3RegFrm, IIC_VCNTiQ,
                      "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd",
-                     [(set QPR:$Vd,
-                       (v4i32 (or (and QPR:$Vn, QPR:$src1),
-                                  (and QPR:$Vm, (vnotq QPR:$src1)))))]>;
+                     [(set QPR:$Vd, (v4i32 (NEONvbsl QPR:$src1, QPR:$Vn, \
QPR:$Vm)))]>; +
+def : Pat<(v4i32 (or (and QPR:$Vn, QPR:$Vd),
+                     (and QPR:$Vm, (vnotq QPR:$Vd)))),
+          (VBSLq QPR:$Vd, QPR:$Vn, QPR:$Vm)>;
 
 //   VBIF     : Vector Bitwise Insert if False
 //              like VBSL but with: "vbif $dst, $src3, $src1", "$src2 = $dst",

Added: test/CodeGen/ARM/vbsl-constant.ll
===================================================================
--- /dev/null
+++ b/test/CodeGen/ARM/vbsl-constant.ll
@@ -0,0 +1,98 @@
+; RUN: llc < %s -march=arm -mattr=+neon | FileCheck %s
+
+define <8 x i8> @v_bsli8(<8 x i8>* %A, <8 x i8>* %B, <8 x i8>* %C) nounwind {
+;CHECK: v_bsli8:
+;CHECK: vbsl
+	%tmp1 = load <8 x i8>* %A
+	%tmp2 = load <8 x i8>* %B
+	%tmp3 = load <8 x i8>* %C
+	%tmp4 = and <8 x i8> %tmp1, <i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3>
+	%tmp6 = and <8 x i8> %tmp3, <i8 -4, i8 -4, i8 -4, i8 -4, i8 -4, i8 -4, i8 -4, i8 \
-4> +	%tmp7 = or <8 x i8> %tmp4, %tmp6
+	ret <8 x i8> %tmp7
+}
+
+define <4 x i16> @v_bsli16(<4 x i16>* %A, <4 x i16>* %B, <4 x i16>* %C) nounwind {
+;CHECK: v_bsli16:
+;CHECK: vbsl
+	%tmp1 = load <4 x i16>* %A
+	%tmp2 = load <4 x i16>* %B
+	%tmp3 = load <4 x i16>* %C
+	%tmp4 = and <4 x i16> %tmp1, <i16 3, i16 3, i16 3, i16 3>
+	%tmp6 = and <4 x i16> %tmp3, <i16 -4, i16 -4, i16 -4, i16 -4>
+	%tmp7 = or <4 x i16> %tmp4, %tmp6
+	ret <4 x i16> %tmp7
+}
+
+define <2 x i32> @v_bsli32(<2 x i32>* %A, <2 x i32>* %B, <2 x i32>* %C) nounwind {
+;CHECK: v_bsli32:
+;CHECK: vbsl
+	%tmp1 = load <2 x i32>* %A
+	%tmp2 = load <2 x i32>* %B
+	%tmp3 = load <2 x i32>* %C
+	%tmp4 = and <2 x i32> %tmp1, <i32 3, i32 3>
+	%tmp6 = and <2 x i32> %tmp3, <i32 -4, i32 -4>
+	%tmp7 = or <2 x i32> %tmp4, %tmp6
+	ret <2 x i32> %tmp7
+}
+
+define <1 x i64> @v_bsli64(<1 x i64>* %A, <1 x i64>* %B, <1 x i64>* %C) nounwind {
+;CHECK: v_bsli64:
+;CHECK: vbsl
+	%tmp1 = load <1 x i64>* %A
+	%tmp2 = load <1 x i64>* %B
+	%tmp3 = load <1 x i64>* %C
+	%tmp4 = and <1 x i64> %tmp1, <i64 3>
+	%tmp6 = and <1 x i64> %tmp3, <i64 -4>
+	%tmp7 = or <1 x i64> %tmp4, %tmp6
+	ret <1 x i64> %tmp7
+}
+
+define <16 x i8> @v_bslQi8(<16 x i8>* %A, <16 x i8>* %B, <16 x i8>* %C) nounwind {
+;CHECK: v_bslQi8:
+;CHECK: vbsl
+	%tmp1 = load <16 x i8>* %A
+	%tmp2 = load <16 x i8>* %B
+	%tmp3 = load <16 x i8>* %C
+	%tmp4 = and <16 x i8> %tmp1, <i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, \
i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3> +	%tmp6 = and <16 x i8> %tmp3, <i8 -4, i8 \
-4, i8 -4, i8 -4, i8 -4, i8 -4, i8 -4, i8 -4, i8 -4, i8 -4, i8 -4, i8 -4, i8 -4, i8 \
-4, i8 -4, i8 -4> +	%tmp7 = or <16 x i8> %tmp4, %tmp6
+	ret <16 x i8> %tmp7
+}
+
+define <8 x i16> @v_bslQi16(<8 x i16>* %A, <8 x i16>* %B, <8 x i16>* %C) nounwind {
+;CHECK: v_bslQi16:
+;CHECK: vbsl
+	%tmp1 = load <8 x i16>* %A
+	%tmp2 = load <8 x i16>* %B
+	%tmp3 = load <8 x i16>* %C
+	%tmp4 = and <8 x i16> %tmp1, <i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 \
3> +	%tmp6 = and <8 x i16> %tmp3, <i16 -4, i16 -4, i16 -4, i16 -4, i16 -4, i16 -4, \
i16 -4, i16 -4> +	%tmp7 = or <8 x i16> %tmp4, %tmp6
+	ret <8 x i16> %tmp7
+}
+
+define <4 x i32> @v_bslQi32(<4 x i32>* %A, <4 x i32>* %B, <4 x i32>* %C) nounwind {
+;CHECK: v_bslQi32:
+;CHECK: vbsl
+	%tmp1 = load <4 x i32>* %A
+	%tmp2 = load <4 x i32>* %B
+	%tmp3 = load <4 x i32>* %C
+	%tmp4 = and <4 x i32> %tmp1, <i32 3, i32 3, i32 3, i32 3>
+	%tmp6 = and <4 x i32> %tmp3, <i32 -4, i32 -4, i32 -4, i32 -4>
+	%tmp7 = or <4 x i32> %tmp4, %tmp6
+	ret <4 x i32> %tmp7
+}
+
+define <2 x i64> @v_bslQi64(<2 x i64>* %A, <2 x i64>* %B, <2 x i64>* %C) nounwind {
+;CHECK: v_bslQi64:
+;CHECK: vbsl
+	%tmp1 = load <2 x i64>* %A
+	%tmp2 = load <2 x i64>* %B
+	%tmp3 = load <2 x i64>* %C
+	%tmp4 = and <2 x i64> %tmp1, <i64 3, i64 3>
+	%tmp6 = and <2 x i64> %tmp3, <i64 -4, i64 -4>
+	%tmp7 = or <2 x i64> %tmp4, %tmp6
+	ret <2 x i64> %tmp7
+}
+



   Commit: 0f61396007b28ee02e1bf1a43ea76ca6e6c1d5aa
   Author: Bruno Cardoso Lopes <bruno.cardoso@gmail.com>
     Date: 03/30/2011 19:32:32
      URL: https://github.com/mono/llvm/commit/0f61396007b28ee02e1bf1a43ea76ca6e6c1d5aa


- Implement asm parsing support for LDRT, LDRBT, STRT, STRBT and
  {STR,LDC}{2}_PRE.
- Fixed the encoding in some places.
- Some of those instructions were using am2offset and now use addrmode2.
Codegen isn't affected, instructions which use SelectAddrMode2Offset were not
touched.
- Teach printAddrMode2Operand to check by the addressing mode which index
mode to print.
- This is a work in progress, more work to come. The idea is to change places
which use am2offset to use addrmode2 instead, as to unify assembly parser.
- Add testcases for assembly parser

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

Changed paths:
 M lib/Target/ARM/ARMBaseInfo.h
 M lib/Target/ARM/ARMBaseInstrInfo.h
 M lib/Target/ARM/ARMInstrFormats.td
 M lib/Target/ARM/ARMInstrInfo.td
 M lib/Target/ARM/AsmParser/ARMAsmParser.cpp
 M lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
 M lib/Target/ARM/InstPrinter/ARMInstPrinter.h
Added paths:
 A test/MC/ARM/arm_addrmode2.s

Modified: lib/Target/ARM/ARMBaseInfo.h
===================================================================
--- a/lib/Target/ARM/ARMBaseInfo.h
+++ b/lib/Target/ARM/ARMBaseInfo.h
@@ -200,6 +200,51 @@ inline static unsigned getARMRegisterNumbering(unsigned Reg) {
 }
 
 namespace ARMII {
+
+  /// ARM Addressing Modes
+  enum AddrMode {
+    AddrModeNone    = 0,
+    AddrMode1       = 1,
+    AddrMode2       = 2,
+    AddrMode3       = 3,
+    AddrMode4       = 4,
+    AddrMode5       = 5,
+    AddrMode6       = 6,
+    AddrModeT1_1    = 7,
+    AddrModeT1_2    = 8,
+    AddrModeT1_4    = 9,
+    AddrModeT1_s    = 10, // i8 * 4 for pc and sp relative data
+    AddrModeT2_i12  = 11,
+    AddrModeT2_i8   = 12,
+    AddrModeT2_so   = 13,
+    AddrModeT2_pc   = 14, // +/- i12 for pc relative data
+    AddrModeT2_i8s4 = 15, // i8 * 4
+    AddrMode_i12    = 16
+  };
+
+  inline static const char *AddrModeToString(AddrMode addrmode) {
+    switch (addrmode) {
+    default: llvm_unreachable("Unknown memory operation");
+    case AddrModeNone:    return "AddrModeNone";
+    case AddrMode1:       return "AddrMode1";
+    case AddrMode2:       return "AddrMode2";
+    case AddrMode3:       return "AddrMode3";
+    case AddrMode4:       return "AddrMode4";
+    case AddrMode5:       return "AddrMode5";
+    case AddrMode6:       return "AddrMode6";
+    case AddrModeT1_1:    return "AddrModeT1_1";
+    case AddrModeT1_2:    return "AddrModeT1_2";
+    case AddrModeT1_4:    return "AddrModeT1_4";
+    case AddrModeT1_s:    return "AddrModeT1_s";
+    case AddrModeT2_i12:  return "AddrModeT2_i12";
+    case AddrModeT2_i8:   return "AddrModeT2_i8";
+    case AddrModeT2_so:   return "AddrModeT2_so";
+    case AddrModeT2_pc:   return "AddrModeT2_pc";
+    case AddrModeT2_i8s4: return "AddrModeT2_i8s4";
+    case AddrMode_i12:    return "AddrMode_i12";
+    }
+  }
+
   /// Target Operand Flag enum.
   enum TOF {
     //===------------------------------------------------------------------===//
Modified: lib/Target/ARM/ARMBaseInstrInfo.h
===================================================================
--- a/lib/Target/ARM/ARMBaseInstrInfo.h
+++ b/lib/Target/ARM/ARMBaseInstrInfo.h
@@ -34,25 +34,7 @@ namespace ARMII {
 
     //===------------------------------------------------------------------===//
     // This four-bit field describes the addressing mode used.
-
-    AddrModeMask  = 0x1f,
-    AddrModeNone    = 0,
-    AddrMode1       = 1,
-    AddrMode2       = 2,
-    AddrMode3       = 3,
-    AddrMode4       = 4,
-    AddrMode5       = 5,
-    AddrMode6       = 6,
-    AddrModeT1_1    = 7,
-    AddrModeT1_2    = 8,
-    AddrModeT1_4    = 9,
-    AddrModeT1_s    = 10, // i8 * 4 for pc and sp relative data
-    AddrModeT2_i12  = 11,
-    AddrModeT2_i8   = 12,
-    AddrModeT2_so   = 13,
-    AddrModeT2_pc   = 14, // +/- i12 for pc relative data
-    AddrModeT2_i8s4 = 15, // i8 * 4
-    AddrMode_i12    = 16,
+    AddrModeMask  = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h
 
     // Size* - Flags to keep track of the size of an instruction.
     SizeShift     = 5,
Modified: lib/Target/ARM/ARMInstrFormats.td
===================================================================
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -515,15 +515,15 @@ class AI2stridx<bit isByte, bit isPre, dag oops, dag iops,
   : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
                pattern> {
   // AM2 store w/ two operands: (GPR, am2offset)
+  // {17-14}  Rn
   // {13}     1 == Rm, 0 == imm12
   // {12}     isAdd
   // {11-0}   imm12/Rm
-  bits<14> offset;
-  bits<4> Rn;
-  let Inst{25} = offset{13};
-  let Inst{23} = offset{12};
-  let Inst{19-16} = Rn;
-  let Inst{11-0} = offset{11-0};
+  bits<18> addr;
+  let Inst{25} = addr{13};
+  let Inst{23} = addr{12};
+  let Inst{19-16} = addr{17-14};
+  let Inst{11-0} = addr{11-0};
 }
 
 // addrmode3 instructions
Modified: lib/Target/ARM/ARMInstrInfo.td
===================================================================
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -498,6 +498,12 @@ def ldst_so_reg : Operand<i32>,
   let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
 }
 
+def MemMode2AsmOperand : AsmOperandClass {
+  let Name = "MemMode2";
+  let SuperClasses = [];
+  let ParserMethod = "tryParseMemMode2Operand";
+}
+
 // addrmode2 := reg +/- imm12
 //           := reg +/- reg shop imm
 //
@@ -505,6 +511,7 @@ def addrmode2 : Operand<i32>,
                 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
   let EncoderMethod = "getAddrMode2OpValue";
   let PrintMethod = "printAddrMode2Operand";
+  let ParserMatchClass = MemMode2AsmOperand;
   let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
 }
 
@@ -1656,6 +1663,7 @@ multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass \
itin> {  let Inst{23} = addr{12};
     let Inst{19-16} = addr{17-14};
     let Inst{11-0} = addr{11-0};
+    let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
   }
   def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
                       (ins GPR:$Rn, am2offset:$offset),
@@ -1714,17 +1722,35 @@ defm LDRD :  AI3_ldridx<0b1101, 0, "ldrd", IIC_iLoad_d_ru>;
 
 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
 let mayLoad = 1, neverHasSideEffects = 1 in {
-def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
-                   (ins GPR:$base, am2offset:$offset), IndexModePost,
-                   LdFrm, IIC_iLoad_ru,
-                   "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
+def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb),
+                   (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_ru,
+                   "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
+  // {17-14}  Rn
+  // {13}     1 == Rm, 0 == imm12
+  // {12}     isAdd
+  // {11-0}   imm12/Rm
+  bits<18> addr;
+  let Inst{25} = addr{13};
+  let Inst{23} = addr{12};
   let Inst{21} = 1; // overwrite
-}
-def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
-                  (ins GPR:$base, am2offset:$offset), IndexModePost,
-                  LdFrm, IIC_iLoad_bh_ru,
-                  "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
+  let Inst{19-16} = addr{17-14};
+  let Inst{11-0} = addr{11-0};
+  let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
+}
+def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb),
+                  (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_bh_ru,
+                  "ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
+  // {17-14}  Rn
+  // {13}     1 == Rm, 0 == imm12
+  // {12}     isAdd
+  // {11-0}   imm12/Rm
+  bits<18> addr;
+  let Inst{25} = addr{13};
+  let Inst{23} = addr{12};
   let Inst{21} = 1; // overwrite
+  let Inst{19-16} = addr{17-14};
+  let Inst{11-0} = addr{11-0};
+  let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
 }
 def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
                  (ins GPR:$base, am3offset:$offset), IndexModePost,
@@ -1818,20 +1844,20 @@ def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
 
 // STRT, STRBT, and STRHT are for disassembly only.
 
-def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb),
-                    (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
+def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr),
                     IndexModePost, StFrm, IIC_iStore_ru,
-                    "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
+                    "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb",
                     [/* For disassembly only; pattern left blank */]> {
   let Inst{21} = 1; // overwrite
+  let AsmMatchConverter = "CvtStWriteBackRegAddrMode2";
 }
 
-def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb),
-                     (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
+def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr),
                      IndexModePost, StFrm, IIC_iStore_bh_ru,
-                     "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
+                     "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb",
                      [/* For disassembly only; pattern left blank */]> {
   let Inst{21} = 1; // overwrite
+  let AsmMatchConverter = "CvtStWriteBackRegAddrMode2";
 }
 
 def STRHT: AI3sthpo<(outs GPR:$base_wb),
@@ -3391,8 +3417,9 @@ def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
   let Inst{23-20} = opc1;
 }
 
-class ACI<dag oops, dag iops, string opc, string asm>
-  : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
+class ACI<dag oops, dag iops, string opc, string asm,
+          IndexMode im = IndexModeNone>
+  : I<oops, iops, AddrModeNone, Size4Bytes, im, BrFrm, NoItinerary,
       opc, asm, "", [/* For disassembly only; pattern left blank */]> {
   let Inst{27-25} = 0b110;
 }
@@ -3411,7 +3438,7 @@ multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
 
   def _PRE : ACI<(outs),
       (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
-      opc, "\tp$cop, cr$CRd, $addr!"> {
+      opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> {
     let Inst{31-28} = op31_28;
     let Inst{24} = 1; // P = 1
     let Inst{21} = 1; // W = 1
@@ -3452,7 +3479,7 @@ multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
 
   def L_PRE : ACI<(outs),
       (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
-      !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
+      !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> {
     let Inst{31-28} = op31_28;
     let Inst{24} = 1; // P = 1
     let Inst{21} = 1; // W = 1
Modified: lib/Target/ARM/AsmParser/ARMAsmParser.cpp
===================================================================
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -48,7 +48,8 @@ class ARMAsmParser : public TargetAsmParser {
   bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
   bool TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
   bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
-  bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
+  bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &,
+                   ARMII::AddrMode AddrMode);
   bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
   bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
   const MCExpr *ApplyPrefixToExpr(const MCExpr *E,
@@ -95,6 +96,14 @@ class ARMAsmParser : public TargetAsmParser {
     SmallVectorImpl<MCParsedAsmOperand*>&);
   OperandMatchResultTy tryParseMSRMaskOperand(
     SmallVectorImpl<MCParsedAsmOperand*>&);
+  OperandMatchResultTy tryParseMemMode2Operand(
+    SmallVectorImpl<MCParsedAsmOperand*>&);
+
+  // Asm Match Converter Methods
+  bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
+                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
+  bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
+                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
 
 public:
   ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM)
@@ -172,6 +181,7 @@ class ARMOperand : public MCParsedAsmOperand {
 
     /// Combined record for all forms of ARM address expressions.
     struct {
+      ARMII::AddrMode AddrMode;
       unsigned BaseRegNum;
       union {
         unsigned RegNum;     ///< Offset register num, when OffsetIsReg.
@@ -293,7 +303,9 @@ public:
 
   /// @name Memory Operand Accessors
   /// @{
-
+  ARMII::AddrMode getMemAddrMode() const {
+    return Mem.AddrMode;
+  }
   unsigned getMemBaseRegNum() const {
     return Mem.BaseRegNum;
   }
@@ -338,6 +350,27 @@ public:
   bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
   bool isMemory() const { return Kind == Memory; }
   bool isShifter() const { return Kind == Shifter; }
+  bool isMemMode2() const {
+    if (getMemAddrMode() != ARMII::AddrMode2)
+      return false;
+
+    if (getMemOffsetIsReg())
+      return true;
+
+    if (getMemNegative() &&
+        !(getMemPostindexed() || getMemPreindexed()))
+      return false;
+
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
+    if (!CE) return false;
+    int64_t Value = CE->getValue();
+
+    // The offset must be in the range 0-4095 (imm12).
+    if (Value > 4095 || Value < -4095)
+      return false;
+
+    return true;
+  }
   bool isMemMode5() const {
     if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() ||
         getMemNegative())
@@ -465,6 +498,46 @@ public:
            "No offset operand support in mode 7");
   }
 
+  void addMemMode2Operands(MCInst &Inst, unsigned N) const {
+    assert(isMemMode2() && "Invalid mode or number of operands!");
+    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
+
+    if (getMemOffsetIsReg()) {
+      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
+
+      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
+      ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift;
+      int64_t ShiftAmount = 0;
+
+      if (getMemOffsetRegShifted()) {
+        ShOpc = getMemShiftType();
+        const MCConstantExpr *CE =
+                   dyn_cast<MCConstantExpr>(getMemShiftAmount());
+        ShiftAmount = CE->getValue();
+      }
+
+      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount,
+                                           ShOpc)));
+      return;
+    }
+
+    // Create a operand placeholder to always yield the same number of operands.
+    Inst.addOperand(MCOperand::CreateReg(0));
+
+    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
+    // the difference?
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
+    assert(CE && "Non-constant mode 2 offset operand!");
+    int64_t Offset = CE->getValue();
+
+    if (Offset >= 0)
+      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add,
+                                           Offset, ARM_AM::no_shift)));
+    else
+      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub,
+                                           -Offset, ARM_AM::no_shift)));
+  }
+
   void addMemMode5Operands(MCInst &Inst, unsigned N) const {
     assert(N == 2 && isMemMode5() && "Invalid number of operands!");
 
@@ -599,9 +672,9 @@ public:
     return Op;
   }
 
-  static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg,
-                               const MCExpr *Offset, int OffsetRegNum,
-                               bool OffsetRegShifted,
+  static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum,
+                               bool OffsetIsReg, const MCExpr *Offset,
+                               int OffsetRegNum, bool OffsetRegShifted,
                                enum ARM_AM::ShiftOpc ShiftType,
                                const MCExpr *ShiftAmount, bool Preindexed,
                                bool Postindexed, bool Negative, bool Writeback,
@@ -618,6 +691,7 @@ public:
            "Cannot have expression offset and register offset!");
 
     ARMOperand *Op = new ARMOperand(Memory);
+    Op->Mem.AddrMode = AddrMode;
     Op->Mem.BaseRegNum = BaseRegNum;
     Op->Mem.OffsetIsReg = OffsetIsReg;
     if (OffsetIsReg)
@@ -689,7 +763,8 @@ void ARMOperand::dump(raw_ostream &OS) const {
     break;
   case Memory:
     OS << "<memory "
-       << "base:" << getMemBaseRegNum();
+       << "am:" << ARMII::AddrModeToString(getMemAddrMode())
+       << " base:" << getMemBaseRegNum();
     if (getMemOffsetIsReg()) {
       OS << " offset:<register " << getMemOffsetRegNum();
       if (getMemOffsetRegShifted()) {
@@ -1132,13 +1207,57 @@ tryParseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> \
&Operands) {  return MatchOperand_Success;
 }
 
+/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand.
+ARMAsmParser::OperandMatchResultTy ARMAsmParser::
+tryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+  SMLoc S = Parser.getTok().getLoc();
+  const AsmToken &Tok = Parser.getTok();
+  assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\"");
+
+  if (ParseMemory(Operands, ARMII::AddrMode2))
+    return MatchOperand_NoMatch;
+
+  return MatchOperand_Success;
+}
+
+/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
+/// Needed here because the Asm Gen Matcher can't handle properly tied operands
+/// when they refer multiple MIOperands inside a single one.
+bool ARMAsmParser::
+CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
+                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
+
+  // Create a writeback register dummy placeholder.
+  Inst.addOperand(MCOperand::CreateImm(0));
+
+  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
+  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
+  return true;
+}
+
+/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
+/// Needed here because the Asm Gen Matcher can't handle properly tied operands
+/// when they refer multiple MIOperands inside a single one.
+bool ARMAsmParser::
+CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
+                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+  // Create a writeback register dummy placeholder.
+  Inst.addOperand(MCOperand::CreateImm(0));
+  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
+  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
+  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
+  return true;
+}
+
 /// Parse an ARM memory expression, return false if successful else return true
 /// or an error.  The first token must be a '[' when called.
 ///
 /// TODO Only preindexing and postindexing addressing are started, unindexed
 /// with option, etc are still to do.
 bool ARMAsmParser::
-ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+            ARMII::AddrMode AddrMode = ARMII::AddrModeNone) {
   SMLoc S, E;
   assert(Parser.getTok().is(AsmToken::LBrac) &&
          "Token is not a Left Bracket");
@@ -1231,11 +1350,10 @@ ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
       Offset = MCConstantExpr::Create(0, getContext());
   }
 
-  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset,
-                                           OffsetRegNum, OffsetRegShifted,
-                                           ShiftType, ShiftAmount, Preindexed,
-                                           Postindexed, Negative, Writeback,
-                                           S, E));
+  Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg,
+                                     Offset, OffsetRegNum, OffsetRegShifted,
+                                     ShiftType, ShiftAmount, Preindexed,
+                                     Postindexed, Negative, Writeback, S, E));
   if (WBOp)
     Operands.push_back(WBOp);
 
Modified: lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
===================================================================
--- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
+++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
@@ -14,6 +14,7 @@
 #define DEBUG_TYPE "asm-printer"
 #include "ARMBaseInfo.h"
 #include "ARMInstPrinter.h"
+#include "ARMInstrInfo.h"
 #include "ARMAddressingModes.h"
 #include "llvm/MC/MCInst.h"
 #include "llvm/MC/MCAsmInfo.h"
@@ -181,18 +182,12 @@ void ARMInstPrinter::printSORegOperand(const MCInst *MI, \
unsigned OpNum,  }
 }
 
-
-void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
-                                           raw_ostream &O) {
+void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
+                                                raw_ostream &O) {
   const MCOperand &MO1 = MI->getOperand(Op);
   const MCOperand &MO2 = MI->getOperand(Op+1);
   const MCOperand &MO3 = MI->getOperand(Op+2);
 
-  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
-    printOperand(MI, Op, O);
-    return;
-  }
-
   O << "[" << getRegisterName(MO1.getReg());
 
   if (!MO2.getReg()) {
@@ -215,6 +210,52 @@ void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, \
unsigned Op,  O << "]";
 }
 
+void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op,
+                                         raw_ostream &O) {
+  const MCOperand &MO1 = MI->getOperand(Op);
+  const MCOperand &MO2 = MI->getOperand(Op+1);
+  const MCOperand &MO3 = MI->getOperand(Op+2);
+
+  O << "[" << getRegisterName(MO1.getReg()) << "], ";
+
+  if (!MO2.getReg()) {
+    unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm());
+    O << '#'
+      << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
+      << ImmOffs;
+    return;
+  }
+
+  O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
+    << getRegisterName(MO2.getReg());
+
+  if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
+    O << ", "
+    << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
+    << " #" << ShImm;
+}
+
+void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
+                                           raw_ostream &O) {
+  const MCOperand &MO1 = MI->getOperand(Op);
+
+  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
+    printOperand(MI, Op, O);
+    return;
+  }
+
+  unsigned Opcode = MI->getOpcode();
+  const TargetInstrDesc &Desc = TM.getInstrInfo()->get(Opcode);
+  uint64_t TSFlags = Desc.TSFlags;
+  unsigned IdxMode = (TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
+
+  if (IdxMode == ARMII::IndexModePost) {
+    printAM2PostIndexOp(MI, Op, O);
+    return;
+  }
+  printAM2PreOrOffsetIndexOp(MI, Op, O);
+}
+
 void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
                                                  unsigned OpNum,
                                                  raw_ostream &O) {
Modified: lib/Target/ARM/InstPrinter/ARMInstPrinter.h
===================================================================
--- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
+++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
@@ -22,9 +22,11 @@ class MCOperand;
 class TargetMachine;
 
 class ARMInstPrinter : public MCInstPrinter {
+private:
+  TargetMachine &TM;
 public:
-  ARMInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI)
-    : MCInstPrinter(MAI) {}
+  ARMInstPrinter(TargetMachine &_TM, const MCAsmInfo &MAI)
+    : MCInstPrinter(MAI), TM(_TM) {}
 
   virtual void printInst(const MCInst *MI, raw_ostream &O);
   virtual StringRef getOpcodeName(unsigned Opcode) const;
@@ -42,7 +44,11 @@ public:
   void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
 
   void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+
   void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+  void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+  void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum,
+                                  raw_ostream &O);
   void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum,
                                    raw_ostream &O);
   void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);

Added: test/MC/ARM/arm_addrmode2.s
===================================================================
--- /dev/null
+++ b/test/MC/ARM/arm_addrmode2.s
@@ -0,0 +1,35 @@
+@ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding %s | \
FileCheck %s +
+@ Post-indexed
+@ CHECK: ldrt  r1, [r0], r2 @ encoding: [0x02,0x10,0xb0,0xe6]
+@ CHECK: ldrt  r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xb0,0xe6]
+@ CHECK: ldrt  r1, [r0], #4 @ encoding: [0x04,0x10,0xb0,0xe4]
+@ CHECK: ldrbt  r1, [r0], r2 @ encoding: [0x02,0x10,0xf0,0xe6]
+@ CHECK: ldrbt  r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xf0,0xe6]
+@ CHECK: ldrbt  r1, [r0], #4 @ encoding: [0x04,0x10,0xf0,0xe4]
+@ CHECK: strt  r1, [r0], r2 @ encoding: [0x02,0x10,0xa0,0xe6]
+@ CHECK: strt  r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xa0,0xe6]
+@ CHECK: strt  r1, [r0], #4 @ encoding: [0x04,0x10,0xa0,0xe4]
+@ CHECK: strbt  r1, [r0], r2 @ encoding: [0x02,0x10,0xe0,0xe6]
+@ CHECK: strbt  r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xe0,0xe6]
+@ CHECK: strbt  r1, [r0], #4 @ encoding: [0x04,0x10,0xe0,0xe4]
+        ldrt  r1, [r0], r2
+        ldrt  r1, [r0], r2, lsr #3
+        ldrt  r1, [r0], #4
+        ldrbt  r1, [r0], r2
+        ldrbt  r1, [r0], r2, lsr #3
+        ldrbt  r1, [r0], #4
+        strt  r1, [r0], r2
+        strt  r1, [r0], r2, lsr #3
+        strt  r1, [r0], #4
+        strbt  r1, [r0], r2
+        strbt  r1, [r0], r2, lsr #3
+        strbt  r1, [r0], #4
+
+@ Pre-indexed
+@ CHECK: ldr  r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xb0,0xe7]
+@ CHECK: ldrb  r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xf0,0xe7]
+        ldr  r1, [r0, r2, lsr #3]!
+        ldrb  r1, [r0, r2, lsr #3]!
+
+



   Commit: ee58599c54b211fa2ccc6601a94975ef4acb0ebf
   Author: Evan Cheng <evan.cheng@apple.com>
     Date: 03/30/2011 19:44:13
      URL: https://github.com/mono/llvm/commit/ee58599c54b211fa2ccc6601a94975ef4acb0ebf


Don't try to create zero-sized stack objects.

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

Changed paths:
 M lib/Target/ARM/ARMISelLowering.cpp
 M lib/Target/X86/X86ISelLowering.cpp
Added paths:
 A test/CodeGen/X86/2011-03-30-CreateFixedObjCrash.ll

Modified: lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -2391,8 +2391,9 @@ ARMTargetLowering::LowerFormalArguments(SDValue Chain,
           // In case of tail call optimization mark all arguments mutable. Since \
                they
           // could be overwritten by lowering of arguments in case of a tail call.
           if (Flags.isByVal()) {
-            int FI = MFI->CreateFixedObject(Flags.getByValSize(),
-                                            VA.getLocMemOffset(), false);
+            unsigned Bytes = Flags.getByValSize();
+            if (Bytes == 0) Bytes = 1; // Don't create zero-sized stack objects.
+            int FI = MFI->CreateFixedObject(Bytes, VA.getLocMemOffset(), false);
             InVals.push_back(DAG.getFrameIndex(FI, getPointerTy()));
           } else {
             int FI = MFI->CreateFixedObject(VA.getLocVT().getSizeInBits()/8,
Modified: lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -1639,8 +1639,9 @@ X86TargetLowering::LowerMemArgument(SDValue Chain,
   // In case of tail call optimization mark all arguments mutable. Since they
   // could be overwritten by lowering of arguments in case of a tail call.
   if (Flags.isByVal()) {
-    int FI = MFI->CreateFixedObject(Flags.getByValSize(),
-                                    VA.getLocMemOffset(), isImmutable);
+    unsigned Bytes = Flags.getByValSize();
+    if (Bytes == 0) Bytes = 1; // Don't create zero-sized stack objects.
+    int FI = MFI->CreateFixedObject(Bytes, VA.getLocMemOffset(), isImmutable);
     return DAG.getFrameIndex(FI, getPointerTy());
   } else {
     int FI = MFI->CreateFixedObject(ValVT.getSizeInBits()/8,

Added: test/CodeGen/X86/2011-03-30-CreateFixedObjCrash.ll
===================================================================
--- /dev/null
+++ b/test/CodeGen/X86/2011-03-30-CreateFixedObjCrash.ll
@@ -0,0 +1,11 @@
+; RUN: llc < %s -march=x86
+
+; rdar://7983260
+
+%struct.T0 = type {}
+
+define void @fn4(%struct.T0* byval %arg0) nounwind ssp {
+entry:
+  ret void
+}
+



   Commit: 11397167f7764b224d8d16e08e35a87fa3e479ee
   Author: Owen Anderson <resistor@mac.com>
     Date: 03/30/2011 19:45:29
      URL: https://github.com/mono/llvm/commit/11397167f7764b224d8d16e08e35a87fa3e479ee


Somehow we managed to forget to encode the lane index for a large swathe of NEON \
instructions.  With this fix, the entire test-suite passes with the Thumb integrated \
assembler.


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

Changed paths:
 M lib/Target/ARM/ARMInstrFormats.td
 M lib/Target/ARM/ARMInstrNEON.td

Modified: lib/Target/ARM/ARMInstrFormats.td
===================================================================
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -1682,7 +1682,8 @@ class N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit \
op6, bit op4,  }
 
 // NEON 3 vector register format.
-class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
+
+class N3VCommon<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit \
op4,  dag oops, dag iops, Format f, InstrItinClass itin,
           string opc, string dt, string asm, string cstr, list<dag> pattern>
   : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
@@ -1692,6 +1693,13 @@ class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, \
bit op6, bit op4,  let Inst{11-8}  = op11_8;
   let Inst{6}     = op6;
   let Inst{4}     = op4;
+}
+
+class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
+          dag oops, dag iops, Format f, InstrItinClass itin,
+          string opc, string dt, string asm, string cstr, list<dag> pattern>
+  : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
+              oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
 
   // Instruction operands.
   bits<5> Vd;
@@ -1706,6 +1714,47 @@ class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, \
bit op6, bit op4,  let Inst{5}     = Vm{4};
 }
 
+class N3VLane32<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit \
op4, +          dag oops, dag iops, Format f, InstrItinClass itin,
+          string opc, string dt, string asm, string cstr, list<dag> pattern>
+  : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
+              oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
+
+  // Instruction operands.
+  bits<5> Vd;
+  bits<5> Vn;
+  bits<5> Vm;
+  bit lane;
+
+  let Inst{15-12} = Vd{3-0};
+  let Inst{22}    = Vd{4};
+  let Inst{19-16} = Vn{3-0};
+  let Inst{7}     = Vn{4};
+  let Inst{3-0}   = Vm{3-0};
+  let Inst{5}     = lane;
+}
+
+class N3VLane16<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit \
op4, +          dag oops, dag iops, Format f, InstrItinClass itin,
+          string opc, string dt, string asm, string cstr, list<dag> pattern>
+  : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
+              oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
+
+  // Instruction operands.
+  bits<5> Vd;
+  bits<5> Vn;
+  bits<5> Vm;
+  bits<2> lane;
+
+  let Inst{15-12} = Vd{3-0};
+  let Inst{22}    = Vd{4};
+  let Inst{19-16} = Vn{3-0};
+  let Inst{7}     = Vn{4};
+  let Inst{2-0}   = Vm{2-0};
+  let Inst{5}     = lane{1};
+  let Inst{3}     = lane{0};
+}
+
 // Same as N3V except it doesn't have a data type suffix.
 class N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
            bit op4,
Modified: lib/Target/ARM/ARMInstrNEON.td
===================================================================
--- a/lib/Target/ARM/ARMInstrNEON.td
+++ b/lib/Target/ARM/ARMInstrNEON.td
@@ -1799,7 +1799,7 @@ class N3VDX<bit op24, bit op23, bits<2> op21_20, bits<4> \
op11_8, bit op4,  class N3VDSL<bits<2> op21_20, bits<4> op11_8,
              InstrItinClass itin, string OpcodeStr, string Dt,
              ValueType Ty, SDNode ShOp>
-  : N3V<0, 1, op21_20, op11_8, 1, 0,
+  : N3VLane32<0, 1, op21_20, op11_8, 1, 0,
         (outs DPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set (Ty DPR:$Vd),
@@ -1809,7 +1809,7 @@ class N3VDSL<bits<2> op21_20, bits<4> op11_8,
 }
 class N3VDSL16<bits<2> op21_20, bits<4> op11_8,
                string OpcodeStr, string Dt, ValueType Ty, SDNode ShOp>
-  : N3V<0, 1, op21_20, op11_8, 1, 0,
+  : N3VLane16<0, 1, op21_20, op11_8, 1, 0,
         (outs DPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, IIC_VMULi16D, OpcodeStr, Dt,"$Vd, $Vn, $Vm[$lane]","",
         [(set (Ty DPR:$Vd),
@@ -1839,7 +1839,7 @@ class N3VQX<bit op24, bit op23, bits<2> op21_20, bits<4> \
op11_8, bit op4,  class N3VQSL<bits<2> op21_20, bits<4> op11_8,
              InstrItinClass itin, string OpcodeStr, string Dt,
              ValueType ResTy, ValueType OpTy, SDNode ShOp>
-  : N3V<1, 1, op21_20, op11_8, 1, 0,
+  : N3VLane32<1, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd), (ins QPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set (ResTy QPR:$Vd),
@@ -1850,7 +1850,7 @@ class N3VQSL<bits<2> op21_20, bits<4> op11_8,
 }
 class N3VQSL16<bits<2> op21_20, bits<4> op11_8, string OpcodeStr, string Dt,
                ValueType ResTy, ValueType OpTy, SDNode ShOp>
-  : N3V<1, 1, op21_20, op11_8, 1, 0,
+  : N3VLane16<1, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd), (ins QPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, IIC_VMULi16Q, OpcodeStr, Dt,"$Vd, $Vn, $Vm[$lane]","",
         [(set (ResTy QPR:$Vd),
@@ -1872,7 +1872,7 @@ class N3VDInt<bit op24, bit op23, bits<2> op21_20, bits<4> \
op11_8, bit op4,  }
 class N3VDIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
                 string OpcodeStr, string Dt, ValueType Ty, Intrinsic IntOp>
-  : N3V<0, 1, op21_20, op11_8, 1, 0,
+  : N3VLane32<0, 1, op21_20, op11_8, 1, 0,
         (outs DPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set (Ty DPR:$Vd),
@@ -1883,7 +1883,7 @@ class N3VDIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass \
itin,  }
 class N3VDIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
                   string OpcodeStr, string Dt, ValueType Ty, Intrinsic IntOp>
-  : N3V<0, 1, op21_20, op11_8, 1, 0,
+  : N3VLane16<0, 1, op21_20, op11_8, 1, 0,
         (outs DPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set (Ty DPR:$Vd),
@@ -1913,7 +1913,7 @@ class N3VQInt<bit op24, bit op23, bits<2> op21_20, bits<4> \
op11_8, bit op4,  class N3VQIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass \
itin,  string OpcodeStr, string Dt,
                 ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
-  : N3V<1, 1, op21_20, op11_8, 1, 0,
+  : N3VLane32<1, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd), (ins QPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set (ResTy QPR:$Vd),
@@ -1925,7 +1925,7 @@ class N3VQIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass \
itin,  class N3VQIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
                   string OpcodeStr, string Dt,
                   ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
-  : N3V<1, 1, op21_20, op11_8, 1, 0,
+  : N3VLane16<1, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd), (ins QPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set (ResTy QPR:$Vd),
@@ -1957,7 +1957,7 @@ class N3VDMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> \
op11_8, bit op4,  class N3VDMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass \
itin,  string OpcodeStr, string Dt,
                   ValueType Ty, SDPatternOperator MulOp, SDPatternOperator ShOp>
-  : N3V<0, 1, op21_20, op11_8, 1, 0,
+  : N3VLane32<0, 1, op21_20, op11_8, 1, 0,
         (outs DPR:$Vd),
         (ins DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin,
@@ -1970,7 +1970,7 @@ class N3VDMulOpSL<bits<2> op21_20, bits<4> op11_8, \
InstrItinClass itin,  class N3VDMulOpSL16<bits<2> op21_20, bits<4> op11_8, \
InstrItinClass itin,  string OpcodeStr, string Dt,
                     ValueType Ty, SDNode MulOp, SDNode ShOp>
-  : N3V<0, 1, op21_20, op11_8, 1, 0,
+  : N3VLane16<0, 1, op21_20, op11_8, 1, 0,
         (outs DPR:$Vd),
         (ins DPR:$src1, DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin,
@@ -1992,7 +1992,7 @@ class N3VQMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> \
op11_8, bit op4,  class N3VQMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass \
                itin,
                   string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
                   SDPatternOperator MulOp, SDPatternOperator ShOp>
-  : N3V<1, 1, op21_20, op11_8, 1, 0,
+  : N3VLane32<1, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd),
         (ins QPR:$src1, QPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin,
@@ -2006,7 +2006,7 @@ class N3VQMulOpSL16<bits<2> op21_20, bits<4> op11_8, \
InstrItinClass itin,  string OpcodeStr, string Dt,
                     ValueType ResTy, ValueType OpTy,
                     SDNode MulOp, SDNode ShOp>
-  : N3V<1, 1, op21_20, op11_8, 1, 0,
+  : N3VLane16<1, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd),
         (ins QPR:$src1, QPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin,
@@ -2067,7 +2067,7 @@ class N3VLMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> \
op11_8, bit op4,  class N3VLMulOpSL<bit op24, bits<2> op21_20, bits<4> op11_8,
                   InstrItinClass itin, string OpcodeStr, string Dt,
                   ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode>
-  : N3V<op24, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd),
+  : N3VLane32<op24, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd),
         (ins QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin,
         OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "$src1 = $Vd",
@@ -2079,7 +2079,7 @@ class N3VLMulOpSL<bit op24, bits<2> op21_20, bits<4> op11_8,
 class N3VLMulOpSL16<bit op24, bits<2> op21_20, bits<4> op11_8,
                     InstrItinClass itin, string OpcodeStr, string Dt,
                     ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode>
-  : N3V<op24, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd),
+  : N3VLane16<op24, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd),
         (ins QPR:$src1, DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin,
         OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "$src1 = $Vd",
@@ -2114,7 +2114,7 @@ class N3VLInt3<bit op24, bit op23, bits<2> op21_20, bits<4> \
op11_8, bit op4,  class N3VLInt3SL<bit op24, bits<2> op21_20, bits<4> op11_8, \
InstrItinClass itin,  string OpcodeStr, string Dt,
                  ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
-  : N3V<op24, 1, op21_20, op11_8, 1, 0,
+  : N3VLane32<op24, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd),
         (ins QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin,
@@ -2127,7 +2127,7 @@ class N3VLInt3SL<bit op24, bits<2> op21_20, bits<4> op11_8, \
InstrItinClass itin,  class N3VLInt3SL16<bit op24, bits<2> op21_20, bits<4> op11_8,
                    InstrItinClass itin, string OpcodeStr, string Dt,
                    ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
-  : N3V<op24, 1, op21_20, op11_8, 1, 0,
+  : N3VLane16<op24, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd),
         (ins QPR:$src1, DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin,
@@ -2162,7 +2162,7 @@ class N3VL<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, \
bit op4,  class N3VLSL<bit op24, bits<2> op21_20, bits<4> op11_8,
              InstrItinClass itin, string OpcodeStr, string Dt,
              ValueType TyQ, ValueType TyD, SDNode OpNode>
-  : N3V<op24, 1, op21_20, op11_8, 1, 0,
+  : N3VLane32<op24, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set QPR:$Vd,
@@ -2171,7 +2171,7 @@ class N3VLSL<bit op24, bits<2> op21_20, bits<4> op11_8,
 class N3VLSL16<bit op24, bits<2> op21_20, bits<4> op11_8,
                InstrItinClass itin, string OpcodeStr, string Dt,
                ValueType TyQ, ValueType TyD, SDNode OpNode>
-  : N3V<op24, 1, op21_20, op11_8, 1, 0,
+  : N3VLane16<op24, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set QPR:$Vd,
@@ -2217,7 +2217,7 @@ class N3VLInt<bit op24, bit op23, bits<2> op21_20, bits<4> \
op11_8, bit op4,  class N3VLIntSL<bit op24, bits<2> op21_20, bits<4> op11_8, \
InstrItinClass itin,  string OpcodeStr, string Dt,
                 ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
-  : N3V<op24, 1, op21_20, op11_8, 1, 0,
+  : N3VLane32<op24, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set (ResTy QPR:$Vd),
@@ -2227,7 +2227,7 @@ class N3VLIntSL<bit op24, bits<2> op21_20, bits<4> op11_8, \
InstrItinClass itin,  class N3VLIntSL16<bit op24, bits<2> op21_20, bits<4> op11_8,
                   InstrItinClass itin, string OpcodeStr, string Dt,
                   ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
-  : N3V<op24, 1, op21_20, op11_8, 1, 0,
+  : N3VLane16<op24, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set (ResTy QPR:$Vd),


   Commit: ffc4598d17fa865bdd804cd305529540155858ea
   Author: Bob Wilson <bob.wilson@apple.com>
     Date: 03/30/2011 20:09:35
      URL: https://github.com/mono/llvm/commit/ffc4598d17fa865bdd804cd305529540155858ea


Use intrinsics for Neon vmull operations.  Radar 9208957.

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

Changed paths:
 M utils/TableGen/NeonEmitter.cpp
 M utils/TableGen/NeonEmitter.h

Modified: utils/TableGen/NeonEmitter.cpp
===================================================================
--- a/utils/TableGen/NeonEmitter.cpp
+++ b/utils/TableGen/NeonEmitter.cpp
@@ -608,16 +608,9 @@ static std::string GenOpString(OpKind op, const std::string \
&proto,  case OpMul:
     s += "__a * __b;";
     break;
-  case OpMullN:
-    s += Extend(typestr, "__a") + " * " +
-      Extend(typestr, Duplicate(nElts << (int)quad, typestr, "__b")) + ";";
-    break;
   case OpMullLane:
-    s += Extend(typestr, "__a") + " * " +
-      Extend(typestr, SplatLane(nElts, "__b", "__c")) + ";";
-    break;
-  case OpMull:
-    s += Extend(typestr, "__a") + " * " + Extend(typestr, "__b") + ";";
+    s += MangleName("vmull", typestr, ClassS) + "(__a, " +
+      SplatLane(nElts, "__b", "__c") + ");";
     break;
   case OpMlaN:
     s += "__a + (__b * " + Duplicate(nElts, typestr, "__c") + ");";
@@ -629,16 +622,15 @@ static std::string GenOpString(OpKind op, const std::string \
&proto,  s += "__a + (__b * __c);";
     break;
   case OpMlalN:
-    s += "__a + (" + Extend(typestr, "__b") + " * " +
-      Extend(typestr, Duplicate(nElts, typestr, "__c")) + ");";
+    s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, " +
+      Duplicate(nElts, typestr, "__c") + ");";
     break;
   case OpMlalLane:
-    s += "__a + (" + Extend(typestr, "__b") + " * " +
-      Extend(typestr, SplatLane(nElts, "__c", "__d")) + ");";
+    s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, " +
+      SplatLane(nElts, "__c", "__d") + ");";
     break;
   case OpMlal:
-    s += "__a + (" + Extend(typestr, "__b") + " * " +
-      Extend(typestr, "__c") + ");";
+    s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, __c);";
     break;
   case OpMlsN:
     s += "__a - (__b * " + Duplicate(nElts, typestr, "__c") + ");";
@@ -650,16 +642,15 @@ static std::string GenOpString(OpKind op, const std::string \
&proto,  s += "__a - (__b * __c);";
     break;
   case OpMlslN:
-    s += "__a - (" + Extend(typestr, "__b") + " * " +
-      Extend(typestr, Duplicate(nElts, typestr, "__c")) + ");";
+    s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, " +
+      Duplicate(nElts, typestr, "__c") + ");";
     break;
   case OpMlslLane:
-    s += "__a - (" + Extend(typestr, "__b") + " * " +
-      Extend(typestr, SplatLane(nElts, "__c", "__d")) + ");";
+    s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, " +
+      SplatLane(nElts, "__c", "__d") + ");";
     break;
   case OpMlsl:
-    s += "__a - (" + Extend(typestr, "__b") + " * " +
-      Extend(typestr, "__c") + ");";
+    s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, __c);";
     break;
   case OpQDMullLane:
     s += MangleName("vqdmull", typestr, ClassS) + "(__a, " +
@@ -1148,17 +1139,20 @@ void NeonEmitter::run(raw_ostream &OS) {
 
   std::vector<Record*> RV = Records.getAllDerivedDefinitions("Inst");
 
-  // Emit vmovl and vabd intrinsics first so they can be used by other
+  // Emit vmovl, vmull and vabd intrinsics first so they can be used by other
   // intrinsics.  (Some of the saturating multiply instructions are also
   // used to implement the corresponding "_lane" variants, but tablegen
   // sorts the records into alphabetical order so that the "_lane" variants
   // come after the intrinsics they use.)
   emitIntrinsic(OS, Records.getDef("VMOVL"));
+  emitIntrinsic(OS, Records.getDef("VMULL"));
   emitIntrinsic(OS, Records.getDef("VABD"));
 
   for (unsigned i = 0, e = RV.size(); i != e; ++i) {
     Record *R = RV[i];
-    if (R->getName() != "VMOVL" && R->getName() != "VABD")
+    if (R->getName() != "VMOVL" &&
+        R->getName() != "VMULL" &&
+        R->getName() != "VABD")
       emitIntrinsic(OS, R);
   }
 
Modified: utils/TableGen/NeonEmitter.h
===================================================================
--- a/utils/TableGen/NeonEmitter.h
+++ b/utils/TableGen/NeonEmitter.h
@@ -30,13 +30,11 @@ enum OpKind {
   OpSubl,
   OpSubw,
   OpMul,
-  OpMull,
   OpMla,
   OpMlal,
   OpMls,
   OpMlsl,
   OpMulN,
-  OpMullN,
   OpMlaN,
   OpMlsN,
   OpMlalN,
@@ -105,13 +103,11 @@ namespace llvm {
       OpMap["OP_SUBL"]  = OpSubl;
       OpMap["OP_SUBW"]  = OpSubw;
       OpMap["OP_MUL"]   = OpMul;
-      OpMap["OP_MULL"]  = OpMull;
       OpMap["OP_MLA"]   = OpMla;
       OpMap["OP_MLAL"]  = OpMlal;
       OpMap["OP_MLS"]   = OpMls;
       OpMap["OP_MLSL"]  = OpMlsl;
       OpMap["OP_MUL_N"] = OpMulN;
-      OpMap["OP_MULL_N"]= OpMullN;
       OpMap["OP_MLA_N"] = OpMlaN;
       OpMap["OP_MLS_N"] = OpMlsN;
       OpMap["OP_MLAL_N"] = OpMlalN;


   Commit: c58900ccdce09aef1f5a0ad3e38ac78a8e4a5bb2
   Author: Nick Lewycky <nicholas@mxc.ca>
     Date: 03/30/2011 20:23:57
      URL: https://github.com/mono/llvm/commit/c58900ccdce09aef1f5a0ad3e38ac78a8e4a5bb2


Fix typo in generated HTML.


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

Changed paths:
 M utils/GenLibDeps.pl

Modified: utils/GenLibDeps.pl
===================================================================
--- a/utils/GenLibDeps.pl
+++ b/utils/GenLibDeps.pl
@@ -202,7 +202,7 @@ sub gen_one_entry {
     print "$lib:";
     if ($WHY) { print "\n"; }
   } else {
-    print "  <dt><b>$lib</b</dt><dd><ul>\n";
+    print "  <dt><b>$lib</b></dt><dd><ul>\n";
   }
   open UNDEFS, 
     "$nmPath -u $Directory/$lib | sed -e 's/^[ 0]* U //' | sort | uniq |";


   Commit: 5092c7ccd3e9db5c5467b025ebb6cd5f1156ec0d
   Author: Matt Beaumont-Gay <matthewbg@google.com>
     Date: 03/30/2011 20:39:16
      URL: https://github.com/mono/llvm/commit/5092c7ccd3e9db5c5467b025ebb6cd5f1156ec0d


Revert "- Implement asm parsing support for LDRT, LDRBT, STRT, STRBT and"

This revision introduced a dependency cycle, as nlewycky mentioned by email.

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

Changed paths:
 M lib/Target/ARM/ARMBaseInfo.h
 M lib/Target/ARM/ARMBaseInstrInfo.h
 M lib/Target/ARM/ARMInstrFormats.td
 M lib/Target/ARM/ARMInstrInfo.td
 M lib/Target/ARM/AsmParser/ARMAsmParser.cpp
 M lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
 M lib/Target/ARM/InstPrinter/ARMInstPrinter.h
Removed paths:
 D test/MC/ARM/arm_addrmode2.s

Modified: lib/Target/ARM/ARMBaseInfo.h
===================================================================
--- a/lib/Target/ARM/ARMBaseInfo.h
+++ b/lib/Target/ARM/ARMBaseInfo.h
@@ -200,51 +200,6 @@ inline static unsigned getARMRegisterNumbering(unsigned Reg) {
 }
 
 namespace ARMII {
-
-  /// ARM Addressing Modes
-  enum AddrMode {
-    AddrModeNone    = 0,
-    AddrMode1       = 1,
-    AddrMode2       = 2,
-    AddrMode3       = 3,
-    AddrMode4       = 4,
-    AddrMode5       = 5,
-    AddrMode6       = 6,
-    AddrModeT1_1    = 7,
-    AddrModeT1_2    = 8,
-    AddrModeT1_4    = 9,
-    AddrModeT1_s    = 10, // i8 * 4 for pc and sp relative data
-    AddrModeT2_i12  = 11,
-    AddrModeT2_i8   = 12,
-    AddrModeT2_so   = 13,
-    AddrModeT2_pc   = 14, // +/- i12 for pc relative data
-    AddrModeT2_i8s4 = 15, // i8 * 4
-    AddrMode_i12    = 16
-  };
-
-  inline static const char *AddrModeToString(AddrMode addrmode) {
-    switch (addrmode) {
-    default: llvm_unreachable("Unknown memory operation");
-    case AddrModeNone:    return "AddrModeNone";
-    case AddrMode1:       return "AddrMode1";
-    case AddrMode2:       return "AddrMode2";
-    case AddrMode3:       return "AddrMode3";
-    case AddrMode4:       return "AddrMode4";
-    case AddrMode5:       return "AddrMode5";
-    case AddrMode6:       return "AddrMode6";
-    case AddrModeT1_1:    return "AddrModeT1_1";
-    case AddrModeT1_2:    return "AddrModeT1_2";
-    case AddrModeT1_4:    return "AddrModeT1_4";
-    case AddrModeT1_s:    return "AddrModeT1_s";
-    case AddrModeT2_i12:  return "AddrModeT2_i12";
-    case AddrModeT2_i8:   return "AddrModeT2_i8";
-    case AddrModeT2_so:   return "AddrModeT2_so";
-    case AddrModeT2_pc:   return "AddrModeT2_pc";
-    case AddrModeT2_i8s4: return "AddrModeT2_i8s4";
-    case AddrMode_i12:    return "AddrMode_i12";
-    }
-  }
-
   /// Target Operand Flag enum.
   enum TOF {
     //===------------------------------------------------------------------===//
Modified: lib/Target/ARM/ARMBaseInstrInfo.h
===================================================================
--- a/lib/Target/ARM/ARMBaseInstrInfo.h
+++ b/lib/Target/ARM/ARMBaseInstrInfo.h
@@ -34,7 +34,25 @@ namespace ARMII {
 
     //===------------------------------------------------------------------===//
     // This four-bit field describes the addressing mode used.
-    AddrModeMask  = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h
+
+    AddrModeMask  = 0x1f,
+    AddrModeNone    = 0,
+    AddrMode1       = 1,
+    AddrMode2       = 2,
+    AddrMode3       = 3,
+    AddrMode4       = 4,
+    AddrMode5       = 5,
+    AddrMode6       = 6,
+    AddrModeT1_1    = 7,
+    AddrModeT1_2    = 8,
+    AddrModeT1_4    = 9,
+    AddrModeT1_s    = 10, // i8 * 4 for pc and sp relative data
+    AddrModeT2_i12  = 11,
+    AddrModeT2_i8   = 12,
+    AddrModeT2_so   = 13,
+    AddrModeT2_pc   = 14, // +/- i12 for pc relative data
+    AddrModeT2_i8s4 = 15, // i8 * 4
+    AddrMode_i12    = 16,
 
     // Size* - Flags to keep track of the size of an instruction.
     SizeShift     = 5,
Modified: lib/Target/ARM/ARMInstrFormats.td
===================================================================
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -515,15 +515,15 @@ class AI2stridx<bit isByte, bit isPre, dag oops, dag iops,
   : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
                pattern> {
   // AM2 store w/ two operands: (GPR, am2offset)
-  // {17-14}  Rn
   // {13}     1 == Rm, 0 == imm12
   // {12}     isAdd
   // {11-0}   imm12/Rm
-  bits<18> addr;
-  let Inst{25} = addr{13};
-  let Inst{23} = addr{12};
-  let Inst{19-16} = addr{17-14};
-  let Inst{11-0} = addr{11-0};
+  bits<14> offset;
+  bits<4> Rn;
+  let Inst{25} = offset{13};
+  let Inst{23} = offset{12};
+  let Inst{19-16} = Rn;
+  let Inst{11-0} = offset{11-0};
 }
 
 // addrmode3 instructions
Modified: lib/Target/ARM/ARMInstrInfo.td
===================================================================
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -498,12 +498,6 @@ def ldst_so_reg : Operand<i32>,
   let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
 }
 
-def MemMode2AsmOperand : AsmOperandClass {
-  let Name = "MemMode2";
-  let SuperClasses = [];
-  let ParserMethod = "tryParseMemMode2Operand";
-}
-
 // addrmode2 := reg +/- imm12
 //           := reg +/- reg shop imm
 //
@@ -511,7 +505,6 @@ def addrmode2 : Operand<i32>,
                 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
   let EncoderMethod = "getAddrMode2OpValue";
   let PrintMethod = "printAddrMode2Operand";
-  let ParserMatchClass = MemMode2AsmOperand;
   let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
 }
 
@@ -1663,7 +1656,6 @@ multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass \
itin> {  let Inst{23} = addr{12};
     let Inst{19-16} = addr{17-14};
     let Inst{11-0} = addr{11-0};
-    let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
   }
   def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
                       (ins GPR:$Rn, am2offset:$offset),
@@ -1722,35 +1714,17 @@ defm LDRD :  AI3_ldridx<0b1101, 0, "ldrd", IIC_iLoad_d_ru>;
 
 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
 let mayLoad = 1, neverHasSideEffects = 1 in {
-def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb),
-                   (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_ru,
-                   "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
-  // {17-14}  Rn
-  // {13}     1 == Rm, 0 == imm12
-  // {12}     isAdd
-  // {11-0}   imm12/Rm
-  bits<18> addr;
-  let Inst{25} = addr{13};
-  let Inst{23} = addr{12};
+def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
+                   (ins GPR:$base, am2offset:$offset), IndexModePost,
+                   LdFrm, IIC_iLoad_ru,
+                   "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
   let Inst{21} = 1; // overwrite
-  let Inst{19-16} = addr{17-14};
-  let Inst{11-0} = addr{11-0};
-  let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
-}
-def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb),
-                  (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_bh_ru,
-                  "ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
-  // {17-14}  Rn
-  // {13}     1 == Rm, 0 == imm12
-  // {12}     isAdd
-  // {11-0}   imm12/Rm
-  bits<18> addr;
-  let Inst{25} = addr{13};
-  let Inst{23} = addr{12};
+}
+def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
+                  (ins GPR:$base, am2offset:$offset), IndexModePost,
+                  LdFrm, IIC_iLoad_bh_ru,
+                  "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
   let Inst{21} = 1; // overwrite
-  let Inst{19-16} = addr{17-14};
-  let Inst{11-0} = addr{11-0};
-  let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
 }
 def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
                  (ins GPR:$base, am3offset:$offset), IndexModePost,
@@ -1844,20 +1818,20 @@ def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
 
 // STRT, STRBT, and STRHT are for disassembly only.
 
-def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr),
+def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb),
+                    (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
                     IndexModePost, StFrm, IIC_iStore_ru,
-                    "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb",
+                    "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
                     [/* For disassembly only; pattern left blank */]> {
   let Inst{21} = 1; // overwrite
-  let AsmMatchConverter = "CvtStWriteBackRegAddrMode2";
 }
 
-def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr),
+def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb),
+                     (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
                      IndexModePost, StFrm, IIC_iStore_bh_ru,
-                     "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb",
+                     "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
                      [/* For disassembly only; pattern left blank */]> {
   let Inst{21} = 1; // overwrite
-  let AsmMatchConverter = "CvtStWriteBackRegAddrMode2";
 }
 
 def STRHT: AI3sthpo<(outs GPR:$base_wb),
@@ -3417,9 +3391,8 @@ def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
   let Inst{23-20} = opc1;
 }
 
-class ACI<dag oops, dag iops, string opc, string asm,
-          IndexMode im = IndexModeNone>
-  : I<oops, iops, AddrModeNone, Size4Bytes, im, BrFrm, NoItinerary,
+class ACI<dag oops, dag iops, string opc, string asm>
+  : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
       opc, asm, "", [/* For disassembly only; pattern left blank */]> {
   let Inst{27-25} = 0b110;
 }
@@ -3438,7 +3411,7 @@ multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
 
   def _PRE : ACI<(outs),
       (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
-      opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> {
+      opc, "\tp$cop, cr$CRd, $addr!"> {
     let Inst{31-28} = op31_28;
     let Inst{24} = 1; // P = 1
     let Inst{21} = 1; // W = 1
@@ -3479,7 +3452,7 @@ multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
 
   def L_PRE : ACI<(outs),
       (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
-      !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> {
+      !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
     let Inst{31-28} = op31_28;
     let Inst{24} = 1; // P = 1
     let Inst{21} = 1; // W = 1
Modified: lib/Target/ARM/AsmParser/ARMAsmParser.cpp
===================================================================
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -48,8 +48,7 @@ class ARMAsmParser : public TargetAsmParser {
   bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
   bool TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
   bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
-  bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &,
-                   ARMII::AddrMode AddrMode);
+  bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
   bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
   bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
   const MCExpr *ApplyPrefixToExpr(const MCExpr *E,
@@ -96,14 +95,6 @@ class ARMAsmParser : public TargetAsmParser {
     SmallVectorImpl<MCParsedAsmOperand*>&);
   OperandMatchResultTy tryParseMSRMaskOperand(
     SmallVectorImpl<MCParsedAsmOperand*>&);
-  OperandMatchResultTy tryParseMemMode2Operand(
-    SmallVectorImpl<MCParsedAsmOperand*>&);
-
-  // Asm Match Converter Methods
-  bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
-                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
-  bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
-                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
 
 public:
   ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM)
@@ -181,7 +172,6 @@ class ARMOperand : public MCParsedAsmOperand {
 
     /// Combined record for all forms of ARM address expressions.
     struct {
-      ARMII::AddrMode AddrMode;
       unsigned BaseRegNum;
       union {
         unsigned RegNum;     ///< Offset register num, when OffsetIsReg.
@@ -303,9 +293,7 @@ public:
 
   /// @name Memory Operand Accessors
   /// @{
-  ARMII::AddrMode getMemAddrMode() const {
-    return Mem.AddrMode;
-  }
+
   unsigned getMemBaseRegNum() const {
     return Mem.BaseRegNum;
   }
@@ -350,27 +338,6 @@ public:
   bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
   bool isMemory() const { return Kind == Memory; }
   bool isShifter() const { return Kind == Shifter; }
-  bool isMemMode2() const {
-    if (getMemAddrMode() != ARMII::AddrMode2)
-      return false;
-
-    if (getMemOffsetIsReg())
-      return true;
-
-    if (getMemNegative() &&
-        !(getMemPostindexed() || getMemPreindexed()))
-      return false;
-
-    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
-    if (!CE) return false;
-    int64_t Value = CE->getValue();
-
-    // The offset must be in the range 0-4095 (imm12).
-    if (Value > 4095 || Value < -4095)
-      return false;
-
-    return true;
-  }
   bool isMemMode5() const {
     if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() ||
         getMemNegative())
@@ -498,46 +465,6 @@ public:
            "No offset operand support in mode 7");
   }
 
-  void addMemMode2Operands(MCInst &Inst, unsigned N) const {
-    assert(isMemMode2() && "Invalid mode or number of operands!");
-    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
-
-    if (getMemOffsetIsReg()) {
-      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
-
-      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
-      ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift;
-      int64_t ShiftAmount = 0;
-
-      if (getMemOffsetRegShifted()) {
-        ShOpc = getMemShiftType();
-        const MCConstantExpr *CE =
-                   dyn_cast<MCConstantExpr>(getMemShiftAmount());
-        ShiftAmount = CE->getValue();
-      }
-
-      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount,
-                                           ShOpc)));
-      return;
-    }
-
-    // Create a operand placeholder to always yield the same number of operands.
-    Inst.addOperand(MCOperand::CreateReg(0));
-
-    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
-    // the difference?
-    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
-    assert(CE && "Non-constant mode 2 offset operand!");
-    int64_t Offset = CE->getValue();
-
-    if (Offset >= 0)
-      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add,
-                                           Offset, ARM_AM::no_shift)));
-    else
-      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub,
-                                           -Offset, ARM_AM::no_shift)));
-  }
-
   void addMemMode5Operands(MCInst &Inst, unsigned N) const {
     assert(N == 2 && isMemMode5() && "Invalid number of operands!");
 
@@ -672,9 +599,9 @@ public:
     return Op;
   }
 
-  static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum,
-                               bool OffsetIsReg, const MCExpr *Offset,
-                               int OffsetRegNum, bool OffsetRegShifted,
+  static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg,
+                               const MCExpr *Offset, int OffsetRegNum,
+                               bool OffsetRegShifted,
                                enum ARM_AM::ShiftOpc ShiftType,
                                const MCExpr *ShiftAmount, bool Preindexed,
                                bool Postindexed, bool Negative, bool Writeback,
@@ -691,7 +618,6 @@ public:
            "Cannot have expression offset and register offset!");
 
     ARMOperand *Op = new ARMOperand(Memory);
-    Op->Mem.AddrMode = AddrMode;
     Op->Mem.BaseRegNum = BaseRegNum;
     Op->Mem.OffsetIsReg = OffsetIsReg;
     if (OffsetIsReg)
@@ -763,8 +689,7 @@ void ARMOperand::dump(raw_ostream &OS) const {
     break;
   case Memory:
     OS << "<memory "
-       << "am:" << ARMII::AddrModeToString(getMemAddrMode())
-       << " base:" << getMemBaseRegNum();
+       << "base:" << getMemBaseRegNum();
     if (getMemOffsetIsReg()) {
       OS << " offset:<register " << getMemOffsetRegNum();
       if (getMemOffsetRegShifted()) {
@@ -1207,57 +1132,13 @@ tryParseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> \
&Operands) {  return MatchOperand_Success;
 }
 
-/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand.
-ARMAsmParser::OperandMatchResultTy ARMAsmParser::
-tryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
-  SMLoc S = Parser.getTok().getLoc();
-  const AsmToken &Tok = Parser.getTok();
-  assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\"");
-
-  if (ParseMemory(Operands, ARMII::AddrMode2))
-    return MatchOperand_NoMatch;
-
-  return MatchOperand_Success;
-}
-
-/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
-/// Needed here because the Asm Gen Matcher can't handle properly tied operands
-/// when they refer multiple MIOperands inside a single one.
-bool ARMAsmParser::
-CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
-                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
-  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
-
-  // Create a writeback register dummy placeholder.
-  Inst.addOperand(MCOperand::CreateImm(0));
-
-  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
-  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
-  return true;
-}
-
-/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
-/// Needed here because the Asm Gen Matcher can't handle properly tied operands
-/// when they refer multiple MIOperands inside a single one.
-bool ARMAsmParser::
-CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
-                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
-  // Create a writeback register dummy placeholder.
-  Inst.addOperand(MCOperand::CreateImm(0));
-  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
-  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
-  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
-  return true;
-}
-
 /// Parse an ARM memory expression, return false if successful else return true
 /// or an error.  The first token must be a '[' when called.
 ///
 /// TODO Only preindexing and postindexing addressing are started, unindexed
 /// with option, etc are still to do.
 bool ARMAsmParser::
-ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
-            ARMII::AddrMode AddrMode = ARMII::AddrModeNone) {
+ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
   SMLoc S, E;
   assert(Parser.getTok().is(AsmToken::LBrac) &&
          "Token is not a Left Bracket");
@@ -1350,10 +1231,11 @@ ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
       Offset = MCConstantExpr::Create(0, getContext());
   }
 
-  Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg,
-                                     Offset, OffsetRegNum, OffsetRegShifted,
-                                     ShiftType, ShiftAmount, Preindexed,
-                                     Postindexed, Negative, Writeback, S, E));
+  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset,
+                                           OffsetRegNum, OffsetRegShifted,
+                                           ShiftType, ShiftAmount, Preindexed,
+                                           Postindexed, Negative, Writeback,
+                                           S, E));
   if (WBOp)
     Operands.push_back(WBOp);
 
Modified: lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
===================================================================
--- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
+++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
@@ -14,7 +14,6 @@
 #define DEBUG_TYPE "asm-printer"
 #include "ARMBaseInfo.h"
 #include "ARMInstPrinter.h"
-#include "ARMInstrInfo.h"
 #include "ARMAddressingModes.h"
 #include "llvm/MC/MCInst.h"
 #include "llvm/MC/MCAsmInfo.h"
@@ -182,12 +181,18 @@ void ARMInstPrinter::printSORegOperand(const MCInst *MI, \
unsigned OpNum,  }
 }
 
-void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
-                                                raw_ostream &O) {
+
+void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
+                                           raw_ostream &O) {
   const MCOperand &MO1 = MI->getOperand(Op);
   const MCOperand &MO2 = MI->getOperand(Op+1);
   const MCOperand &MO3 = MI->getOperand(Op+2);
 
+  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
+    printOperand(MI, Op, O);
+    return;
+  }
+
   O << "[" << getRegisterName(MO1.getReg());
 
   if (!MO2.getReg()) {
@@ -210,52 +215,6 @@ void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst \
*MI, unsigned Op,  O << "]";
 }
 
-void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op,
-                                         raw_ostream &O) {
-  const MCOperand &MO1 = MI->getOperand(Op);
-  const MCOperand &MO2 = MI->getOperand(Op+1);
-  const MCOperand &MO3 = MI->getOperand(Op+2);
-
-  O << "[" << getRegisterName(MO1.getReg()) << "], ";
-
-  if (!MO2.getReg()) {
-    unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm());
-    O << '#'
-      << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
-      << ImmOffs;
-    return;
-  }
-
-  O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
-    << getRegisterName(MO2.getReg());
-
-  if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
-    O << ", "
-    << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
-    << " #" << ShImm;
-}
-
-void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
-                                           raw_ostream &O) {
-  const MCOperand &MO1 = MI->getOperand(Op);
-
-  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
-    printOperand(MI, Op, O);
-    return;
-  }
-
-  unsigned Opcode = MI->getOpcode();
-  const TargetInstrDesc &Desc = TM.getInstrInfo()->get(Opcode);
-  uint64_t TSFlags = Desc.TSFlags;
-  unsigned IdxMode = (TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
-
-  if (IdxMode == ARMII::IndexModePost) {
-    printAM2PostIndexOp(MI, Op, O);
-    return;
-  }
-  printAM2PreOrOffsetIndexOp(MI, Op, O);
-}
-
 void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
                                                  unsigned OpNum,
                                                  raw_ostream &O) {
Modified: lib/Target/ARM/InstPrinter/ARMInstPrinter.h
===================================================================
--- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
+++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
@@ -22,11 +22,9 @@ class MCOperand;
 class TargetMachine;
 
 class ARMInstPrinter : public MCInstPrinter {
-private:
-  TargetMachine &TM;
 public:
-  ARMInstPrinter(TargetMachine &_TM, const MCAsmInfo &MAI)
-    : MCInstPrinter(MAI), TM(_TM) {}
+  ARMInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI)
+    : MCInstPrinter(MAI) {}
 
   virtual void printInst(const MCInst *MI, raw_ostream &O);
   virtual StringRef getOpcodeName(unsigned Opcode) const;
@@ -44,11 +42,7 @@ public:
   void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
 
   void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
-
   void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
-  void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O);
-  void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum,
-                                  raw_ostream &O);
   void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum,
                                    raw_ostream &O);
   void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);


   Commit: a4cc2bbc4a82006fd52c28c7d6a3ed55e201d52b
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/30/2011 23:54:44
      URL: https://github.com/mono/llvm/commit/a4cc2bbc4a82006fd52c28c7d6a3ed55e201d52b


Pick a conservative register class when creating a small live range for remat.

The rematerialized instruction may require a more constrained register class
than the register being spilled. In the test case, the spilled register has been
inflated to the DPR register class, but we are rematerializing a load of the
ssub_0 sub-register which only exists for DPR_VFP2 registers.

The register class is reinflated after spilling, so the conservative choice is
only temporary.

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

Changed paths:
 M lib/CodeGen/InlineSpiller.cpp
Added paths:
 A test/CodeGen/ARM/crash-greedy.ll

Modified: lib/CodeGen/InlineSpiller.cpp
===================================================================
--- a/lib/CodeGen/InlineSpiller.cpp
+++ b/lib/CodeGen/InlineSpiller.cpp
@@ -627,7 +627,7 @@ bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg,
   }
 
   // Alocate a new register for the remat.
-  LiveInterval &NewLI = Edit->createFrom(VirtReg.reg, LIS, VRM);
+  LiveInterval &NewLI = Edit->createFrom(Original, LIS, VRM);
   NewLI.markNotSpillable();
 
   // Finally we can rematerialize OrigMI before MI.

Added: test/CodeGen/ARM/crash-greedy.ll
===================================================================
--- /dev/null
+++ b/test/CodeGen/ARM/crash-greedy.ll
@@ -0,0 +1,62 @@
+; RUN: llc < %s -regalloc=greedy -mcpu=cortex-a8 -relocation-model=pic \
-disable-fp-elim | FileCheck %s +;
+; ARM tests that crash or fail with the greedy register allocator.
+
+target triple = "thumbv7-apple-darwin"
+
+declare double @exp(double)
+
+; CHECK remat_subreg
+define void @remat_subreg(float* nocapture %x, i32* %y, i32 %n, i32 %z, float %c, \
float %lambda, float* nocapture %ret_f, float* nocapture %ret_df) nounwind { +entry:
+  %conv16 = fpext float %lambda to double
+  %mul17 = fmul double %conv16, -1.000000e+00
+  br i1 undef, label %cond.end.us, label %cond.end
+
+cond.end.us:                                      ; preds = %entry
+  unreachable
+
+cond.end:                                         ; preds = %cond.end, %entry
+  %mul = fmul double undef, 0.000000e+00
+  %add = fadd double undef, %mul
+  %add46 = fadd double undef, undef
+  %add75 = fadd double 0.000000e+00, undef
+  br i1 undef, label %for.end, label %cond.end
+
+for.end:                                          ; preds = %cond.end
+  %conv78 = sitofp i32 %z to double
+  %conv83 = fpext float %c to double
+  %mul84 = fmul double %mul17, %conv83
+  %call85 = tail call double @exp(double %mul84) nounwind
+  %mul86 = fmul double %conv78, %call85
+  %add88 = fadd double 0.000000e+00, %mul86
+; CHECK: blx _exp
+  %call100 = tail call double @exp(double %mul84) nounwind
+  %mul101 = fmul double undef, %call100
+  %add103 = fadd double %add46, %mul101
+  %mul111 = fmul double undef, %conv83
+  %mul119 = fmul double %mul111, undef
+  %add121 = fadd double undef, %mul119
+  %div = fdiv double 1.000000e+00, %conv16
+  %div126 = fdiv double %add, %add75
+  %sub = fsub double %div, %div126
+  %div129 = fdiv double %add103, %add88
+  %add130 = fadd double %sub, %div129
+  %conv131 = fptrunc double %add130 to float
+  store float %conv131, float* %ret_f, align 4
+  %mul139 = fmul double %div129, %div129
+  %div142 = fdiv double %add121, %add88
+  %sub143 = fsub double %mul139, %div142
+; %lambda is passed on the stack, and the stack slot load is rematerialized.
+; The rematted load of a float constrains the D register used for the mul.
+; CHECK: vldr
+  %mul146 = fmul float %lambda, %lambda
+  %conv147 = fpext float %mul146 to double
+  %div148 = fdiv double 1.000000e+00, %conv147
+  %sub149 = fsub double %sub143, %div148
+  %conv150 = fptrunc double %sub149 to float
+  store float %conv150, float* %ret_df, align 4
+  ret void
+}
+
+



   Commit: 1d80b6f3e1d163fdb7347c3d31dd08e7fa795ede
   Author: Bill Wendling <isanbard@gmail.com>
     Date: 03/31/2011 04:13:57
      URL: https://github.com/mono/llvm/commit/1d80b6f3e1d163fdb7347c3d31dd08e7fa795ede


Testcase for r128619 (PR9571).

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

Added paths:
 A test/FrontendC/2011-03-31-ArrayRefFolding.c

Added: test/FrontendC/2011-03-31-ArrayRefFolding.c
===================================================================
--- /dev/null
+++ b/test/FrontendC/2011-03-31-ArrayRefFolding.c
@@ -0,0 +1,16 @@
+// RUN: %llvmgcc -S -o - -m32 -Os %s | FileCheck %s
+// PR9571
+
+struct t {
+  int x;
+};
+
+extern struct t *cfun;
+
+int f(void) {
+  if (!(cfun + 0))
+// CHECK: icmp eq %struct.t* %0, null
+    return 0;
+  return cfun->x;
+}
+



   Commit: 59bfecc2dec876e5e2c96fb8b6103d24127fe100
   Author: Duncan Sands <baldrick@free.fr>
     Date: 03/31/2011 05:58:51
      URL: https://github.com/mono/llvm/commit/59bfecc2dec876e5e2c96fb8b6103d24127fe100


Strip trailing whitespace.


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

Changed paths:
 M unittests/VMCore/DerivedTypesTest.cpp
 M unittests/VMCore/PassManagerTest.cpp

Modified: unittests/VMCore/DerivedTypesTest.cpp
===================================================================
--- a/unittests/VMCore/DerivedTypesTest.cpp
+++ b/unittests/VMCore/DerivedTypesTest.cpp
@@ -19,13 +19,13 @@ namespace {
 
 static void PR7658() {
   LLVMContext ctx;
-  
+
   WeakVH NullPtr;
   PATypeHolder h1;
   {
     OpaqueType *o1 = OpaqueType::get(ctx);
     PointerType *p1 = PointerType::get(o1, 0);
-    
+
     std::vector<const Type *> t1;
     t1.push_back(IntegerType::get(ctx, 32));
     t1.push_back(p1);
@@ -33,41 +33,41 @@ static void PR7658() {
     OpaqueType *o2 = OpaqueType::get (ctx);
     PointerType *p2 = PointerType::get (o2, 0);
     t1.push_back(p2);
-    
-    
+
+
     StructType *s1 = StructType::get(ctx, t1);
     h1 = s1;
     o1->refineAbstractTypeTo(s1);
     o2->refineAbstractTypeTo(h1.get());  // h1 = { i32, \2*, \2* }
   }
-  
-  
+
+
   OpaqueType *o3 = OpaqueType::get(ctx);
   PointerType *p3 = PointerType::get(o3, 0);  // p3 = opaque*
-  
+
   std::vector<const Type *> t2;
   t2.push_back(IntegerType::get(ctx, 32));
   t2.push_back(p3);
-  
+
   std::vector<Constant *> v2;
   v2.push_back(ConstantInt::get(IntegerType::get(ctx, 32), 14));
   v2.push_back(ConstantPointerNull::get(p3));
-  
+
   OpaqueType *o4 = OpaqueType::get(ctx);
   {
     PointerType *p4 = PointerType::get(o4, 0);
     t2.push_back(p4);
     v2.push_back(ConstantPointerNull::get(p4));
   }
-  
+
   WeakVH CS = ConstantStruct::get(ctx, v2, false); // { i32 14, opaque* null, \
                opaque* null}
-  
+
   StructType *s2 = StructType::get(ctx, t2);
   PATypeHolder h2(s2);
   o3->refineAbstractTypeTo(s2);
   o4->refineAbstractTypeTo(h2.get());
 }
-  
+
 
 TEST(OpaqueTypeTest, RegisterWithContext) {
   LLVMContext C;
@@ -81,7 +81,7 @@ TEST(OpaqueTypeTest, RegisterWithContext) {
     EXPECT_EQ(2u, pImpl->OpaqueTypes.size());
   }
   EXPECT_EQ(1u, pImpl->OpaqueTypes.size());
-  
+
   PR7658();
 }
 
Modified: unittests/VMCore/PassManagerTest.cpp
===================================================================
--- a/unittests/VMCore/PassManagerTest.cpp
+++ b/unittests/VMCore/PassManagerTest.cpp
@@ -40,7 +40,7 @@ namespace llvm {
   void initializeCGPassPass(PassRegistry&);
   void initializeLPassPass(PassRegistry&);
   void initializeBPassPass(PassRegistry&);
-  
+
   namespace {
     // ND = no deps
     // NM = no modifications


   Commit: 862e47692f70553bfc196dd16ad4328ad6445a08
   Author: Duncan Sands <baldrick@free.fr>
     Date: 03/31/2011 06:03:32
      URL: https://github.com/mono/llvm/commit/862e47692f70553bfc196dd16ad4328ad6445a08


Will not compile without the spec!


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

Changed paths:
 M test/FrontendAda/real_cst.adb

Modified: test/FrontendAda/real_cst.adb
===================================================================
--- a/test/FrontendAda/real_cst.adb
+++ b/test/FrontendAda/real_cst.adb
@@ -1,4 +1,4 @@
--- RUN: %llvmgcc -S -O2 -gnatn %s
+-- RUN: %llvmgcc -S -O2 -gnatn %s -I%p/Support
 package body Real_Cst is
    Cst : constant Float := 0.0;
    procedure Write (Stream : access Ada.Streams.Root_Stream_Type'Class) is


   Commit: 507ab92bc9a798a6667c3eaa964819c2c388d45f
   Author: Benjamin Kramer <benny.kra@googlemail.com>
     Date: 03/31/2011 06:11:58
      URL: https://github.com/mono/llvm/commit/507ab92bc9a798a6667c3eaa964819c2c388d45f


InstCombine: fold fcmp (fpext x), (fpext y) -> fcmp x, y.

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

Changed paths:
 M lib/Transforms/InstCombine/InstCombineCompares.cpp
Added paths:
 A test/Transforms/InstCombine/fcmp.ll

Modified: lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2813,5 +2813,12 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
       }
   }
 
+  // fcmp (fpext x), (fpext y) -> fcmp x, y
+  if (FPExtInst *LHSExt = dyn_cast<FPExtInst>(Op0))
+    if (FPExtInst *RHSExt = dyn_cast<FPExtInst>(Op1))
+      if (LHSExt->getSrcTy() == RHSExt->getSrcTy())
+        return new FCmpInst(I.getPredicate(), LHSExt->getOperand(0),
+                            RHSExt->getOperand(0));
+
   return Changed ? &I : 0;
 }

Added: test/Transforms/InstCombine/fcmp.ll
===================================================================
--- /dev/null
+++ b/test/Transforms/InstCombine/fcmp.ll
@@ -0,0 +1,12 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+
+define i1 @test1(float %x, float %y) nounwind {
+  %ext1 = fpext float %x to double
+  %ext2 = fpext float %y to double
+  %cmp = fcmp ogt double %ext1, %ext2
+  ret i1 %cmp
+; CHECK: @test1
+; CHECK-NEXT: fcmp ogt float %x, %y
+}
+
+



   Commit: b0f57c4a5fcb8dfdf733b5c3cfed6d03737eef08
   Author: Benjamin Kramer <benny.kra@googlemail.com>
     Date: 03/31/2011 06:12:07
      URL: https://github.com/mono/llvm/commit/b0f57c4a5fcb8dfdf733b5c3cfed6d03737eef08


InstCombine: Shrink "fcmp (fpext x), C" to "fcmp x, C" if C can be losslessly \
converted to the type of x.

Fixes PR9592.

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

Changed paths:
 M lib/Transforms/InstCombine/InstCombineCompares.cpp
 M test/Transforms/InstCombine/fcmp.ll

Modified: lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2762,6 +2762,40 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
   if (Constant *RHSC = dyn_cast<Constant>(Op1)) {
     if (Instruction *LHSI = dyn_cast<Instruction>(Op0))
       switch (LHSI->getOpcode()) {
+      case Instruction::FPExt: {
+        // fcmp (fpext x), C -> fcmp x, (fptrunc C) if fptrunc is lossless
+        FPExtInst *LHSExt = cast<FPExtInst>(LHSI);
+        ConstantFP *RHSF = dyn_cast<ConstantFP>(RHSC);
+        if (!RHSF)
+          break;
+
+        const fltSemantics *Sem;
+        // FIXME: This shouldn't be here.
+        if (LHSExt->getSrcTy()->isFloatTy())
+          Sem = &APFloat::IEEEsingle;
+        else if (LHSExt->getSrcTy()->isDoubleTy())
+          Sem = &APFloat::IEEEdouble;
+        else if (LHSExt->getSrcTy()->isFP128Ty())
+          Sem = &APFloat::IEEEquad;
+        else if (LHSExt->getSrcTy()->isX86_FP80Ty())
+          Sem = &APFloat::x87DoubleExtended;
+        else if (LHSExt->getSrcTy()->isPPC_FP128Ty())
+          Sem = &APFloat::PPCDoubleDouble;
+        else
+          break;
+
+        bool Lossy;
+        APFloat F = RHSF->getValueAPF();
+        F.convert(*Sem, APFloat::rmNearestTiesToEven, &Lossy);
+
+        // Avoid lossy conversions and denormals.
+        if (!Lossy &&
+            F.compare(APFloat::getSmallestNormalized(*Sem)) !=
+                                                           APFloat::cmpLessThan)
+          return new FCmpInst(I.getPredicate(), LHSExt->getOperand(0),
+                              ConstantFP::get(RHSC->getContext(), F));
+        break;
+      }
       case Instruction::PHI:
         // Only fold fcmp into the PHI if the phi and fcmp are in the same
         // block.  If in the same block, we're encouraging jump threading.  If
Modified: test/Transforms/InstCombine/fcmp.ll
===================================================================
--- a/test/Transforms/InstCombine/fcmp.ll
+++ b/test/Transforms/InstCombine/fcmp.ll
@@ -9,3 +9,26 @@ define i1 @test1(float %x, float %y) nounwind {
 ; CHECK-NEXT: fcmp ogt float %x, %y
 }
 
+define i1 @test2(float %a) nounwind {
+  %ext = fpext float %a to double
+  %cmp = fcmp ogt double %ext, 1.000000e+00
+  ret i1 %cmp
+; CHECK: @test2
+; CHECK-NEXT: fcmp ogt float %a, 1.0
+}
+
+define i1 @test3(float %a) nounwind {
+  %ext = fpext float %a to double
+  %cmp = fcmp ogt double %ext, 0x3FF0000000000001 ; more precision than float.
+  ret i1 %cmp
+; CHECK: @test3
+; CHECK-NEXT: fpext float %a to double
+}
+
+define i1 @test4(float %a) nounwind {
+  %ext = fpext float %a to double
+  %cmp = fcmp ogt double %ext, 0x36A0000000000000 ; denormal in float.
+  ret i1 %cmp
+; CHECK: @test4
+; CHECK-NEXT: fpext float %a to double
+}


   Commit: 7a6c997a7f148ef9103b77d2be65364795fb19a5
   Author: Benjamin Kramer <benny.kra@googlemail.com>
     Date: 03/31/2011 06:12:15
      URL: https://github.com/mono/llvm/commit/7a6c997a7f148ef9103b77d2be65364795fb19a5


InstCombine: fold fcmp pred (fneg x), C -> fcmp swap(pred) x, -C

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

Changed paths:
 M lib/Transforms/InstCombine/InstCombineCompares.cpp
 M test/Transforms/InstCombine/fcmp.ll

Modified: lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2834,6 +2834,14 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
           return SelectInst::Create(LHSI->getOperand(0), Op1, Op2);
         break;
       }
+      case Instruction::FSub: {
+        // fcmp pred (fneg x), C -> fcmp swap(pred) x, -C
+        Value *Op;
+        if (match(LHSI, m_FNeg(m_Value(Op))))
+          return new FCmpInst(I.getSwappedPredicate(), Op,
+                              ConstantExpr::getFNeg(RHSC));
+        break;
+      }
       case Instruction::Load:
         if (GetElementPtrInst *GEP =
             dyn_cast<GetElementPtrInst>(LHSI->getOperand(0))) {
Modified: test/Transforms/InstCombine/fcmp.ll
===================================================================
--- a/test/Transforms/InstCombine/fcmp.ll
+++ b/test/Transforms/InstCombine/fcmp.ll
@@ -32,3 +32,11 @@ define i1 @test4(float %a) nounwind {
 ; CHECK: @test4
 ; CHECK-NEXT: fpext float %a to double
 }
+
+define i1 @test5(float %a) nounwind {
+  %neg = fsub float -0.000000e+00, %a
+  %cmp = fcmp ogt float %neg, 1.000000e+00
+  ret i1 %cmp
+; CHECK: @test5
+; CHECK-NEXT: fcmp olt float %a, -1.0
+}


   Commit: d485cc70c0de1ddd0c3db25258aa5c0894822f39
   Author: Benjamin Kramer <benny.kra@googlemail.com>
     Date: 03/31/2011 06:12:22
      URL: https://github.com/mono/llvm/commit/d485cc70c0de1ddd0c3db25258aa5c0894822f39


InstCombine: fold fcmp (fneg x), (fneg y) -> fcmp x, y

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

Changed paths:
 M lib/Transforms/InstCombine/InstCombineCompares.cpp
 M test/Transforms/InstCombine/fcmp.ll

Modified: lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2855,6 +2855,11 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
       }
   }
 
+  // fcmp (fneg x), (fneg y) -> fcmp x, y
+  Value *X, *Y;
+  if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_FNeg(m_Value(Y))))
+    return new FCmpInst(I.getPredicate(), X, Y);
+
   // fcmp (fpext x), (fpext y) -> fcmp x, y
   if (FPExtInst *LHSExt = dyn_cast<FPExtInst>(Op0))
     if (FPExtInst *RHSExt = dyn_cast<FPExtInst>(Op1))
Modified: test/Transforms/InstCombine/fcmp.ll
===================================================================
--- a/test/Transforms/InstCombine/fcmp.ll
+++ b/test/Transforms/InstCombine/fcmp.ll
@@ -40,3 +40,12 @@ define i1 @test5(float %a) nounwind {
 ; CHECK: @test5
 ; CHECK-NEXT: fcmp olt float %a, -1.0
 }
+
+define i1 @test6(float %x, float %y) nounwind {
+  %neg1 = fsub float -0.000000e+00, %x
+  %neg2 = fsub float -0.000000e+00, %y
+  %cmp = fcmp ogt float %neg1, %neg2
+  ret i1 %cmp
+; CHECK: @test6
+; CHECK-NEXT: fcmp ogt float %x, %y
+}


   Commit: 7402b659f04f819d701b4f519f6e9a734fcf3f2e
   Author: Benjamin Kramer <benny.kra@googlemail.com>
     Date: 03/31/2011 06:46:03
      URL: https://github.com/mono/llvm/commit/7402b659f04f819d701b4f519f6e9a734fcf3f2e


InstCombine: Fix transform to use the swapped predicate.

Thanks Frits!

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

Changed paths:
 M lib/Transforms/InstCombine/InstCombineCompares.cpp
 M test/Transforms/InstCombine/fcmp.ll

Modified: lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2855,10 +2855,10 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
       }
   }
 
-  // fcmp (fneg x), (fneg y) -> fcmp x, y
+  // fcmp pred (fneg x), (fneg y) -> fcmp swap(pred) x, y
   Value *X, *Y;
   if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_FNeg(m_Value(Y))))
-    return new FCmpInst(I.getPredicate(), X, Y);
+    return new FCmpInst(I.getSwappedPredicate(), X, Y);
 
   // fcmp (fpext x), (fpext y) -> fcmp x, y
   if (FPExtInst *LHSExt = dyn_cast<FPExtInst>(Op0))
Modified: test/Transforms/InstCombine/fcmp.ll
===================================================================
--- a/test/Transforms/InstCombine/fcmp.ll
+++ b/test/Transforms/InstCombine/fcmp.ll
@@ -44,7 +44,7 @@ define i1 @test5(float %a) nounwind {
 define i1 @test6(float %x, float %y) nounwind {
   %neg1 = fsub float -0.000000e+00, %x
   %neg2 = fsub float -0.000000e+00, %y
-  %cmp = fcmp ogt float %neg1, %neg2
+  %cmp = fcmp olt float %neg1, %neg2
   ret i1 %cmp
 ; CHECK: @test6
 ; CHECK-NEXT: fcmp ogt float %x, %y


   Commit: e811258369bb78654d6c419f8cf007795be207b5
   Author: NAKAMURA Takumi <geek4civic@gmail.com>
     Date: 03/31/2011 08:11:33
      URL: https://github.com/mono/llvm/commit/e811258369bb78654d6c419f8cf007795be207b5


lib/CodeGen/LiveIntervalAnalysis.cpp: [PR9590] Don't use std::pow(float,float) here.

We don't expect the real "powf()" on some hosts (and powf() would be available on \
other hosts). For consistency, std::pow(double,double) may be called instead.
Or, precision issue might attack us, to see unstable regalloc and stack coloring.

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

Changed paths:
 M lib/CodeGen/LiveIntervalAnalysis.cpp

Modified: lib/CodeGen/LiveIntervalAnalysis.cpp
===================================================================
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -1715,7 +1715,9 @@ LiveIntervals::getSpillWeight(bool isDef, bool isUse, unsigned \
loopDepth) {  // overflow a float. This expression behaves like 10^d for small d, but \
is  // more tempered for large d. At d=200 we get 6.7e33 which leaves a bit of
   // headroom before overflow.
-  float lc = std::pow(1 + (100.0f / (loopDepth+10)), (float)loopDepth);
+  // By the way, powf() might be unavailable here. For consistency,
+  // We may take pow(double,double).
+  float lc = std::pow(1 + (100.0 / (loopDepth + 10)), (double)loopDepth);
 
   return (isDef + isUse) * lc;
 }


   Commit: 6ca04966cb572a2100c3773392e1058483817a2c
   Author: Michael J. Spencer <bigcheesegs@gmail.com>
     Date: 03/31/2011 09:04:19
      URL: https://github.com/mono/llvm/commit/6ca04966cb572a2100c3773392e1058483817a2c


Switch FileRemover from PathV1 to V2.

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

Changed paths:
 M include/llvm/Support/FileUtilities.h
 M tools/bugpoint/BugDriver.cpp
 M tools/bugpoint/ExecutionDriver.cpp
 M tools/bugpoint/Miscompilation.cpp
 M tools/bugpoint/ToolRunner.cpp
 M tools/llvm-ld/llvm-ld.cpp

Modified: include/llvm/Support/FileUtilities.h
===================================================================
--- a/include/llvm/Support/FileUtilities.h
+++ b/include/llvm/Support/FileUtilities.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_SUPPORT_FILEUTILITIES_H
 #define LLVM_SUPPORT_FILEUTILITIES_H
 
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 
 namespace llvm {
@@ -37,29 +38,36 @@ namespace llvm {
   /// specified (if deleteIt is true).
   ///
   class FileRemover {
-    sys::Path Filename;
+    SmallString<128> Filename;
     bool DeleteIt;
   public:
     FileRemover() : DeleteIt(false) {}
 
-    explicit FileRemover(const sys::Path &filename, bool deleteIt = true)
-      : Filename(filename), DeleteIt(deleteIt) {}
+    explicit FileRemover(const Twine& filename, bool deleteIt = true)
+      : DeleteIt(deleteIt) {
+      filename.toVector(Filename);
+    }
 
     ~FileRemover() {
       if (DeleteIt) {
         // Ignore problems deleting the file.
-        Filename.eraseFromDisk();
+        bool existed;
+        sys::fs::remove(Filename.str(), existed);
       }
     }
 
     /// setFile - Give ownership of the file to the FileRemover so it will
     /// be removed when the object is destroyed.  If the FileRemover already
     /// had ownership of a file, remove it first.
-    void setFile(const sys::Path &filename, bool deleteIt = true) {
-      if (DeleteIt)
-        Filename.eraseFromDisk();
+    void setFile(const Twine& filename, bool deleteIt = true) {
+      if (DeleteIt) {
+        // Ignore problems deleting the file.
+        bool existed;
+        sys::fs::remove(Filename.str(), existed);
+      }
 
-      Filename = filename;
+      Filename.clear();
+      filename.toVector(Filename);
       DeleteIt = deleteIt;
     }
 
Modified: tools/bugpoint/BugDriver.cpp
===================================================================
--- a/tools/bugpoint/BugDriver.cpp
+++ b/tools/bugpoint/BugDriver.cpp
@@ -194,7 +194,7 @@ bool BugDriver::run(std::string &ErrMsg) {
   // Make sure the reference output file gets deleted on exit from this
   // function, if appropriate.
   sys::Path ROF(ReferenceOutputFile);
-  FileRemover RemoverInstance(ROF, CreatedOutput && !SaveTemps);
+  FileRemover RemoverInstance(ROF.str(), CreatedOutput && !SaveTemps);
 
   // Diff the output of the raw program against the reference output.  If it
   // matches, then we assume there is a miscompilation bug and try to 
Modified: tools/bugpoint/ExecutionDriver.cpp
===================================================================
--- a/tools/bugpoint/ExecutionDriver.cpp
+++ b/tools/bugpoint/ExecutionDriver.cpp
@@ -323,7 +323,7 @@ void BugDriver::compileProgram(Module *M, std::string *Error) \
const {  }
 
   // Remove the temporary bitcode file when we are done.
-  FileRemover BitcodeFileRemover(BitcodeFile, !SaveTemps);
+  FileRemover BitcodeFileRemover(BitcodeFile.str(), !SaveTemps);
 
   // Actually compile the program!
   Interpreter->compileProgram(BitcodeFile.str(), Error, Timeout, MemoryLimit);
@@ -364,7 +364,8 @@ std::string BugDriver::executeProgram(const Module *Program,
 
   // Remove the temporary bitcode file when we are done.
   sys::Path BitcodePath(BitcodeFile);
-  FileRemover BitcodeFileRemover(BitcodePath, CreatedBitcode && !SaveTemps);
+  FileRemover BitcodeFileRemover(BitcodePath.str(),
+    CreatedBitcode && !SaveTemps);
 
   if (OutputFile.empty()) OutputFile = OutputPrefix + "-execution-output";
 
Modified: tools/bugpoint/Miscompilation.cpp
===================================================================
--- a/tools/bugpoint/Miscompilation.cpp
+++ b/tools/bugpoint/Miscompilation.cpp
@@ -943,7 +943,7 @@ static bool TestCodeGenerator(BugDriver &BD, Module *Test, Module \
*Safe,  }
   delete Test;
 
-  FileRemover TestModuleBCRemover(TestModuleBC, !SaveTemps);
+  FileRemover TestModuleBCRemover(TestModuleBC.str(), !SaveTemps);
 
   // Make the shared library
   sys::Path SafeModuleBC("bugpoint.safe.bc");
@@ -959,14 +959,14 @@ static bool TestCodeGenerator(BugDriver &BD, Module *Test, \
Module *Safe,  exit(1);
   }
 
-  FileRemover SafeModuleBCRemover(SafeModuleBC, !SaveTemps);
+  FileRemover SafeModuleBCRemover(SafeModuleBC.str(), !SaveTemps);
 
   std::string SharedObject = BD.compileSharedObject(SafeModuleBC.str(), Error);
   if (!Error.empty())
     return false;
   delete Safe;
 
-  FileRemover SharedObjectRemover(sys::Path(SharedObject), !SaveTemps);
+  FileRemover SharedObjectRemover(SharedObject, !SaveTemps);
 
   // Run the code generator on the `Test' code, loading the shared library.
   // The function returns whether or not the new output differs from reference.
Modified: tools/bugpoint/ToolRunner.cpp
===================================================================
--- a/tools/bugpoint/ToolRunner.cpp
+++ b/tools/bugpoint/ToolRunner.cpp
@@ -503,7 +503,7 @@ int LLC::ExecuteProgram(const std::string &Bitcode,
   sys::Path OutputAsmFile;
   GCC::FileType FileKind = OutputCode(Bitcode, OutputAsmFile, *Error, Timeout,
                                       MemoryLimit);
-  FileRemover OutFileRemover(OutputAsmFile, !SaveTemps);
+  FileRemover OutFileRemover(OutputAsmFile.str(), !SaveTemps);
 
   std::vector<std::string> GCCArgs(ArgsForGCC);
   GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end());
@@ -675,7 +675,7 @@ int CBE::ExecuteProgram(const std::string &Bitcode,
   sys::Path OutputCFile;
   OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit);
 
-  FileRemover CFileRemove(OutputCFile, !SaveTemps);
+  FileRemover CFileRemove(OutputCFile.str(), !SaveTemps);
 
   std::vector<std::string> GCCArgs(ArgsForGCC);
   GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end());
@@ -851,7 +851,7 @@ int GCC::ExecuteProgram(const std::string &ProgramFile,
         errs() << "\n";
         );
 
-  FileRemover OutputBinaryRemover(OutputBinary, !SaveTemps);
+  FileRemover OutputBinaryRemover(OutputBinary.str(), !SaveTemps);
 
   if (RemoteClientPath.isEmpty()) {
     DEBUG(errs() << "<run locally>");
Modified: tools/llvm-ld/llvm-ld.cpp
===================================================================
--- a/tools/llvm-ld/llvm-ld.cpp
+++ b/tools/llvm-ld/llvm-ld.cpp
@@ -552,12 +552,12 @@ int main(int argc, char **argv, char **envp) {
   }
 
   // Arrange for the bitcode output file to be deleted on any errors.
-  BitcodeOutputRemover.setFile(sys::Path(BitcodeOutputFilename));
+  BitcodeOutputRemover.setFile(BitcodeOutputFilename);
   sys::RemoveFileOnSignal(sys::Path(BitcodeOutputFilename));
 
   // Arrange for the output file to be deleted on any errors.
   if (!LinkAsLibrary) {
-    OutputRemover.setFile(sys::Path(OutputFilename));
+    OutputRemover.setFile(OutputFilename);
     sys::RemoveFileOnSignal(sys::Path(OutputFilename));
   }
 
@@ -657,7 +657,7 @@ int main(int argc, char **argv, char **envp) {
       AssemblyFile.appendSuffix("s");
 
       // Mark the output files for removal.
-      FileRemover AssemblyFileRemover(AssemblyFile);
+      FileRemover AssemblyFileRemover(AssemblyFile.str());
       sys::RemoveFileOnSignal(AssemblyFile);
 
       // Determine the locations of the llc and gcc programs.
@@ -684,7 +684,7 @@ int main(int argc, char **argv, char **envp) {
       CFile.appendSuffix("cbe.c");
 
       // Mark the output files for removal.
-      FileRemover CFileRemover(CFile);
+      FileRemover CFileRemover(CFile.str());
       sys::RemoveFileOnSignal(CFile);
 
       // Determine the locations of the llc and gcc programs.


   Commit: 752b807091cc4f33a118800a048981467456b0a5
   Author: Michael J. Spencer <bigcheesegs@gmail.com>
     Date: 03/31/2011 09:06:39
      URL: https://github.com/mono/llvm/commit/752b807091cc4f33a118800a048981467456b0a5


Fix whitespace.

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

Changed paths:
 M include/llvm/Support/FileUtilities.h
 M tools/bugpoint/BugDriver.cpp
 M tools/bugpoint/Miscompilation.cpp

Modified: include/llvm/Support/FileUtilities.h
===================================================================
--- a/include/llvm/Support/FileUtilities.h
+++ b/include/llvm/Support/FileUtilities.h
@@ -22,7 +22,7 @@ namespace llvm {
 
   /// DiffFilesWithTolerance - Compare the two files specified, returning 0 if
   /// the files match, 1 if they are different, and 2 if there is a file error.
-  /// This function allows you to specify an absolete and relative FP error that
+  /// This function allows you to specify an absolute and relative FP error that
   /// is allowed to exist.  If you specify a string to fill in for the error
   /// option, it will set the string to an error message if an error occurs, or
   /// if the files are different.
Modified: tools/bugpoint/BugDriver.cpp
===================================================================
--- a/tools/bugpoint/BugDriver.cpp
+++ b/tools/bugpoint/BugDriver.cpp
@@ -71,7 +71,7 @@ BugDriver::BugDriver(const char *toolname, bool find_bugs,
                      LLVMContext& ctxt)
   : Context(ctxt), ToolName(toolname), ReferenceOutputFile(OutputFile),
     Program(0), Interpreter(0), SafeInterpreter(0), gcc(0),
-    run_find_bugs(find_bugs), Timeout(timeout), 
+    run_find_bugs(find_bugs), Timeout(timeout),
     MemoryLimit(memlimit), UseValgrind(use_valgrind) {}
 
 BugDriver::~BugDriver() {
@@ -97,7 +97,7 @@ Module *llvm::ParseInputFile(const std::string &Filename,
 
       if (TheTriple.getTriple().empty())
         TheTriple.setTriple(sys::getHostTriple());
-        
+
       TargetTriple.setTriple(TheTriple.getTriple());
     }
 
@@ -118,7 +118,7 @@ bool BugDriver::addSources(const std::vector<std::string> \
&Filenames) {  // Load the first input file.
   Program = ParseInputFile(Filenames[0], Context);
   if (Program == 0) return true;
-    
+
   outs() << "Read input file      : '" << Filenames[0] << "'\n";
 
   for (unsigned i = 1, e = Filenames.size(); i != e; ++i) {
@@ -152,12 +152,12 @@ bool BugDriver::run(std::string &ErrMsg) {
     return runManyPasses(PassesToRun, ErrMsg);
   }
 
-  // If we're not running as a child, the first thing that we must do is 
-  // determine what the problem is. Does the optimization series crash the 
-  // compiler, or does it produce illegal code?  We make the top-level 
-  // decision by trying to run all of the passes on the the input program, 
-  // which should generate a bitcode file.  If it does generate a bitcode 
-  // file, then we know the compiler didn't crash, so try to diagnose a 
+  // If we're not running as a child, the first thing that we must do is
+  // determine what the problem is. Does the optimization series crash the
+  // compiler, or does it produce illegal code?  We make the top-level
+  // decision by trying to run all of the passes on the the input program,
+  // which should generate a bitcode file.  If it does generate a bitcode
+  // file, then we know the compiler didn't crash, so try to diagnose a
   // miscompilation.
   if (!PassesToRun.empty()) {
     outs() << "Running selected passes on program to test for crash: ";
@@ -197,7 +197,7 @@ bool BugDriver::run(std::string &ErrMsg) {
   FileRemover RemoverInstance(ROF.str(), CreatedOutput && !SaveTemps);
 
   // Diff the output of the raw program against the reference output.  If it
-  // matches, then we assume there is a miscompilation bug and try to 
+  // matches, then we assume there is a miscompilation bug and try to
   // diagnose it.
   outs() << "*** Checking the code generator...\n";
   bool Diff = diffProgram(Program, "", "", false, &Error);
Modified: tools/bugpoint/Miscompilation.cpp
===================================================================
--- a/tools/bugpoint/Miscompilation.cpp
+++ b/tools/bugpoint/Miscompilation.cpp
@@ -34,12 +34,12 @@ namespace llvm {
 }
 
 namespace {
-  static llvm::cl::opt<bool> 
-    DisableLoopExtraction("disable-loop-extraction", 
+  static llvm::cl::opt<bool>
+    DisableLoopExtraction("disable-loop-extraction",
         cl::desc("Don't extract loops when searching for miscompilations"),
         cl::init(false));
-  static llvm::cl::opt<bool> 
-    DisableBlockExtraction("disable-block-extraction", 
+  static llvm::cl::opt<bool>
+    DisableBlockExtraction("disable-block-extraction",
         cl::desc("Don't extract blocks when searching for miscompilations"),
         cl::init(false));
 
@@ -75,7 +75,7 @@ ReduceMiscompilingPasses::doTest(std::vector<std::string> &Prefix,
     BD.EmitProgressBitcode(BD.getProgram(), "pass-error",  false);
     exit(BD.debugOptimizerCrash());
   }
-  
+
   // Check to see if the finished program matches the reference output...
   bool Diff = BD.diffProgram(BD.getProgram(), BitcodeResult, "",
                              true /*delete bitcode*/, &Error);
@@ -309,7 +309,7 @@ static bool ExtractLoops(BugDriver &BD,
   bool MadeChange = false;
   while (1) {
     if (BugpointIsInterrupted) return MadeChange;
-    
+
     ValueToValueMapTy VMap;
     Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap);
     Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
@@ -354,7 +354,7 @@ static bool ExtractLoops(BugDriver &BD,
       BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to-le.bc",
                             ToOptimizeLoopExtracted);
 
-      errs() << "Please submit the " 
+      errs() << "Please submit the "
              << OutputPrefix << "-loop-extract-fail-*.bc files.\n";
       delete ToOptimize;
       delete ToNotOptimize;
@@ -409,9 +409,9 @@ static bool ExtractLoops(BugDriver &BD,
     MiscompiledFunctions.clear();
     for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) {
       Function *NewF = ToNotOptimize->getFunction(MisCompFunctions[i].first);
-                                                  
+
       assert(NewF && "Function not found??");
-      assert(NewF->getFunctionType() == MisCompFunctions[i].second && 
+      assert(NewF->getFunctionType() == MisCompFunctions[i].second &&
              "found wrong function type?");
       MiscompiledFunctions.push_back(NewF);
     }
@@ -523,7 +523,7 @@ static bool ExtractBlocks(BugDriver &BD,
                           std::vector<Function*> &MiscompiledFunctions,
                           std::string &Error) {
   if (BugpointIsInterrupted) return false;
-  
+
   std::vector<BasicBlock*> Blocks;
   for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i)
     for (Function::iterator I = MiscompiledFunctions[i]->begin(),
@@ -593,7 +593,7 @@ static bool ExtractBlocks(BugDriver &BD,
   for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) {
     Function *NewF = ProgClone->getFunction(MisCompFunctions[i].first);
     assert(NewF && "Function not found??");
-    assert(NewF->getFunctionType() == MisCompFunctions[i].second && 
+    assert(NewF->getFunctionType() == MisCompFunctions[i].second &&
            "Function has wrong type??");
     MiscompiledFunctions.push_back(NewF);
   }
@@ -731,7 +731,7 @@ void BugDriver::debugMiscompilation(std::string *Error) {
          << getPassesString(getPassesToRun()) << '\n';
   EmitProgressBitcode(Program, "passinput");
 
-  std::vector<Function *> MiscompiledFunctions = 
+  std::vector<Function *> MiscompiledFunctions =
     DebugAMiscompilation(*this, TestOptimizer, *Error);
   if (!Error->empty())
     return;
@@ -845,7 +845,7 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module \
*&Test,  // Create a new global to hold the cached function pointer.
           Constant *NullPtr = ConstantPointerNull::get(F->getType());
           GlobalVariable *Cache =
-            new GlobalVariable(*F->getParent(), F->getType(), 
+            new GlobalVariable(*F->getParent(), F->getType(),
                                false, GlobalValue::InternalLinkage,
                                NullPtr,F->getName()+".fpcache");
 


   Commit: 716883d0a94abf5405de8a028fc037c4812ac3b9
   Author: Bruno Cardoso Lopes <bruno.cardoso@gmail.com>
     Date: 03/31/2011 10:52:28
      URL: https://github.com/mono/llvm/commit/716883d0a94abf5405de8a028fc037c4812ac3b9


Reapply r128585 without generating a lib depedency cycle. An updated log:

- Implement asm parsing support for LDRT, LDRBT, STRT, STRBT and
  {STR,LDC}{2}_{PRE,POST} fixing the encoding wherever is possible.
- Move all instructions which use am2offset without a pattern to use
  addrmode2.
- Add a new encoding bit to describe the index mode used and teach
  printAddrMode2Operand to check by the addressing mode which index
  mode to print.
- Testcases

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

Changed paths:
 M lib/Target/ARM/ARMAddressingModes.h
 M lib/Target/ARM/ARMBaseInfo.h
 M lib/Target/ARM/ARMBaseInstrInfo.h
 M lib/Target/ARM/ARMInstrFormats.td
 M lib/Target/ARM/ARMInstrInfo.td
 M lib/Target/ARM/AsmParser/ARMAsmParser.cpp
 M lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
 M lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
 M lib/Target/ARM/InstPrinter/ARMInstPrinter.h
Added paths:
 A test/MC/ARM/arm_addrmode2.s

Modified: lib/Target/ARM/ARMAddressingModes.h
===================================================================
--- a/lib/Target/ARM/ARMAddressingModes.h
+++ b/lib/Target/ARM/ARMAddressingModes.h
@@ -408,16 +408,18 @@ namespace ARM_AM {
   //
   // The first operand is always a Reg.  The second operand is a reg if in
   // reg/reg form, otherwise it's reg#0.  The third field encodes the operation
-  // in bit 12, the immediate in bits 0-11, and the shift op in 13-15.
+  // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The
+  // forth operand 16-17 encodes the index mode.
   //
   // If this addressing mode is a frame index (before prolog/epilog insertion
   // and code rewriting), this operand will have the form:  FI#, reg0, <offs>
   // with no shift amount for the frame offset.
   //
-  static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO) {
+  static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO,
+                                   unsigned IdxMode = 0) {
     assert(Imm12 < (1 << 12) && "Imm too large!");
     bool isSub = Opc == sub;
-    return Imm12 | ((int)isSub << 12) | (SO << 13);
+    return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ;
   }
   static inline unsigned getAM2Offset(unsigned AM2Opc) {
     return AM2Opc & ((1 << 12)-1);
@@ -426,7 +428,10 @@ namespace ARM_AM {
     return ((AM2Opc >> 12) & 1) ? sub : add;
   }
   static inline ShiftOpc getAM2ShiftOpc(unsigned AM2Opc) {
-    return (ShiftOpc)(AM2Opc >> 13);
+    return (ShiftOpc)((AM2Opc >> 13) & 7);
+  }
+  static inline unsigned getAM2IdxMode(unsigned AM2Opc) {
+    return (AM2Opc >> 16);
   }
 
 
Modified: lib/Target/ARM/ARMBaseInfo.h
===================================================================
--- a/lib/Target/ARM/ARMBaseInfo.h
+++ b/lib/Target/ARM/ARMBaseInfo.h
@@ -200,6 +200,59 @@ inline static unsigned getARMRegisterNumbering(unsigned Reg) {
 }
 
 namespace ARMII {
+
+  /// ARM Index Modes
+  enum IndexMode {
+    IndexModeNone  = 0,
+    IndexModePre   = 1,
+    IndexModePost  = 2,
+    IndexModeUpd   = 3
+  };
+
+  /// ARM Addressing Modes
+  enum AddrMode {
+    AddrModeNone    = 0,
+    AddrMode1       = 1,
+    AddrMode2       = 2,
+    AddrMode3       = 3,
+    AddrMode4       = 4,
+    AddrMode5       = 5,
+    AddrMode6       = 6,
+    AddrModeT1_1    = 7,
+    AddrModeT1_2    = 8,
+    AddrModeT1_4    = 9,
+    AddrModeT1_s    = 10, // i8 * 4 for pc and sp relative data
+    AddrModeT2_i12  = 11,
+    AddrModeT2_i8   = 12,
+    AddrModeT2_so   = 13,
+    AddrModeT2_pc   = 14, // +/- i12 for pc relative data
+    AddrModeT2_i8s4 = 15, // i8 * 4
+    AddrMode_i12    = 16
+  };
+
+  inline static const char *AddrModeToString(AddrMode addrmode) {
+    switch (addrmode) {
+    default: llvm_unreachable("Unknown memory operation");
+    case AddrModeNone:    return "AddrModeNone";
+    case AddrMode1:       return "AddrMode1";
+    case AddrMode2:       return "AddrMode2";
+    case AddrMode3:       return "AddrMode3";
+    case AddrMode4:       return "AddrMode4";
+    case AddrMode5:       return "AddrMode5";
+    case AddrMode6:       return "AddrMode6";
+    case AddrModeT1_1:    return "AddrModeT1_1";
+    case AddrModeT1_2:    return "AddrModeT1_2";
+    case AddrModeT1_4:    return "AddrModeT1_4";
+    case AddrModeT1_s:    return "AddrModeT1_s";
+    case AddrModeT2_i12:  return "AddrModeT2_i12";
+    case AddrModeT2_i8:   return "AddrModeT2_i8";
+    case AddrModeT2_so:   return "AddrModeT2_so";
+    case AddrModeT2_pc:   return "AddrModeT2_pc";
+    case AddrModeT2_i8s4: return "AddrModeT2_i8s4";
+    case AddrMode_i12:    return "AddrMode_i12";
+    }
+  }
+
   /// Target Operand Flag enum.
   enum TOF {
     //===------------------------------------------------------------------===//
Modified: lib/Target/ARM/ARMBaseInstrInfo.h
===================================================================
--- a/lib/Target/ARM/ARMBaseInstrInfo.h
+++ b/lib/Target/ARM/ARMBaseInstrInfo.h
@@ -34,25 +34,7 @@ namespace ARMII {
 
     //===------------------------------------------------------------------===//
     // This four-bit field describes the addressing mode used.
-
-    AddrModeMask  = 0x1f,
-    AddrModeNone    = 0,
-    AddrMode1       = 1,
-    AddrMode2       = 2,
-    AddrMode3       = 3,
-    AddrMode4       = 4,
-    AddrMode5       = 5,
-    AddrMode6       = 6,
-    AddrModeT1_1    = 7,
-    AddrModeT1_2    = 8,
-    AddrModeT1_4    = 9,
-    AddrModeT1_s    = 10, // i8 * 4 for pc and sp relative data
-    AddrModeT2_i12  = 11,
-    AddrModeT2_i8   = 12,
-    AddrModeT2_so   = 13,
-    AddrModeT2_pc   = 14, // +/- i12 for pc relative data
-    AddrModeT2_i8s4 = 15, // i8 * 4
-    AddrMode_i12    = 16,
+    AddrModeMask  = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h
 
     // Size* - Flags to keep track of the size of an instruction.
     SizeShift     = 5,
@@ -64,11 +46,9 @@ namespace ARMII {
 
     // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load
     // and store ops only.  Generic "updating" flag is used for ld/st multiple.
+    // The index mode enums are declared in ARMBaseInfo.h
     IndexModeShift = 8,
     IndexModeMask  = 3 << IndexModeShift,
-    IndexModePre   = 1,
-    IndexModePost  = 2,
-    IndexModeUpd   = 3,
 
     //===------------------------------------------------------------------===//
     // Instruction encoding formats.
Modified: lib/Target/ARM/ARMInstrFormats.td
===================================================================
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -515,15 +515,15 @@ class AI2stridx<bit isByte, bit isPre, dag oops, dag iops,
   : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
                pattern> {
   // AM2 store w/ two operands: (GPR, am2offset)
+  // {17-14}  Rn
   // {13}     1 == Rm, 0 == imm12
   // {12}     isAdd
   // {11-0}   imm12/Rm
-  bits<14> offset;
-  bits<4> Rn;
-  let Inst{25} = offset{13};
-  let Inst{23} = offset{12};
-  let Inst{19-16} = Rn;
-  let Inst{11-0} = offset{11-0};
+  bits<18> addr;
+  let Inst{25} = addr{13};
+  let Inst{23} = addr{12};
+  let Inst{19-16} = addr{17-14};
+  let Inst{11-0} = addr{11-0};
 }
 
 // addrmode3 instructions
Modified: lib/Target/ARM/ARMInstrInfo.td
===================================================================
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -498,6 +498,12 @@ def ldst_so_reg : Operand<i32>,
   let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
 }
 
+def MemMode2AsmOperand : AsmOperandClass {
+  let Name = "MemMode2";
+  let SuperClasses = [];
+  let ParserMethod = "tryParseMemMode2Operand";
+}
+
 // addrmode2 := reg +/- imm12
 //           := reg +/- reg shop imm
 //
@@ -505,6 +511,7 @@ def addrmode2 : Operand<i32>,
                 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
   let EncoderMethod = "getAddrMode2OpValue";
   let PrintMethod = "printAddrMode2Operand";
+  let ParserMatchClass = MemMode2AsmOperand;
   let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
 }
 
@@ -1656,20 +1663,21 @@ multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass \
itin> {  let Inst{23} = addr{12};
     let Inst{19-16} = addr{17-14};
     let Inst{11-0} = addr{11-0};
+    let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
   }
   def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
-                      (ins GPR:$Rn, am2offset:$offset),
-                      IndexModePost, LdFrm, itin,
-                      opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
+                      (ins addrmode2:$addr), IndexModePost, LdFrm, itin,
+                      opc, "\t$Rt, $addr", "$addr.base = $Rn_wb", []> {
+    // {17-14}  Rn
     // {13}     1 == Rm, 0 == imm12
     // {12}     isAdd
     // {11-0}   imm12/Rm
-    bits<14> offset;
-    bits<4> Rn;
-    let Inst{25} = offset{13};
-    let Inst{23} = offset{12};
-    let Inst{19-16} = Rn;
-    let Inst{11-0} = offset{11-0};
+    bits<18> addr;
+    let Inst{25} = addr{13};
+    let Inst{23} = addr{12};
+    let Inst{19-16} = addr{17-14};
+    let Inst{11-0} = addr{11-0};
+    let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
   }
 }
 
@@ -1714,17 +1722,35 @@ defm LDRD :  AI3_ldridx<0b1101, 0, "ldrd", IIC_iLoad_d_ru>;
 
 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
 let mayLoad = 1, neverHasSideEffects = 1 in {
-def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
-                   (ins GPR:$base, am2offset:$offset), IndexModePost,
-                   LdFrm, IIC_iLoad_ru,
-                   "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
+def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb),
+                   (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_ru,
+                   "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
+  // {17-14}  Rn
+  // {13}     1 == Rm, 0 == imm12
+  // {12}     isAdd
+  // {11-0}   imm12/Rm
+  bits<18> addr;
+  let Inst{25} = addr{13};
+  let Inst{23} = addr{12};
   let Inst{21} = 1; // overwrite
-}
-def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
-                  (ins GPR:$base, am2offset:$offset), IndexModePost,
-                  LdFrm, IIC_iLoad_bh_ru,
-                  "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
+  let Inst{19-16} = addr{17-14};
+  let Inst{11-0} = addr{11-0};
+  let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
+}
+def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb),
+                  (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_bh_ru,
+                  "ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
+  // {17-14}  Rn
+  // {13}     1 == Rm, 0 == imm12
+  // {12}     isAdd
+  // {11-0}   imm12/Rm
+  bits<18> addr;
+  let Inst{25} = addr{13};
+  let Inst{23} = addr{12};
   let Inst{21} = 1; // overwrite
+  let Inst{19-16} = addr{17-14};
+  let Inst{11-0} = addr{11-0};
+  let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
 }
 def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
                  (ins GPR:$base, am3offset:$offset), IndexModePost,
@@ -1818,20 +1844,20 @@ def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
 
 // STRT, STRBT, and STRHT are for disassembly only.
 
-def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb),
-                    (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
+def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr),
                     IndexModePost, StFrm, IIC_iStore_ru,
-                    "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
+                    "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb",
                     [/* For disassembly only; pattern left blank */]> {
   let Inst{21} = 1; // overwrite
+  let AsmMatchConverter = "CvtStWriteBackRegAddrMode2";
 }
 
-def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb),
-                     (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
+def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr),
                      IndexModePost, StFrm, IIC_iStore_bh_ru,
-                     "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
+                     "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb",
                      [/* For disassembly only; pattern left blank */]> {
   let Inst{21} = 1; // overwrite
+  let AsmMatchConverter = "CvtStWriteBackRegAddrMode2";
 }
 
 def STRHT: AI3sthpo<(outs GPR:$base_wb),
@@ -3391,8 +3417,9 @@ def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
   let Inst{23-20} = opc1;
 }
 
-class ACI<dag oops, dag iops, string opc, string asm>
-  : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
+class ACI<dag oops, dag iops, string opc, string asm,
+          IndexMode im = IndexModeNone>
+  : I<oops, iops, AddrModeNone, Size4Bytes, im, BrFrm, NoItinerary,
       opc, asm, "", [/* For disassembly only; pattern left blank */]> {
   let Inst{27-25} = 0b110;
 }
@@ -3411,7 +3438,7 @@ multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
 
   def _PRE : ACI<(outs),
       (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
-      opc, "\tp$cop, cr$CRd, $addr!"> {
+      opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> {
     let Inst{31-28} = op31_28;
     let Inst{24} = 1; // P = 1
     let Inst{21} = 1; // W = 1
@@ -3420,8 +3447,8 @@ multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
   }
 
   def _POST : ACI<(outs),
-      (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
-      opc, "\tp$cop, cr$CRd, [$base], $offset"> {
+      (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
+      opc, "\tp$cop, cr$CRd, $addr", IndexModePost> {
     let Inst{31-28} = op31_28;
     let Inst{24} = 0; // P = 0
     let Inst{21} = 1; // W = 1
@@ -3452,7 +3479,7 @@ multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
 
   def L_PRE : ACI<(outs),
       (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
-      !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
+      !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> {
     let Inst{31-28} = op31_28;
     let Inst{24} = 1; // P = 1
     let Inst{21} = 1; // W = 1
@@ -3461,8 +3488,8 @@ multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
   }
 
   def L_POST : ACI<(outs),
-      (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
-      !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
+      (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
+      !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr", IndexModePost> {
     let Inst{31-28} = op31_28;
     let Inst{24} = 0; // P = 0
     let Inst{21} = 1; // W = 1
Modified: lib/Target/ARM/AsmParser/ARMAsmParser.cpp
===================================================================
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -48,7 +48,8 @@ class ARMAsmParser : public TargetAsmParser {
   bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
   bool TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
   bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
-  bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
+  bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &,
+                   ARMII::AddrMode AddrMode);
   bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
   bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
   const MCExpr *ApplyPrefixToExpr(const MCExpr *E,
@@ -95,6 +96,14 @@ class ARMAsmParser : public TargetAsmParser {
     SmallVectorImpl<MCParsedAsmOperand*>&);
   OperandMatchResultTy tryParseMSRMaskOperand(
     SmallVectorImpl<MCParsedAsmOperand*>&);
+  OperandMatchResultTy tryParseMemMode2Operand(
+    SmallVectorImpl<MCParsedAsmOperand*>&);
+
+  // Asm Match Converter Methods
+  bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
+                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
+  bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
+                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
 
 public:
   ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM)
@@ -172,6 +181,7 @@ class ARMOperand : public MCParsedAsmOperand {
 
     /// Combined record for all forms of ARM address expressions.
     struct {
+      ARMII::AddrMode AddrMode;
       unsigned BaseRegNum;
       union {
         unsigned RegNum;     ///< Offset register num, when OffsetIsReg.
@@ -293,7 +303,9 @@ public:
 
   /// @name Memory Operand Accessors
   /// @{
-
+  ARMII::AddrMode getMemAddrMode() const {
+    return Mem.AddrMode;
+  }
   unsigned getMemBaseRegNum() const {
     return Mem.BaseRegNum;
   }
@@ -338,6 +350,27 @@ public:
   bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
   bool isMemory() const { return Kind == Memory; }
   bool isShifter() const { return Kind == Shifter; }
+  bool isMemMode2() const {
+    if (getMemAddrMode() != ARMII::AddrMode2)
+      return false;
+
+    if (getMemOffsetIsReg())
+      return true;
+
+    if (getMemNegative() &&
+        !(getMemPostindexed() || getMemPreindexed()))
+      return false;
+
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
+    if (!CE) return false;
+    int64_t Value = CE->getValue();
+
+    // The offset must be in the range 0-4095 (imm12).
+    if (Value > 4095 || Value < -4095)
+      return false;
+
+    return true;
+  }
   bool isMemMode5() const {
     if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() ||
         getMemNegative())
@@ -465,6 +498,47 @@ public:
            "No offset operand support in mode 7");
   }
 
+  void addMemMode2Operands(MCInst &Inst, unsigned N) const {
+    assert(isMemMode2() && "Invalid mode or number of operands!");
+    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
+    unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
+
+    if (getMemOffsetIsReg()) {
+      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
+
+      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
+      ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift;
+      int64_t ShiftAmount = 0;
+
+      if (getMemOffsetRegShifted()) {
+        ShOpc = getMemShiftType();
+        const MCConstantExpr *CE =
+                   dyn_cast<MCConstantExpr>(getMemShiftAmount());
+        ShiftAmount = CE->getValue();
+      }
+
+      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount,
+                                           ShOpc, IdxMode)));
+      return;
+    }
+
+    // Create a operand placeholder to always yield the same number of operands.
+    Inst.addOperand(MCOperand::CreateReg(0));
+
+    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
+    // the difference?
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
+    assert(CE && "Non-constant mode 2 offset operand!");
+    int64_t Offset = CE->getValue();
+
+    if (Offset >= 0)
+      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add,
+                                           Offset, ARM_AM::no_shift, IdxMode)));
+    else
+      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub,
+                                          -Offset, ARM_AM::no_shift, IdxMode)));
+  }
+
   void addMemMode5Operands(MCInst &Inst, unsigned N) const {
     assert(N == 2 && isMemMode5() && "Invalid number of operands!");
 
@@ -599,9 +673,9 @@ public:
     return Op;
   }
 
-  static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg,
-                               const MCExpr *Offset, int OffsetRegNum,
-                               bool OffsetRegShifted,
+  static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum,
+                               bool OffsetIsReg, const MCExpr *Offset,
+                               int OffsetRegNum, bool OffsetRegShifted,
                                enum ARM_AM::ShiftOpc ShiftType,
                                const MCExpr *ShiftAmount, bool Preindexed,
                                bool Postindexed, bool Negative, bool Writeback,
@@ -618,6 +692,7 @@ public:
            "Cannot have expression offset and register offset!");
 
     ARMOperand *Op = new ARMOperand(Memory);
+    Op->Mem.AddrMode = AddrMode;
     Op->Mem.BaseRegNum = BaseRegNum;
     Op->Mem.OffsetIsReg = OffsetIsReg;
     if (OffsetIsReg)
@@ -689,7 +764,8 @@ void ARMOperand::dump(raw_ostream &OS) const {
     break;
   case Memory:
     OS << "<memory "
-       << "base:" << getMemBaseRegNum();
+       << "am:" << ARMII::AddrModeToString(getMemAddrMode())
+       << " base:" << getMemBaseRegNum();
     if (getMemOffsetIsReg()) {
       OS << " offset:<register " << getMemOffsetRegNum();
       if (getMemOffsetRegShifted()) {
@@ -1132,13 +1208,57 @@ tryParseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> \
&Operands) {  return MatchOperand_Success;
 }
 
+/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand.
+ARMAsmParser::OperandMatchResultTy ARMAsmParser::
+tryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+  SMLoc S = Parser.getTok().getLoc();
+  const AsmToken &Tok = Parser.getTok();
+  assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\"");
+
+  if (ParseMemory(Operands, ARMII::AddrMode2))
+    return MatchOperand_NoMatch;
+
+  return MatchOperand_Success;
+}
+
+/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
+/// Needed here because the Asm Gen Matcher can't handle properly tied operands
+/// when they refer multiple MIOperands inside a single one.
+bool ARMAsmParser::
+CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
+                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
+
+  // Create a writeback register dummy placeholder.
+  Inst.addOperand(MCOperand::CreateImm(0));
+
+  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
+  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
+  return true;
+}
+
+/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
+/// Needed here because the Asm Gen Matcher can't handle properly tied operands
+/// when they refer multiple MIOperands inside a single one.
+bool ARMAsmParser::
+CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
+                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+  // Create a writeback register dummy placeholder.
+  Inst.addOperand(MCOperand::CreateImm(0));
+  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
+  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
+  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
+  return true;
+}
+
 /// Parse an ARM memory expression, return false if successful else return true
 /// or an error.  The first token must be a '[' when called.
 ///
 /// TODO Only preindexing and postindexing addressing are started, unindexed
 /// with option, etc are still to do.
 bool ARMAsmParser::
-ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+            ARMII::AddrMode AddrMode = ARMII::AddrModeNone) {
   SMLoc S, E;
   assert(Parser.getTok().is(AsmToken::LBrac) &&
          "Token is not a Left Bracket");
@@ -1196,6 +1316,9 @@ ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
                                      ExclaimTok.getLoc());
       Writeback = true;
       Parser.Lex(); // Eat exclaim token
+    } else { // In addressing mode 2, pre-indexed mode always end with "!"
+      if (AddrMode == ARMII::AddrMode2)
+        Preindexed = false;
     }
   } else {
     // The "[Rn" we have so far was not followed by a comma.
@@ -1231,11 +1354,10 @@ ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
       Offset = MCConstantExpr::Create(0, getContext());
   }
 
-  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset,
-                                           OffsetRegNum, OffsetRegShifted,
-                                           ShiftType, ShiftAmount, Preindexed,
-                                           Postindexed, Negative, Writeback,
-                                           S, E));
+  Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg,
+                                     Offset, OffsetRegNum, OffsetRegShifted,
+                                     ShiftType, ShiftAmount, Preindexed,
+                                     Postindexed, Negative, Writeback, S, E));
   if (WBOp)
     Operands.push_back(WBOp);
 
Modified: lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
===================================================================
--- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
@@ -643,8 +643,11 @@ static bool DisassembleCoprocessor(MCInst &MI, unsigned Opcode, \
uint32_t insn,  if (PW) {
       MI.addOperand(MCOperand::CreateReg(0));
       ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub;
+      const TargetInstrDesc &TID = ARMInsts[Opcode];
+      unsigned IndexMode =
+                  (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
       unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, slice(insn, 7, 0) << 2,
-                                          ARM_AM::no_shift);
+                                          ARM_AM::no_shift, IndexMode);
       MI.addOperand(MCOperand::CreateImm(Offset));
       OpIdx = 5;
     } else {
@@ -1073,6 +1076,8 @@ static bool DisassembleLdStFrm(MCInst &MI, unsigned Opcode, \
uint32_t insn,  return false;
 
   ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub;
+  unsigned IndexMode =
+               (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
   if (getIBit(insn) == 0) {
     // For pre- and post-indexed case, add a reg0 operand (Addressing Mode #2).
     // Otherwise, skip the reg operand since for addrmode_imm12, Rn has already
@@ -1084,7 +1089,8 @@ static bool DisassembleLdStFrm(MCInst &MI, unsigned Opcode, \
uint32_t insn,  
     // Disassemble the 12-bit immediate offset.
     unsigned Imm12 = slice(insn, 11, 0);
-    unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift);
+    unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift,
+                                        IndexMode);
     MI.addOperand(MCOperand::CreateImm(Offset));
     OpIdx += 1;
   } else {
@@ -1099,7 +1105,7 @@ static bool DisassembleLdStFrm(MCInst &MI, unsigned Opcode, \
uint32_t insn,  // A8.4.1.  Possible rrx or shift amount of 32...
     getImmShiftSE(ShOp, ShImm);
     MI.addOperand(MCOperand::CreateImm(
-                    ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp)));
+                    ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp, IndexMode)));
     OpIdx += 2;
   }
 
Modified: lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
===================================================================
--- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
+++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
@@ -181,18 +181,12 @@ void ARMInstPrinter::printSORegOperand(const MCInst *MI, \
unsigned OpNum,  }
 }
 
-
-void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
-                                           raw_ostream &O) {
+void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
+                                                raw_ostream &O) {
   const MCOperand &MO1 = MI->getOperand(Op);
   const MCOperand &MO2 = MI->getOperand(Op+1);
   const MCOperand &MO3 = MI->getOperand(Op+2);
 
-  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
-    printOperand(MI, Op, O);
-    return;
-  }
-
   O << "[" << getRegisterName(MO1.getReg());
 
   if (!MO2.getReg()) {
@@ -215,6 +209,50 @@ void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, \
unsigned Op,  O << "]";
 }
 
+void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op,
+                                         raw_ostream &O) {
+  const MCOperand &MO1 = MI->getOperand(Op);
+  const MCOperand &MO2 = MI->getOperand(Op+1);
+  const MCOperand &MO3 = MI->getOperand(Op+2);
+
+  O << "[" << getRegisterName(MO1.getReg()) << "], ";
+
+  if (!MO2.getReg()) {
+    unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm());
+    O << '#'
+      << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
+      << ImmOffs;
+    return;
+  }
+
+  O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
+    << getRegisterName(MO2.getReg());
+
+  if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
+    O << ", "
+    << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
+    << " #" << ShImm;
+}
+
+void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
+                                           raw_ostream &O) {
+  const MCOperand &MO1 = MI->getOperand(Op);
+
+  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
+    printOperand(MI, Op, O);
+    return;
+  }
+
+  const MCOperand &MO3 = MI->getOperand(Op+2);
+  unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm());
+
+  if (IdxMode == ARMII::IndexModePost) {
+    printAM2PostIndexOp(MI, Op, O);
+    return;
+  }
+  printAM2PreOrOffsetIndexOp(MI, Op, O);
+}
+
 void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
                                                  unsigned OpNum,
                                                  raw_ostream &O) {
Modified: lib/Target/ARM/InstPrinter/ARMInstPrinter.h
===================================================================
--- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
+++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
@@ -42,7 +42,11 @@ public:
   void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
 
   void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+
   void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+  void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+  void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum,
+                                  raw_ostream &O);
   void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum,
                                    raw_ostream &O);
   void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);

Added: test/MC/ARM/arm_addrmode2.s
===================================================================
--- /dev/null
+++ b/test/MC/ARM/arm_addrmode2.s
@@ -0,0 +1,39 @@
+@ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding %s | \
FileCheck %s +
+@ Post-indexed
+@ CHECK: ldrt  r1, [r0], r2 @ encoding: [0x02,0x10,0xb0,0xe6]
+@ CHECK: ldrt  r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xb0,0xe6]
+@ CHECK: ldrt  r1, [r0], #4 @ encoding: [0x04,0x10,0xb0,0xe4]
+@ CHECK: ldrbt  r1, [r0], r2 @ encoding: [0x02,0x10,0xf0,0xe6]
+@ CHECK: ldrbt  r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xf0,0xe6]
+@ CHECK: ldrbt  r1, [r0], #4 @ encoding: [0x04,0x10,0xf0,0xe4]
+@ CHECK: strt  r1, [r0], r2 @ encoding: [0x02,0x10,0xa0,0xe6]
+@ CHECK: strt  r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xa0,0xe6]
+@ CHECK: strt  r1, [r0], #4 @ encoding: [0x04,0x10,0xa0,0xe4]
+@ CHECK: strbt  r1, [r0], r2 @ encoding: [0x02,0x10,0xe0,0xe6]
+@ CHECK: strbt  r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xe0,0xe6]
+@ CHECK: strbt  r1, [r0], #4 @ encoding: [0x04,0x10,0xe0,0xe4]
+@ CHECK: ldr  r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0x90,0xe6]
+@ CHECK: ldrb  r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xd0,0xe6]
+        ldrt  r1, [r0], r2
+        ldrt  r1, [r0], r2, lsr #3
+        ldrt  r1, [r0], #4
+        ldrbt  r1, [r0], r2
+        ldrbt  r1, [r0], r2, lsr #3
+        ldrbt  r1, [r0], #4
+        strt  r1, [r0], r2
+        strt  r1, [r0], r2, lsr #3
+        strt  r1, [r0], #4
+        strbt  r1, [r0], r2
+        strbt  r1, [r0], r2, lsr #3
+        strbt  r1, [r0], #4
+        ldr  r1, [r0], r2, lsr #3
+        ldrb  r1, [r0], r2, lsr #3
+
+@ Pre-indexed
+@ CHECK: ldr  r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xb0,0xe7]
+@ CHECK: ldrb  r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xf0,0xe7]
+        ldr  r1, [r0, r2, lsr #3]!
+        ldrb  r1, [r0, r2, lsr #3]!
+
+



   Commit: 53185177680ecc0bf3b9cf526b7e3459d6884a18
   Author: Richard Osborne <richard@xmos.com>
     Date: 03/31/2011 11:13:13
      URL: https://github.com/mono/llvm/commit/53185177680ecc0bf3b9cf526b7e3459d6884a18


Add XCore intrinsics for initializing / starting / synchronizing threads.


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

Changed paths:
 M include/llvm/IntrinsicsXCore.td
 M lib/Target/XCore/XCoreInstrInfo.td
Added paths:
 A test/CodeGen/XCore/threads.ll

Modified: include/llvm/IntrinsicsXCore.td
===================================================================
--- a/include/llvm/IntrinsicsXCore.td
+++ b/include/llvm/IntrinsicsXCore.td
@@ -69,4 +69,21 @@ let TargetPrefix = "xcore" in {  // All intrinsics start with \
"llvm.xcore.".  def int_xcore_checkevent : Intrinsic<[llvm_ptr_ty],[llvm_ptr_ty]>;
 
   def int_xcore_clre : Intrinsic<[],[],[]>;
+
+  // Intrinsics for threads.
+  def int_xcore_getst : Intrinsic <[llvm_anyptr_ty],[llvm_anyptr_ty],
+                                   [NoCapture<0>]>;
+  def int_xcore_msync : Intrinsic <[],[llvm_anyptr_ty], [NoCapture<0>]>;
+  def int_xcore_ssync : Intrinsic <[],[]>;
+  def int_xcore_mjoin : Intrinsic <[],[llvm_anyptr_ty], [NoCapture<0>]>;
+  def int_xcore_initsp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+                                    [NoCapture<0>]>;
+  def int_xcore_initpc : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+                                    [NoCapture<0>]>;
+  def int_xcore_initlr : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+                                    [NoCapture<0>]>;
+  def int_xcore_initcp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+                                    [NoCapture<0>]>;
+  def int_xcore_initdp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+                                    [NoCapture<0>]>;
 }
Modified: lib/Target/XCore/XCoreInstrInfo.td
===================================================================
--- a/lib/Target/XCore/XCoreInstrInfo.td
+++ b/lib/Target/XCore/XCoreInstrInfo.td
@@ -739,7 +739,7 @@ def BL_lu10 : _FLU10<
 }
 
 // Two operand short
-// TODO getr, getst
+// TODO eet, eef, testwct, tsetmr, sext (reg), zext (reg)
 def NOT : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b),
                  "not $dst, $b",
                  [(set GRRegs:$dst, (not GRRegs:$b))]>;
@@ -748,8 +748,6 @@ def NEG : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b),
                  "neg $dst, $b",
                  [(set GRRegs:$dst, (ineg GRRegs:$b))]>;
 
-// TODO setd, eet, eef, testwct, tinitpc, tinitdp,
-// tinitsp, tinitcp, tsetmr, sext (reg), zext (reg)
 let Constraints = "$src1 = $dst" in {
 let neverHasSideEffects = 1 in
 def SEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2),
@@ -837,9 +835,29 @@ def SETD_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val),
                  "setd res[$r], $val",
                  [(int_xcore_setd GRRegs:$r, GRRegs:$val)]>;
 
+def GETST_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r),
+                    "getst $dst, res[$r]",
+                    [(set GRRegs:$dst, (int_xcore_getst GRRegs:$r))]>;
+
+def INITSP_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src),
+                     "init t[$t]:sp, $src",
+                     [(int_xcore_initsp GRRegs:$t, GRRegs:$src)]>;
+
+def INITPC_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src),
+                     "init t[$t]:pc, $src",
+                     [(int_xcore_initpc GRRegs:$t, GRRegs:$src)]>;
+
+def INITCP_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src),
+                     "init t[$t]:cp, $src",
+                     [(int_xcore_initcp GRRegs:$t, GRRegs:$src)]>;
+
+def INITDP_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src),
+                     "init t[$t]:dp, $src",
+                     [(int_xcore_initdp GRRegs:$t, GRRegs:$src)]>;
+
 // Two operand long
 // TODO endin, peek,
-// getd, testlcl, tinitlr
+// getd, testlcl
 def BITREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src),
                  "bitrev $dst, $src",
                  [(set GRRegs:$dst, (int_xcore_bitrev GRRegs:$src))]>;
@@ -868,6 +886,10 @@ def SETPS_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2),
                  "set ps[$src1], $src2",
                  [(int_xcore_setps GRRegs:$src1, GRRegs:$src2)]>;
 
+def INITLR_l2r : _FL2R<(outs), (ins GRRegs:$t, GRRegs:$src),
+                       "init t[$t]:lr, $src",
+                       [(int_xcore_initlr GRRegs:$t, GRRegs:$src)]>;
+
 def SETCLK_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2),
                        "setclk res[$src1], $src2",
                        [(int_xcore_setclk GRRegs:$src1, GRRegs:$src2)]>;
@@ -881,9 +903,16 @@ def SETPSC_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2),
                        [(int_xcore_setpsc GRRegs:$src1, GRRegs:$src2)]>;
 
 // One operand short
-// TODO edu, eeu, waitet, waitef, tstart, msync, mjoin, clrtp
+// TODO edu, eeu, waitet, waitef, tstart, clrtp
 // setdp, setcp, setev, kcall
 // dgetreg
+def MSYNC_1r : _F1R<(outs), (ins GRRegs:$i),
+                    "msync res[$i]",
+		    [(int_xcore_msync GRRegs:$i)]>;
+def MJOIN_1r : _F1R<(outs), (ins GRRegs:$i),
+                    "mjoin res[$i]",
+		    [(int_xcore_mjoin GRRegs:$i)]>;
+
 let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in
 def BAU_1r : _F1R<(outs), (ins GRRegs:$addr),
                  "bau $addr",
@@ -940,7 +969,7 @@ def EEU_1r : _F1R<(outs), (ins GRRegs:$r),
                [(int_xcore_eeu GRRegs:$r)]>;
 
 // Zero operand short
-// TODO ssync, freet, ldspc, stspc, ldssr, stssr, ldsed, stsed,
+// TODO freet, ldspc, stspc, ldssr, stssr, ldsed, stsed,
 // stet, geted, getet, getkep, getksp, setkep, getid, kret, dcall, dret,
 // dentsp, drestsp
 
@@ -951,6 +980,10 @@ def GETID_0R : _F0R<(outs), (ins),
                  "get r11, id",
                  [(set R11, (int_xcore_getid))]>;
 
+def SSYNC_0r : _F0R<(outs), (ins),
+                    "ssync",
+		    [(int_xcore_ssync)]>;
+
 let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1,
     hasSideEffects = 1 in
 def WAITEU_0R : _F0R<(outs), (ins),

Added: test/CodeGen/XCore/threads.ll
===================================================================
--- /dev/null
+++ b/test/CodeGen/XCore/threads.ll
@@ -0,0 +1,68 @@
+; RUN: llc -march=xcore < %s | FileCheck %s
+
+declare i8 addrspace(1)* @llvm.xcore.getst.p1i8.p1i8(i8 addrspace(1)* %r)
+declare void @llvm.xcore.msync.p1i8(i8 addrspace(1)* %r)
+declare void @llvm.xcore.ssync()
+declare void @llvm.xcore.mjoin.p1i8(i8 addrspace(1)* %r)
+declare void @llvm.xcore.initsp.p1i8(i8 addrspace(1)* %r, i8* %value)
+declare void @llvm.xcore.initpc.p1i8(i8 addrspace(1)* %r, i8* %value)
+declare void @llvm.xcore.initlr.p1i8(i8 addrspace(1)* %r, i8* %value)
+declare void @llvm.xcore.initcp.p1i8(i8 addrspace(1)* %r, i8* %value)
+declare void @llvm.xcore.initdp.p1i8(i8 addrspace(1)* %r, i8* %value)
+
+define i8 addrspace(1)* @getst(i8 addrspace(1)* %r) {
+; CHECK: getst:
+; CHECK: getst r0, res[r0]
+        %result = call i8 addrspace(1)* @llvm.xcore.getst.p1i8.p1i8(i8 addrspace(1)* \
%r) +        ret i8 addrspace(1)* %result
+}
+
+define void @ssync() {
+; CHECK: ssync:
+; CHECK: ssync
+	call void @llvm.xcore.ssync()
+	ret void
+}
+
+define void @mjoin(i8 addrspace(1)* %r) {
+; CHECK: mjoin:
+; CHECK: mjoin res[r0]
+	call void @llvm.xcore.mjoin.p1i8(i8 addrspace(1)* %r)
+	ret void
+}
+
+define void @initsp(i8 addrspace(1)* %t, i8* %src) {
+; CHECK: initsp:
+; CHECK: init t[r0]:sp, r1
+        call void @llvm.xcore.initsp.p1i8(i8 addrspace(1)* %t, i8* %src)
+        ret void
+}
+
+define void @initpc(i8 addrspace(1)* %t, i8* %src) {
+; CHECK: initpc:
+; CHECK: init t[r0]:pc, r1
+        call void @llvm.xcore.initpc.p1i8(i8 addrspace(1)* %t, i8* %src)
+        ret void
+}
+
+define void @initlr(i8 addrspace(1)* %t, i8* %src) {
+; CHECK: initlr:
+; CHECK: init t[r0]:lr, r1
+        call void @llvm.xcore.initlr.p1i8(i8 addrspace(1)* %t, i8* %src)
+        ret void
+}
+
+define void @initcp(i8 addrspace(1)* %t, i8* %src) {
+; CHECK: initcp:
+; CHECK: init t[r0]:cp, r1
+        call void @llvm.xcore.initcp.p1i8(i8 addrspace(1)* %t, i8* %src)
+        ret void
+}
+
+define void @initdp(i8 addrspace(1)* %t, i8* %src) {
+; CHECK: initdp:
+; CHECK: init t[r0]:dp, r1
+        call void @llvm.xcore.initdp.p1i8(i8 addrspace(1)* %t, i8* %src)
+        ret void
+}
+



   Commit: 5a336e20280ac7bbb6bd87f1d6d1100e1ea2352f
   Author: Jakob Stoklund Olesen <stoklund@2pi.dk>
     Date: 03/31/2011 11:14:11
      URL: https://github.com/mono/llvm/commit/5a336e20280ac7bbb6bd87f1d6d1100e1ea2352f


Fix bug found by valgrind.

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

Changed paths:
 M lib/CodeGen/LiveIntervalUnion.h

Modified: lib/CodeGen/LiveIntervalUnion.h
===================================================================
--- a/lib/CodeGen/LiveIntervalUnion.h
+++ b/lib/CodeGen/LiveIntervalUnion.h
@@ -166,7 +166,7 @@ public:
     unsigned Tag, UserTag;
 
   public:
-    Query(): LiveUnion(), VirtReg() {}
+    Query(): LiveUnion(), VirtReg(), Tag(0), UserTag(0) {}
 
     Query(LiveInterval *VReg, LiveIntervalUnion *LIU):
       LiveUnion(LIU), VirtReg(VReg), CheckedFirstInterference(false),


   Commit: d9885985ed58dff815260c4677eeac9b2d7a0e50
   Author: Zoltan Varga <vargaz@gmail.com>
     Date: 03/31/2011 11:33:54
      URL: https://github.com/mono/llvm/commit/d9885985ed58dff815260c4677eeac9b2d7a0e50


Merge branch 'master' of http://github.com/earl/llvm-mirror into mono

Changed paths:
 M cmake/modules/AddLLVM.cmake
 M cmake/modules/LLVMConfig.cmake
 M docs/GettingStarted.html
 M docs/HowToReleaseLLVM.html
 M docs/SourceLevelDebugging.html
 M docs/tutorial/LangImpl5.html
 M docs/tutorial/LangImpl6.html
 M docs/tutorial/LangImpl7.html
 M examples/BrainF/BrainF.cpp
 M examples/Kaleidoscope/Chapter5/toy.cpp
 M examples/Kaleidoscope/Chapter6/toy.cpp
 M examples/Kaleidoscope/Chapter7/toy.cpp
 M include/llvm/ADT/APFloat.h
 M include/llvm/ADT/APInt.h
 M include/llvm/ADT/DenseMap.h
 M include/llvm/ADT/SmallPtrSet.h
 M include/llvm/ADT/StringMap.h
 M include/llvm/CodeGen/MachineBasicBlock.h
 M include/llvm/ExecutionEngine/ExecutionEngine.h
 M include/llvm/ExecutionEngine/JITMemoryManager.h
 M include/llvm/ExecutionEngine/RuntimeDyld.h
 M include/llvm/Instructions.h
 M include/llvm/IntrinsicsARM.td
 M include/llvm/IntrinsicsXCore.td
 M include/llvm/MC/MCAsmInfo.h
 M include/llvm/MC/MCContext.h
 M include/llvm/MC/MCParser/AsmLexer.h
 M include/llvm/PassAnalysisSupport.h
 M include/llvm/Support/FileUtilities.h
 M include/llvm/Support/IRBuilder.h
 M include/llvm/Target/TargetMachine.h
 M lib/Analysis/ConstantFolding.cpp
 M lib/Analysis/ScalarEvolutionExpander.cpp
 M lib/AsmParser/LLParser.cpp
 M lib/Bitcode/Reader/BitcodeReader.cpp
 M lib/CodeGen/AsmPrinter/AsmPrinter.cpp
 M lib/CodeGen/AsmPrinter/DwarfDebug.cpp
 M lib/CodeGen/AsmPrinter/DwarfDebug.h
 M lib/CodeGen/CalcSpillWeights.cpp
 M lib/CodeGen/DwarfEHPrepare.cpp
 M lib/CodeGen/InlineSpiller.cpp
 M lib/CodeGen/LLVMTargetMachine.cpp
 M lib/CodeGen/LiveIntervalAnalysis.cpp
 M lib/CodeGen/LiveIntervalUnion.h
 M lib/CodeGen/LiveRangeEdit.cpp
 M lib/CodeGen/LiveRangeEdit.h
 M lib/CodeGen/RegAllocGreedy.cpp
 M lib/CodeGen/RegAllocLinearScan.cpp
 M lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
 M lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
 M lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
 M lib/CodeGen/SplitKit.cpp
 M lib/CodeGen/StackProtector.cpp
 M lib/CodeGen/VirtRegRewriter.cpp
 M lib/ExecutionEngine/MCJIT/MCJIT.cpp
 M lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
 M lib/Linker/LinkModules.cpp
 M lib/MC/MCAsmInfo.cpp
 M lib/MC/MCAsmStreamer.cpp
 M lib/MC/MCContext.cpp
 M lib/MC/MCDisassembler/CMakeLists.txt
 M lib/MC/MCDisassembler/EDInfo.h
 M lib/MC/MCDisassembler/EDOperand.cpp
 M lib/MC/MCParser/AsmLexer.cpp
 M lib/MC/MCParser/AsmParser.cpp
 M lib/Support/APFloat.cpp
 M lib/Support/APInt.cpp
 M lib/Support/SmallPtrSet.cpp
 M lib/Support/StringMap.cpp
 M lib/Target/ARM/ARMAddressingModes.h
 M lib/Target/ARM/ARMBaseInfo.h
 M lib/Target/ARM/ARMBaseInstrInfo.cpp
 M lib/Target/ARM/ARMBaseInstrInfo.h
 M lib/Target/ARM/ARMBaseRegisterInfo.cpp
 M lib/Target/ARM/ARMExpandPseudoInsts.cpp
 M lib/Target/ARM/ARMFastISel.cpp
 M lib/Target/ARM/ARMISelLowering.cpp
 M lib/Target/ARM/ARMISelLowering.h
 M lib/Target/ARM/ARMInstrFormats.td
 M lib/Target/ARM/ARMInstrInfo.td
 M lib/Target/ARM/ARMInstrNEON.td
 M lib/Target/ARM/ARMInstrThumb2.td
 M lib/Target/ARM/ARMInstrVFP.td
 M lib/Target/ARM/ARMLoadStoreOptimizer.cpp
 M lib/Target/ARM/AsmParser/ARMAsmParser.cpp
 M lib/Target/ARM/Disassembler/ARMDisassembler.cpp
 M lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
 M lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
 M lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
 M lib/Target/ARM/InstPrinter/ARMInstPrinter.h
 M lib/Target/CppBackend/CPPBackend.cpp
 M lib/Target/Mips/MipsISelLowering.cpp
 M lib/Target/PTX/PTXISelLowering.cpp
 M lib/Target/PTX/PTXInstrInfo.cpp
 M lib/Target/PTX/PTXInstrInfo.td
 M lib/Target/README.txt
 M lib/Target/TargetInstrInfo.cpp
 M lib/Target/TargetMachine.cpp
 M lib/Target/X86/X86ISelLowering.cpp
 M lib/Target/XCore/XCoreInstrInfo.td
 M lib/Transforms/IPO/GlobalOpt.cpp
 M lib/Transforms/IPO/LowerSetJmp.cpp
 M lib/Transforms/IPO/MergeFunctions.cpp
 M lib/Transforms/IPO/PartialInlining.cpp
 M lib/Transforms/InstCombine/InstCombine.h
 M lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
 M lib/Transforms/InstCombine/InstCombineCalls.cpp
 M lib/Transforms/InstCombine/InstCombineCasts.cpp
 M lib/Transforms/InstCombine/InstCombineCompares.cpp
 M lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
 M lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
 M lib/Transforms/InstCombine/InstCombinePHI.cpp
 M lib/Transforms/InstCombine/InstCombineSelect.cpp
 M lib/Transforms/InstCombine/InstructionCombining.cpp
 M lib/Transforms/Instrumentation/PathProfiling.cpp
 M lib/Transforms/Scalar/DeadStoreElimination.cpp
 M lib/Transforms/Scalar/GVN.cpp
 M lib/Transforms/Scalar/IndVarSimplify.cpp
 M lib/Transforms/Scalar/JumpThreading.cpp
 M lib/Transforms/Scalar/LoopStrengthReduce.cpp
 M lib/Transforms/Scalar/ScalarReplAggregates.cpp
 M lib/Transforms/Scalar/SimplifyCFGPass.cpp
 M lib/Transforms/Scalar/TailRecursionElimination.cpp
 M lib/Transforms/Utils/BasicBlockUtils.cpp
 M lib/Transforms/Utils/BreakCriticalEdges.cpp
 M lib/Transforms/Utils/CodeExtractor.cpp
 M lib/Transforms/Utils/InlineFunction.cpp
 M lib/Transforms/Utils/LCSSA.cpp
 M lib/Transforms/Utils/LoopSimplify.cpp
 M lib/Transforms/Utils/PromoteMemoryToRegister.cpp
 M lib/Transforms/Utils/SSAUpdater.cpp
 M lib/Transforms/Utils/SimplifyCFG.cpp
 M lib/Transforms/Utils/UnifyFunctionExitNodes.cpp
 M lib/VMCore/AutoUpgrade.cpp
 M lib/VMCore/Core.cpp
 M lib/VMCore/Dominators.cpp
 M test/Bitcode/neon-intrinsics.ll
 M test/CodeGen/ARM/vmul.ll
 M test/CodeGen/Thumb2/bfi.ll
 M test/CodeGen/X86/2010-05-26-DotDebugLoc.ll
 M test/CodeGen/X86/crash.ll
 M test/CodeGen/X86/dbg-merge-loc-entry.ll
 M test/CodeGen/X86/dbg-value-range.ll
 M test/CodeGen/X86/unknown-location.ll
 M test/FrontendAda/real_cst.adb
 M test/MC/ARM/arm_instructions.s
 M test/MC/ARM/thumb2.s
 M test/MC/AsmParser/floating-literals.s
 M test/MC/Disassembler/ARM/arm-tests.txt
 M test/MC/Disassembler/ARM/neon-tests.txt
 M test/MC/Disassembler/ARM/thumb-tests.txt
 M test/Transforms/ConstProp/overflow-ops.ll
 M test/Transforms/InstCombine/select.ll
 M test/Transforms/ScalarRepl/vector_promote.ll
 M tools/bugpoint/BugDriver.cpp
 M tools/bugpoint/ExecutionDriver.cpp
 M tools/bugpoint/Miscompilation.cpp
 M tools/bugpoint/ToolRunner.cpp
 M tools/llvm-ld/llvm-ld.cpp
 M tools/llvm-mc/llvm-mc.cpp
 M tools/llvm-rtdyld/CMakeLists.txt
 M tools/llvm-rtdyld/Makefile
 M tools/llvm-rtdyld/llvm-rtdyld.cpp
 M tools/lto/Makefile
 M tools/lto/lto.exports
 M unittests/ADT/APFloatTest.cpp
 M unittests/Transforms/Utils/Local.cpp
 M unittests/VMCore/DerivedTypesTest.cpp
 M unittests/VMCore/PassManagerTest.cpp
 M utils/GenLibDeps.pl
 M utils/TableGen/ARMDecoderEmitter.cpp
 M utils/TableGen/ClangAttrEmitter.cpp
 M utils/TableGen/ClangSACheckersEmitter.cpp
 M utils/TableGen/EDEmitter.cpp
 M utils/TableGen/NeonEmitter.cpp
 M utils/TableGen/NeonEmitter.h
 M utils/release/test-release.sh
Added paths:
 A include/llvm-c/Disassembler.h
 A lib/MC/MCDisassembler/Disassembler.cpp
 A lib/MC/MCDisassembler/Disassembler.h
 A test/CodeGen/ARM/crash-greedy.ll
 A test/CodeGen/ARM/int-to-fp.ll
 A test/CodeGen/ARM/vbsl-constant.ll
 A test/CodeGen/X86/2011-03-30-CreateFixedObjCrash.ll
 A test/CodeGen/X86/dbg-file-name.ll
 A test/CodeGen/XCore/threads.ll
 A test/FrontendC/2011-03-31-ArrayRefFolding.c
 A test/FrontendC/vla-3.c
 A test/MC/ARM/arm_addrmode2.s
 A test/MC/AsmParser/dot-symbol.s
 A test/MC/Disassembler/ARM/invalid-CPS2p-arm.txt
 A test/MC/Disassembler/ARM/invalid-VLDMSDB_UPD-arm.txt
 A test/MC/Disassembler/ARM/thumb-printf.txt
 A test/MC/MachO/temp-labels.s
 A test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll
 A test/Transforms/InstCombine/fcmp.ll
 A test/Transforms/InstCombine/fdiv.ll
 A test/Transforms/InstCombine/sign-test-and-or.ll
 A test/Transforms/ScalarRepl/inline-vector.ll
 A utils/release/findRegressions.py
Removed paths:
 D test/MC/Disassembler/ARM/invalid-VLDMSDB-arm.txt
 D utils/CollectDebugInfoUsingLLDB.py
 D utils/CompareDebugInfo.py

Modified: cmake/modules/AddLLVM.cmake
===================================================================
--- a/cmake/modules/AddLLVM.cmake
+++ b/cmake/modules/AddLLVM.cmake
@@ -11,10 +11,12 @@ macro(add_llvm_library name)
 
   if( BUILD_SHARED_LIBS )
     llvm_config( ${name} ${LLVM_LINK_COMPONENTS} )
-    get_system_libs(sl)
-    target_link_libraries( ${name} ${sl} )
   endif()
 
+  # Ensure that the system libraries always comes last on the
+  # list. Without this, linking the unit tests on MinGW fails.
+  link_system_libs( ${name} )
+
   install(TARGETS ${name}
     LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
     ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
@@ -47,8 +49,7 @@ ${name} ignored.")
     set_target_properties( ${name} PROPERTIES PREFIX "" )
 
     llvm_config( ${name} ${LLVM_LINK_COMPONENTS} )
-    get_system_libs(sl)
-    target_link_libraries( ${name} ${sl} )
+    link_system_libs( ${name} )
 
     if (APPLE)
       # Darwin-specific linker flags for loadable modules.
@@ -73,21 +74,12 @@ macro(add_llvm_executable name)
     add_executable(${name} ${ALL_FILES})
   endif()
   set(EXCLUDE_FROM_ALL OFF)
-  if( LLVM_USED_LIBS )
-    foreach(lib ${LLVM_USED_LIBS})
-      target_link_libraries( ${name} ${lib} )
-    endforeach(lib)
-  endif( LLVM_USED_LIBS )
-  if( LLVM_LINK_COMPONENTS )
-    llvm_config(${name} ${LLVM_LINK_COMPONENTS})
-  endif( LLVM_LINK_COMPONENTS )
+  target_link_libraries( ${name} ${LLVM_USED_LIBS} )
+  llvm_config( ${name} ${LLVM_LINK_COMPONENTS} )
   if( LLVM_COMMON_DEPENDS )
     add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} )
   endif( LLVM_COMMON_DEPENDS )
-  get_system_libs(llvm_system_libs)
-  if( llvm_system_libs )
-    target_link_libraries(${name} ${llvm_system_libs})
-  endif()
+  link_system_libs( ${name} )
 endmacro(add_llvm_executable name)
 
 
Modified: cmake/modules/LLVMConfig.cmake
===================================================================
--- a/cmake/modules/LLVMConfig.cmake
+++ b/cmake/modules/LLVMConfig.cmake
@@ -16,6 +16,12 @@ function(get_system_libs return_var)
 endfunction(get_system_libs)
 
 
+function(link_system_libs target)
+  get_system_libs(llvm_system_libs)
+  target_link_libraries(${target} ${llvm_system_libs})
+endfunction(link_system_libs)
+
+
 function(is_llvm_target_library library return_var)
   # Sets variable `return_var' to ON if `library' corresponds to a
   # LLVM supported target. To OFF if it doesn't.
Modified: docs/GettingStarted.html
===================================================================
--- a/docs/GettingStarted.html
+++ b/docs/GettingStarted.html
@@ -268,7 +268,8 @@ software you will need.</p>
 <tr>
   <td>MinGW/Win32</td>
   <td>x86<sup><a href="#pf_1">1</a>,<a href="#pf_6">6</a>,
-     <a href="#pf_8">8</a>, <a href="#pf_10">10</a></sup></td>
+     <a href="#pf_8">8</a>, <a href="#pf_10">10</a>,
+     <a href="#pf_11">11</a></sup></td>
   <td>GCC 3.4.X, binutils 2.20</td>
 </tr>
 </table>
@@ -311,6 +312,11 @@ software you will need.</p>
   <td>Itanium (IA-64)</td>
   <td>HP aCC</td>
 </tr>
+<tr>
+  <td>Windows x64</td>
+  <td>x86-64</td>
+  <td>mingw-w64's GCC-4.5.x<sup><a href="#pf_12">12</a></sup></td>
+</tr>
 </table>
 
 <p><b>Notes:</b></p>
@@ -337,9 +343,10 @@ up</a></li>
     before any Windows-based versions such as Strawberry Perl and
     ActivePerl, as these have Windows-specifics that will cause the
     build to fail.</a></li>
-<li><a name="pf_11">In general, LLVM modules requiring dynamic linking can
-    not be built on Windows. However, you can build LLVM tools using
-    <i>"make tools-only"</i>.</li>
+<li><a name="pf_11">To use LLVM modules on Win32-based system,
+    you may configure LLVM with <i>&quot;--enable-shared&quot;</i>.</li>
+<li><a name="pf_12">To compile SPU backend, you need to add
+    <tt>&quot;LDFLAGS=-Wl,--stack,16777216&quot;</tt> to configure.</li>
 </ol>
 </div>
 
Modified: docs/HowToReleaseLLVM.html
===================================================================
--- a/docs/HowToReleaseLLVM.html
+++ b/docs/HowToReleaseLLVM.html
@@ -256,10 +256,10 @@ $ svn export \
https://llvm.org/svn/llvm-project/llvm-gcc-4.2/tags/RELEASE_<i>XY</  $ svn export \
https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_<i>XY</i>/rc1 \
llvm-test-<i>X.Y</i>rc1  $ svn export \
https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_<i>XY</i>/rc1 clang-<i>X.Y</i>rc1  \
                
-$ tar -czvf - llvm-<i>X.Y</i>rc1        | gzip &gt; llvm-<i>X.Y</i>rc1.src.tar.gz
-$ tar -czvf - llvm-test-<i>X.Y</i>rc1   | gzip &gt; \
                llvm-test-<i>X.Y</i>rc1.src.tar.gz
-$ tar -czvf - llvm-gcc4.2-<i>X.Y</i>rc1 | gzip &gt; \
                llvm-gcc-4.2-<i>X.Y</i>rc1.src.tar.gz
-$ tar -czvf - clang-<i>X.Y</i>rc1       | gzip &gt; clang-<i>X.Y</i>rc1.src.tar.gz
+$ tar -cvf - llvm-<i>X.Y</i>rc1        | gzip &gt; llvm-<i>X.Y</i>rc1.src.tar.gz
+$ tar -cvf - llvm-test-<i>X.Y</i>rc1   | gzip &gt; \
llvm-test-<i>X.Y</i>rc1.src.tar.gz +$ tar -cvf - llvm-gcc4.2-<i>X.Y</i>rc1 | gzip \
&gt; llvm-gcc-4.2-<i>X.Y</i>rc1.src.tar.gz +$ tar -cvf - clang-<i>X.Y</i>rc1       | \
gzip &gt; clang-<i>X.Y</i>rc1.src.tar.gz  </pre>
 </div>
 
Modified: docs/SourceLevelDebugging.html
===================================================================
--- a/docs/SourceLevelDebugging.html
+++ b/docs/SourceLevelDebugging.html
@@ -407,7 +407,8 @@ height="369">
 </div>
 
 <p>These descriptors provide debug information about globals variables.  The
-provide details such as name, type and where the variable is defined.</p>
+provide details such as name, type and where the variable is defined. All
+global variables are collected by named metadata <tt>!llvm.dbg.gv</tt>.</p>
 
 </div>
 
@@ -446,7 +447,10 @@ provide details such as name, type and where the variable is \
defined.</p>  
 <p>These descriptors provide debug information about functions, methods and
    subprograms.  They provide details such as name, return types and the source
-   location where the subprogram is defined.</p>
+   location where the subprogram is defined.
+   All subprogram descriptors are collected by a named metadata 
+   <tt>!llvm.dbg.sp</tt>.
+</p>
 
 </div>
 
@@ -646,7 +650,8 @@ DW_TAG_inheritance      = 28
 
 <p>The members of enumeration types (tag = <tt>DW_TAG_enumeration_type</tt>) are
    <a href="#format_enumeration">enumerator descriptors</a>, each representing
-   the definition of enumeration value for the set.</p>
+   the definition of enumeration value for the set. All enumeration type
+   descriptors are collected by named metadata <tt>!llvm.dbg.enum</tt>.</p>
 
 <p>The members of structure (tag = <tt>DW_TAG_structure_type</tt>) or union (tag
    = <tt>DW_TAG_union_type</tt>) types are any one of
Modified: docs/tutorial/LangImpl5.html
===================================================================
--- a/docs/tutorial/LangImpl5.html
+++ b/docs/tutorial/LangImpl5.html
@@ -472,7 +472,7 @@ are emitted, we can finish up with the merge code:</p>
   // Emit merge block.
   TheFunction->getBasicBlockList().push_back(MergeBB);
   Builder.SetInsertPoint(MergeBB);
-  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
+  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
                                   "iftmp");
   
   PN->addIncoming(ThenV, ThenBB);
@@ -746,7 +746,7 @@ create an unconditional branch for the fall-through between the \
two blocks.</p>  Builder.SetInsertPoint(LoopBB);
   
   // Start the PHI node with an entry for Start.
-  PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), \
VarName.c_str()); +  PHINode *Variable = \
Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, VarName.c_str());  \
Variable-&gt;addIncoming(StartVal, PreheaderBB);  </pre>
 </div>
@@ -1452,7 +1452,7 @@ Value *IfExprAST::Codegen() {
   // Emit merge block.
   TheFunction-&gt;getBasicBlockList().push_back(MergeBB);
   Builder.SetInsertPoint(MergeBB);
-  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
+  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
                                   "iftmp");
   
   PN-&gt;addIncoming(ThenV, ThenBB);
@@ -1494,7 +1494,7 @@ Value *ForExprAST::Codegen() {
   Builder.SetInsertPoint(LoopBB);
   
   // Start the PHI node with an entry for Start.
-  PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), \
VarName.c_str()); +  PHINode *Variable = \
Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, VarName.c_str());  \
Variable-&gt;addIncoming(StartVal, PreheaderBB);  
   // Within the loop, the variable is defined equal to the PHI node.  If it
Modified: docs/tutorial/LangImpl6.html
===================================================================
--- a/docs/tutorial/LangImpl6.html
+++ b/docs/tutorial/LangImpl6.html
@@ -1475,7 +1475,7 @@ Value *IfExprAST::Codegen() {
   // Emit merge block.
   TheFunction-&gt;getBasicBlockList().push_back(MergeBB);
   Builder.SetInsertPoint(MergeBB);
-  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
+  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
                                   "iftmp");
   
   PN-&gt;addIncoming(ThenV, ThenBB);
@@ -1517,7 +1517,7 @@ Value *ForExprAST::Codegen() {
   Builder.SetInsertPoint(LoopBB);
   
   // Start the PHI node with an entry for Start.
-  PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), \
VarName.c_str()); +  PHINode *Variable = \
Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, VarName.c_str());  \
Variable-&gt;addIncoming(StartVal, PreheaderBB);  
   // Within the loop, the variable is defined equal to the PHI node.  If it
Modified: docs/tutorial/LangImpl7.html
===================================================================
--- a/docs/tutorial/LangImpl7.html
+++ b/docs/tutorial/LangImpl7.html
@@ -1755,7 +1755,7 @@ Value *IfExprAST::Codegen() {
   // Emit merge block.
   TheFunction-&gt;getBasicBlockList().push_back(MergeBB);
   Builder.SetInsertPoint(MergeBB);
-  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
+  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
                                   "iftmp");
   
   PN-&gt;addIncoming(ThenV, ThenBB);
Modified: examples/BrainF/BrainF.cpp
===================================================================
--- a/examples/BrainF/BrainF.cpp
+++ b/examples/BrainF/BrainF.cpp
@@ -294,8 +294,7 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock \
                *testbb,
           // Make part of PHI instruction now, wait until end of loop to finish
           PHINode *phi_0 =
             PHINode::Create(PointerType::getUnqual(IntegerType::getInt8Ty(C)),
-                            headreg, testbb);
-          phi_0->reserveOperandSpace(2);
+                            2, headreg, testbb);
           phi_0->addIncoming(curhead, bb_0);
           curhead = phi_0;
 
@@ -449,8 +448,8 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock \
*testbb,  
       //%head.%d = phi i8 *[%head.%d, %main.%d]
       PHINode *phi_1 = builder->
-        CreatePHI(PointerType::getUnqual(IntegerType::getInt8Ty(C)), headreg);
-      phi_1->reserveOperandSpace(1);
+        CreatePHI(PointerType::getUnqual(IntegerType::getInt8Ty(C)), 1,
+                  headreg);
       phi_1->addIncoming(head_0, testbb);
       curhead = phi_1;
     }
Modified: examples/Kaleidoscope/Chapter5/toy.cpp
===================================================================
--- a/examples/Kaleidoscope/Chapter5/toy.cpp
+++ b/examples/Kaleidoscope/Chapter5/toy.cpp
@@ -550,7 +550,7 @@ Value *IfExprAST::Codegen() {
   // Emit merge block.
   TheFunction->getBasicBlockList().push_back(MergeBB);
   Builder.SetInsertPoint(MergeBB);
-  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
+  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
                                   "iftmp");
   
   PN->addIncoming(ThenV, ThenBB);
@@ -592,7 +592,7 @@ Value *ForExprAST::Codegen() {
   Builder.SetInsertPoint(LoopBB);
   
   // Start the PHI node with an entry for Start.
-  PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), \
VarName.c_str()); +  PHINode *Variable = \
Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, VarName.c_str());  \
Variable->addIncoming(StartVal, PreheaderBB);  
   // Within the loop, the variable is defined equal to the PHI node.  If it
Modified: examples/Kaleidoscope/Chapter6/toy.cpp
===================================================================
--- a/examples/Kaleidoscope/Chapter6/toy.cpp
+++ b/examples/Kaleidoscope/Chapter6/toy.cpp
@@ -654,7 +654,7 @@ Value *IfExprAST::Codegen() {
   // Emit merge block.
   TheFunction->getBasicBlockList().push_back(MergeBB);
   Builder.SetInsertPoint(MergeBB);
-  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
+  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
                                   "iftmp");
   
   PN->addIncoming(ThenV, ThenBB);
@@ -696,7 +696,7 @@ Value *ForExprAST::Codegen() {
   Builder.SetInsertPoint(LoopBB);
   
   // Start the PHI node with an entry for Start.
-  PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), \
VarName.c_str()); +  PHINode *Variable = \
Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, VarName.c_str());  \
Variable->addIncoming(StartVal, PreheaderBB);  
   // Within the loop, the variable is defined equal to the PHI node.  If it
Modified: examples/Kaleidoscope/Chapter7/toy.cpp
===================================================================
--- a/examples/Kaleidoscope/Chapter7/toy.cpp
+++ b/examples/Kaleidoscope/Chapter7/toy.cpp
@@ -750,7 +750,7 @@ Value *IfExprAST::Codegen() {
   // Emit merge block.
   TheFunction->getBasicBlockList().push_back(MergeBB);
   Builder.SetInsertPoint(MergeBB);
-  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
+  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
                                   "iftmp");
   
   PN->addIncoming(ThenV, ThenBB);
Modified: include/llvm/ADT/APFloat.h
===================================================================
--- a/include/llvm/ADT/APFloat.h
+++ b/include/llvm/ADT/APFloat.h
@@ -353,6 +353,10 @@ namespace llvm {
                   unsigned FormatPrecision = 0,
                   unsigned FormatMaxPadding = 3) const;
 
+    /// getExactInverse - If this value has an exact multiplicative inverse,
+    /// store it in inv and return true.
+    bool getExactInverse(APFloat *inv) const;
+
   private:
 
     /* Trivial queries.  */
Modified: include/llvm/ADT/APInt.h
===================================================================
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -818,6 +818,7 @@ public:
   APInt usub_ov(const APInt &RHS, bool &Overflow) const;
   APInt sdiv_ov(const APInt &RHS, bool &Overflow) const;
   APInt smul_ov(const APInt &RHS, bool &Overflow) const;
+  APInt umul_ov(const APInt &RHS, bool &Overflow) const;
   APInt sshl_ov(unsigned Amt, bool &Overflow) const;
 
   /// @returns the bit value at bitPosition
Modified: include/llvm/ADT/DenseMap.h
===================================================================
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -289,11 +289,14 @@ private:
     // table completely filled with tombstones, no lookup would ever succeed,
     // causing infinite loops in lookup.
     ++NumEntries;
-    if (NumEntries*4 >= NumBuckets*3 ||
-        NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {
+    if (NumEntries*4 >= NumBuckets*3) {
       this->grow(NumBuckets * 2);
       LookupBucketFor(Key, TheBucket);
     }
+    if (NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {
+      this->grow(NumBuckets);
+      LookupBucketFor(Key, TheBucket);
+    }
 
     // If we are writing over a tombstone, remember this.
     if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey()))
@@ -422,7 +425,8 @@ private:
     }
 
 #ifndef NDEBUG
-    memset(OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets);
+    if (OldNumBuckets)
+      memset(OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets);
 #endif
     // Free the old table.
     operator delete(OldBuckets);
Modified: include/llvm/ADT/SmallPtrSet.h
===================================================================
--- a/include/llvm/ADT/SmallPtrSet.h
+++ b/include/llvm/ADT/SmallPtrSet.h
@@ -133,7 +133,7 @@ private:
   void shrink_and_clear();
 
   /// Grow - Allocate a larger backing store for the buckets and move it over.
-  void Grow();
+  void Grow(unsigned NewSize);
 
   void operator=(const SmallPtrSetImpl &RHS);  // DO NOT IMPLEMENT.
 protected:
Modified: include/llvm/ADT/StringMap.h
===================================================================
--- a/include/llvm/ADT/StringMap.h
+++ b/include/llvm/ADT/StringMap.h
@@ -81,16 +81,6 @@ protected:
   StringMapImpl(unsigned InitSize, unsigned ItemSize);
   void RehashTable();
 
-  /// ShouldRehash - Return true if the table should be rehashed after a new
-  /// element was recently inserted.
-  bool ShouldRehash() const {
-    // If the hash table is now more than 3/4 full, or if fewer than 1/8 of
-    // the buckets are empty (meaning that many are filled with tombstones),
-    // grow the table.
-    return NumItems*4 > NumBuckets*3 ||
-           NumBuckets-(NumItems+NumTombstones) < NumBuckets/8;
-  }
-
   /// LookupBucketFor - Look up the bucket that the specified string should end
   /// up in.  If it already exists as a key in the map, the Item pointer for the
   /// specified bucket will be non-null.  Otherwise, it will be null.  In either
@@ -339,9 +329,9 @@ public:
       --NumTombstones;
     Bucket.Item = KeyValue;
     ++NumItems;
+    assert(NumItems + NumTombstones <= NumBuckets);
 
-    if (ShouldRehash())
-      RehashTable();
+    RehashTable();
     return true;
   }
 
@@ -359,6 +349,7 @@ public:
     }
 
     NumItems = 0;
+    NumTombstones = 0;
   }
 
   /// GetOrCreateValue - Look up the specified key in the table.  If a value
@@ -378,13 +369,13 @@ public:
     if (Bucket.Item == getTombstoneVal())
       --NumTombstones;
     ++NumItems;
+    assert(NumItems + NumTombstones <= NumBuckets);
 
     // Fill in the bucket for the hash table.  The FullHashValue was already
     // filled in by LookupBucketFor.
     Bucket.Item = NewItem;
 
-    if (ShouldRehash())
-      RehashTable();
+    RehashTable();
     return *NewItem;
   }
 
Modified: include/llvm/CodeGen/MachineBasicBlock.h
===================================================================
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -309,6 +309,10 @@ public:
   /// instruction in the basic block, or end()
   iterator getLastNonDebugInstr();
 
+  const_iterator getLastNonDebugInstr() const {
+    return const_cast<MachineBasicBlock*>(this)->getLastNonDebugInstr();
+  }
+
   /// SplitCriticalEdge - Split the critical edge from this block to the
   /// given successor block, and return the newly created block, or null
   /// if splitting is not possible.
Modified: include/llvm/ExecutionEngine/ExecutionEngine.h
===================================================================
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -118,11 +118,11 @@ protected:
   /// The list of Modules that we are JIT'ing from.  We use a SmallVector to
   /// optimize for the case where there is only one module.
   SmallVector<Module*, 1> Modules;
-  
+
   void setTargetData(const TargetData *td) {
     TD = td;
   }
-  
+
   /// getMemoryforGV - Allocate memory for a global variable.
   virtual char *getMemoryForGV(const GlobalVariable *GV);
 
@@ -156,7 +156,7 @@ protected:
   /// pointer is invoked to create it.  If this returns null, the JIT will
   /// abort.
   void *(*LazyFunctionCreator)(const std::string &);
-  
+
   /// ExceptionTableRegister - If Exception Handling is set, the JIT will
   /// register dwarf tables with this function.
   typedef void (*EERegisterFn)(void*);
@@ -216,7 +216,7 @@ public:
   virtual void addModule(Module *M) {
     Modules.push_back(M);
   }
-  
+
   //===--------------------------------------------------------------------===//
 
   const TargetData *getTargetData() const { return TD; }
@@ -229,7 +229,7 @@ public:
   /// defines FnName.  This is very slow operation and shouldn't be used for
   /// general code.
   Function *FindFunctionNamed(const char *FnName);
-  
+
   /// runFunction - Execute the specified function with the specified arguments,
   /// and return the result.
   virtual GenericValue runFunction(Function *F,
@@ -246,8 +246,8 @@ public:
   ///
   /// \param isDtors - Run the destructors instead of constructors.
   void runStaticConstructorsDestructors(Module *module, bool isDtors);
-  
-  
+
+
   /// runFunctionAsMain - This is a helper function which wraps runFunction to
   /// handle the common task of starting up main with the specified argc, argv,
   /// and envp parameters.
@@ -262,21 +262,21 @@ public:
   /// existing data in memory.  Mappings are automatically removed when their
   /// GlobalValue is destroyed.
   void addGlobalMapping(const GlobalValue *GV, void *Addr);
-  
+
   /// clearAllGlobalMappings - Clear all global mappings and start over again,
   /// for use in dynamic compilation scenarios to move globals.
   void clearAllGlobalMappings();
-  
+
   /// clearGlobalMappingsFromModule - Clear all global mappings that came from a
   /// particular module, because it has been removed from the JIT.
   void clearGlobalMappingsFromModule(Module *M);
-  
+
   /// updateGlobalMapping - Replace an existing mapping for GV with a new
   /// address.  This updates both maps as required.  If "Addr" is null, the
   /// entry for the global is removed from the mappings.  This returns the old
   /// value of the pointer, or null if it was not in the map.
   void *updateGlobalMapping(const GlobalValue *GV, void *Addr);
-  
+
   /// getPointerToGlobalIfAvailable - This returns the address of the specified
   /// global value if it is has already been codegen'd, otherwise it returns
   /// null.
@@ -297,7 +297,7 @@ public:
   /// different ways.  Return the representation for a blockaddress of the
   /// specified block.
   virtual void *getPointerToBasicBlock(BasicBlock *BB) = 0;
-  
+
   /// getPointerToFunctionOrStub - If the specified function has been
   /// code-gen'd, return a pointer to the function.  If not, compile it, or use
   /// a stub to implement lazy compilation if available.  See
@@ -401,7 +401,7 @@ public:
   void InstallLazyFunctionCreator(void* (*P)(const std::string &)) {
     LazyFunctionCreator = P;
   }
-  
+
   /// InstallExceptionTableRegister - The JIT will use the given function
   /// to register the exception tables it generates.
   void InstallExceptionTableRegister(EERegisterFn F) {
@@ -410,7 +410,7 @@ public:
   void InstallExceptionTableDeregister(EERegisterFn F) {
     ExceptionTableDeregister = F;
   }
-  
+
   /// RegisterTable - Registers the given pointer as an exception table.  It
   /// uses the ExceptionTableRegister function.
   void RegisterTable(const Function *fn, void* res) {
@@ -420,10 +420,12 @@ public:
     }
   }
 
-  /// DeregisterTable - Deregisters the exception frame previously registered for \
the given function. +  /// DeregisterTable - Deregisters the exception frame \
previously registered +  /// for the given function.
   void DeregisterTable(const Function *Fn) {
     if (ExceptionTableDeregister) {
-      DenseMap<const Function*, void*>::iterator frame = \
AllExceptionTables.find(Fn); +      DenseMap<const Function*, void*>::iterator frame \
= +        AllExceptionTables.find(Fn);
       if(frame != AllExceptionTables.end()) {
         ExceptionTableDeregister(frame->second);
         AllExceptionTables.erase(frame);
@@ -443,7 +445,7 @@ protected:
   void EmitGlobalVariable(const GlobalVariable *GV);
 
   GenericValue getConstantValue(const Constant *C);
-  void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr, 
+  void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr,
                            const Type *Ty);
 };
 
Modified: include/llvm/ExecutionEngine/JITMemoryManager.h
===================================================================
--- a/include/llvm/ExecutionEngine/JITMemoryManager.h
+++ b/include/llvm/ExecutionEngine/JITMemoryManager.h
@@ -29,11 +29,11 @@ protected:
 public:
   JITMemoryManager() : HasGOT(false) {}
   virtual ~JITMemoryManager();
-  
+
   /// CreateDefaultMemManager - This is used to create the default
   /// JIT Memory Manager if the client does not provide one to the JIT.
   static JITMemoryManager *CreateDefaultMemManager();
-  
+
   /// setMemoryWritable - When code generation is in progress,
   /// the code pages may need permissions changed.
   virtual void setMemoryWritable() = 0;
@@ -55,16 +55,16 @@ public:
   /// method is invoked to allocate it.  This method is required to set HasGOT
   /// to true.
   virtual void AllocateGOT() = 0;
-  
+
   /// isManagingGOT - Return true if the AllocateGOT method is called.
   bool isManagingGOT() const {
     return HasGOT;
   }
-  
+
   /// getGOTBase - If this is managing a Global Offset Table, this method should
   /// return a pointer to its base.
   virtual uint8_t *getGOTBase() const = 0;
-  
+
   //===--------------------------------------------------------------------===//
   // Main Allocation Functions
   //===--------------------------------------------------------------------===//
@@ -91,11 +91,11 @@ public:
   /// startFunctionBody.
   virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
                                 unsigned Alignment) = 0;
-  
+
   /// endFunctionBody - This method is called when the JIT is done codegen'ing
   /// the specified function.  At this point we know the size of the JIT
   /// compiled function.  This passes in FunctionStart (which was returned by
-  /// the startFunctionBody method) and FunctionEnd which is a pointer to the 
+  /// the startFunctionBody method) and FunctionEnd which is a pointer to the
   /// actual end of the function.  This method should mark the space allocated
   /// and remember where it is in case the client wants to deallocate it.
   virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
@@ -113,12 +113,12 @@ public:
   /// been deallocated yet.  This is never called when the JIT is currently
   /// emitting a function.
   virtual void deallocateFunctionBody(void *Body) = 0;
-  
+
   /// startExceptionTable - When we finished JITing the function, if exception
   /// handling is set, we emit the exception table.
   virtual uint8_t* startExceptionTable(const Function* F,
                                        uintptr_t &ActualSize) = 0;
-  
+
   /// endExceptionTable - This method is called when the JIT is done emitting
   /// the exception table.
   virtual void endExceptionTable(const Function *F, uint8_t *TableStart,
Modified: include/llvm/ExecutionEngine/RuntimeDyld.h
===================================================================
--- a/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -21,6 +21,7 @@ namespace llvm {
 
 class RuntimeDyldImpl;
 class MemoryBuffer;
+class JITMemoryManager;
 
 class RuntimeDyld {
   RuntimeDyld(const RuntimeDyld &);     // DO NOT IMPLEMENT
@@ -30,7 +31,7 @@ class RuntimeDyld {
   // interface.
   RuntimeDyldImpl *Dyld;
 public:
-  RuntimeDyld();
+  RuntimeDyld(JITMemoryManager*);
   ~RuntimeDyld();
 
   bool loadObject(MemoryBuffer *InputBuffer);
Modified: include/llvm/Instructions.h
===================================================================
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -1811,39 +1811,37 @@ class PHINode : public Instruction {
   void *operator new(size_t s) {
     return User::operator new(s, 0);
   }
-  explicit PHINode(const Type *Ty, const Twine &NameStr = "",
-                   Instruction *InsertBefore = 0)
+  explicit PHINode(const Type *Ty, unsigned NumReservedValues,
+                   const Twine &NameStr = "", Instruction *InsertBefore = 0)
     : Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore),
-      ReservedSpace(0) {
+      ReservedSpace(NumReservedValues * 2) {
     setName(NameStr);
+    OperandList = allocHungoffUses(ReservedSpace);
   }
 
-  PHINode(const Type *Ty, const Twine &NameStr, BasicBlock *InsertAtEnd)
+  PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr,
+          BasicBlock *InsertAtEnd)
     : Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd),
-      ReservedSpace(0) {
+      ReservedSpace(NumReservedValues * 2) {
     setName(NameStr);
+    OperandList = allocHungoffUses(ReservedSpace);
   }
 protected:
   virtual PHINode *clone_impl() const;
 public:
-  static PHINode *Create(const Type *Ty, const Twine &NameStr = "",
+  /// Constructors - NumReservedValues is a hint for the number of incoming
+  /// edges that this phi node will have (use 0 if you really have no idea).
+  static PHINode *Create(const Type *Ty, unsigned NumReservedValues,
+                         const Twine &NameStr = "",
                          Instruction *InsertBefore = 0) {
-    return new PHINode(Ty, NameStr, InsertBefore);
+    return new PHINode(Ty, NumReservedValues, NameStr, InsertBefore);
   }
-  static PHINode *Create(const Type *Ty, const Twine &NameStr,
-                         BasicBlock *InsertAtEnd) {
-    return new PHINode(Ty, NameStr, InsertAtEnd);
+  static PHINode *Create(const Type *Ty, unsigned NumReservedValues, 
+                         const Twine &NameStr, BasicBlock *InsertAtEnd) {
+    return new PHINode(Ty, NumReservedValues, NameStr, InsertAtEnd);
   }
   ~PHINode();
 
-  /// reserveOperandSpace - This method can be used to avoid repeated
-  /// reallocation of PHI operand lists by reserving space for the correct
-  /// number of operands before adding them.  Unlike normal vector reserves,
-  /// this method can also be used to trim the operand space.
-  void reserveOperandSpace(unsigned NumValues) {
-    resizeOperands(NumValues*2);
-  }
-
   /// Provide fast operand accessors
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
 
Modified: include/llvm/IntrinsicsARM.td
===================================================================
--- a/include/llvm/IntrinsicsARM.td
+++ b/include/llvm/IntrinsicsARM.td
@@ -129,8 +129,12 @@ let Properties = [IntrNoMem, Commutative] in {
   def int_arm_neon_vmulp : Neon_2Arg_Intrinsic;
   def int_arm_neon_vqdmulh : Neon_2Arg_Intrinsic;
   def int_arm_neon_vqrdmulh : Neon_2Arg_Intrinsic;
+  def int_arm_neon_vmulls : Neon_2Arg_Long_Intrinsic;
+  def int_arm_neon_vmullu : Neon_2Arg_Long_Intrinsic;
   def int_arm_neon_vmullp : Neon_2Arg_Long_Intrinsic;
   def int_arm_neon_vqdmull : Neon_2Arg_Long_Intrinsic;
+
+  // Vector Multiply and Accumulate/Subtract.
   def int_arm_neon_vqdmlal : Neon_3Arg_Long_Intrinsic;
   def int_arm_neon_vqdmlsl : Neon_3Arg_Long_Intrinsic;
 
Modified: include/llvm/IntrinsicsXCore.td
===================================================================
--- a/include/llvm/IntrinsicsXCore.td
+++ b/include/llvm/IntrinsicsXCore.td
@@ -69,4 +69,21 @@ let TargetPrefix = "xcore" in {  // All intrinsics start with \
"llvm.xcore.".  def int_xcore_checkevent : Intrinsic<[llvm_ptr_ty],[llvm_ptr_ty]>;
 
   def int_xcore_clre : Intrinsic<[],[],[]>;
+
+  // Intrinsics for threads.
+  def int_xcore_getst : Intrinsic <[llvm_anyptr_ty],[llvm_anyptr_ty],
+                                   [NoCapture<0>]>;
+  def int_xcore_msync : Intrinsic <[],[llvm_anyptr_ty], [NoCapture<0>]>;
+  def int_xcore_ssync : Intrinsic <[],[]>;
+  def int_xcore_mjoin : Intrinsic <[],[llvm_anyptr_ty], [NoCapture<0>]>;
+  def int_xcore_initsp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+                                    [NoCapture<0>]>;
+  def int_xcore_initpc : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+                                    [NoCapture<0>]>;
+  def int_xcore_initlr : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+                                    [NoCapture<0>]>;
+  def int_xcore_initcp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+                                    [NoCapture<0>]>;
+  def int_xcore_initdp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+                                    [NoCapture<0>]>;
 }
Modified: include/llvm/MC/MCAsmInfo.h
===================================================================
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -66,10 +66,9 @@ namespace llvm {
     /// relative expressions.
     const char *PCSymbol;                    // Defaults to "$".
 
-    /// SeparatorChar - This character, if specified, is used to separate
-    /// instructions from each other when on the same line.  This is used to
-    /// measure inline asm instructions.
-    char SeparatorChar;                      // Defaults to ';'
+    /// SeparatorString - This string, if specified, is used to separate
+    /// instructions from each other when on the same line.
+    const char *SeparatorString;             // Defaults to ';'
 
     /// CommentColumn - This indicates the comment num (zero-based) at
     /// which asm comments should be printed.
@@ -350,8 +349,8 @@ namespace llvm {
     const char *getPCSymbol() const {
       return PCSymbol;
     }
-    char getSeparatorChar() const {
-      return SeparatorChar;
+    const char *getSeparatorString() const {
+      return SeparatorString;
     }
     unsigned getCommentColumn() const {
       return CommentColumn;
Modified: include/llvm/MC/MCContext.h
===================================================================
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -84,6 +84,11 @@ namespace llvm {
     MCDwarfLoc CurrentDwarfLoc;
     bool DwarfLocSeen;
 
+    /// Honor temporary labels, this is useful for debugging semantic
+    /// differences between temporary and non-temporary labels (primarily on
+    /// Darwin).
+    bool AllowTemporaryLabels;
+
     /// The dwarf line information from the .loc directives for the sections
     /// with assembled machine instructions have after seeing .loc directives.
     DenseMap<const MCSection *, MCLineSection *> MCLineSections;
@@ -109,6 +114,8 @@ namespace llvm {
 
     const TargetAsmInfo &getTargetAsmInfo() const { return *TAI; }
 
+    void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; }
+
     /// @name Symbol Management
     /// @{
 
Modified: include/llvm/MC/MCParser/AsmLexer.h
===================================================================
--- a/include/llvm/MC/MCParser/AsmLexer.h
+++ b/include/llvm/MC/MCParser/AsmLexer.h
@@ -49,6 +49,7 @@ public:
   virtual StringRef LexUntilEndOfStatement();
 
   bool isAtStartOfComment(char Char);
+  bool isAtStatementSeparator(const char *Ptr);
 
   const MCAsmInfo &getMAI() const { return MAI; }
 
Modified: include/llvm/PassAnalysisSupport.h
===================================================================
--- a/include/llvm/PassAnalysisSupport.h
+++ b/include/llvm/PassAnalysisSupport.h
@@ -142,6 +142,8 @@ public:
   Pass *findImplPass(Pass *P, AnalysisID PI, Function &F);
 
   void addAnalysisImplsPair(AnalysisID PI, Pass *P) {
+    if (findImplPass(PI) == P)
+      return;
     std::pair<AnalysisID, Pass*> pir = std::make_pair(PI,P);
     AnalysisImpls.push_back(pir);
   }
Modified: include/llvm/Support/FileUtilities.h
===================================================================
--- a/include/llvm/Support/FileUtilities.h
+++ b/include/llvm/Support/FileUtilities.h
@@ -15,13 +15,14 @@
 #ifndef LLVM_SUPPORT_FILEUTILITIES_H
 #define LLVM_SUPPORT_FILEUTILITIES_H
 
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 
 namespace llvm {
 
   /// DiffFilesWithTolerance - Compare the two files specified, returning 0 if
   /// the files match, 1 if they are different, and 2 if there is a file error.
-  /// This function allows you to specify an absolete and relative FP error that
+  /// This function allows you to specify an absolute and relative FP error that
   /// is allowed to exist.  If you specify a string to fill in for the error
   /// option, it will set the string to an error message if an error occurs, or
   /// if the files are different.
@@ -37,29 +38,36 @@ namespace llvm {
   /// specified (if deleteIt is true).
   ///
   class FileRemover {
-    sys::Path Filename;
+    SmallString<128> Filename;
     bool DeleteIt;
   public:
     FileRemover() : DeleteIt(false) {}
 
-    explicit FileRemover(const sys::Path &filename, bool deleteIt = true)
-      : Filename(filename), DeleteIt(deleteIt) {}
+    explicit FileRemover(const Twine& filename, bool deleteIt = true)
+      : DeleteIt(deleteIt) {
+      filename.toVector(Filename);
+    }
 
     ~FileRemover() {
       if (DeleteIt) {
         // Ignore problems deleting the file.
-        Filename.eraseFromDisk();
+        bool existed;
+        sys::fs::remove(Filename.str(), existed);
       }
     }
 
     /// setFile - Give ownership of the file to the FileRemover so it will
     /// be removed when the object is destroyed.  If the FileRemover already
     /// had ownership of a file, remove it first.
-    void setFile(const sys::Path &filename, bool deleteIt = true) {
-      if (DeleteIt)
-        Filename.eraseFromDisk();
+    void setFile(const Twine& filename, bool deleteIt = true) {
+      if (DeleteIt) {
+        // Ignore problems deleting the file.
+        bool existed;
+        sys::fs::remove(Filename.str(), existed);
+      }
 
-      Filename = filename;
+      Filename.clear();
+      filename.toVector(Filename);
       DeleteIt = deleteIt;
     }
 
Modified: include/llvm/Support/IRBuilder.h
===================================================================
--- a/include/llvm/Support/IRBuilder.h
+++ b/include/llvm/Support/IRBuilder.h
@@ -1070,8 +1070,9 @@ public:
   // Instruction creation methods: Other Instructions
   //===--------------------------------------------------------------------===//
 
-  PHINode *CreatePHI(const Type *Ty, const Twine &Name = "") {
-    return Insert(PHINode::Create(Ty), Name);
+  PHINode *CreatePHI(const Type *Ty, unsigned NumReservedValues,
+                     const Twine &Name = "") {
+    return Insert(PHINode::Create(Ty, NumReservedValues), Name);
   }
 
   CallInst *CreateCall(Value *Callee, const Twine &Name = "") {
Modified: include/llvm/Target/TargetMachine.h
===================================================================
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -106,6 +106,7 @@ protected: // Can only create subclasses.
 
   unsigned MCRelaxAll : 1;
   unsigned MCNoExecStack : 1;
+  unsigned MCSaveTempLabels : 1;
   unsigned MCUseLoc : 1;
 
 public:
@@ -172,6 +173,14 @@ public:
   /// relaxed.
   void setMCRelaxAll(bool Value) { MCRelaxAll = Value; }
 
+  /// hasMCSaveTempLabels - Check whether temporary labels will be preserved
+  /// (i.e., not treated as temporary).
+  bool hasMCSaveTempLabels() const { return MCSaveTempLabels; }
+
+  /// setMCSaveTempLabels - Set whether temporary labels will be preserved
+  /// (i.e., not treated as temporary).
+  void setMCSaveTempLabels(bool Value) { MCSaveTempLabels = Value; }
+
   /// hasMCNoExecStack - Check whether an executable stack is not needed.
   bool hasMCNoExecStack() const { return MCNoExecStack; }
 
Modified: lib/Analysis/ConstantFolding.cpp
===================================================================
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -1048,11 +1048,12 @@ llvm::canConstantFoldCallTo(const Function *F) {
   case Intrinsic::ctpop:
   case Intrinsic::ctlz:
   case Intrinsic::cttz:
-  case Intrinsic::uadd_with_overflow:
-  case Intrinsic::usub_with_overflow:
   case Intrinsic::sadd_with_overflow:
+  case Intrinsic::uadd_with_overflow:
   case Intrinsic::ssub_with_overflow:
+  case Intrinsic::usub_with_overflow:
   case Intrinsic::smul_with_overflow:
+  case Intrinsic::umul_with_overflow:
   case Intrinsic::convert_from_fp16:
   case Intrinsic::convert_to_fp16:
   case Intrinsic::x86_sse_cvtss2si:
@@ -1362,7 +1363,8 @@ llvm::ConstantFoldCall(Function *F,
         case Intrinsic::uadd_with_overflow:
         case Intrinsic::ssub_with_overflow:
         case Intrinsic::usub_with_overflow:
-        case Intrinsic::smul_with_overflow: {
+        case Intrinsic::smul_with_overflow:
+        case Intrinsic::umul_with_overflow: {
           APInt Res;
           bool Overflow;
           switch (F->getIntrinsicID()) {
@@ -1382,6 +1384,9 @@ llvm::ConstantFoldCall(Function *F,
           case Intrinsic::smul_with_overflow:
             Res = Op1->getValue().smul_ov(Op2->getValue(), Overflow);
             break;
+          case Intrinsic::umul_with_overflow:
+            Res = Op1->getValue().umul_ov(Op2->getValue(), Overflow);
+            break;
           }
           Constant *Ops[] = {
             ConstantInt::get(F->getContext(), Res),
Modified: lib/Analysis/ScalarEvolutionExpander.cpp
===================================================================
--- a/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -932,14 +932,14 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr \
*Normalized,  Value *StepV = expandCodeFor(Step, IntTy, L->getHeader()->begin());
 
   // Create the PHI.
-  Builder.SetInsertPoint(L->getHeader(), L->getHeader()->begin());
-  PHINode *PN = Builder.CreatePHI(ExpandTy, "lsr.iv");
+  BasicBlock *Header = L->getHeader();
+  Builder.SetInsertPoint(Header, Header->begin());
+  pred_iterator HPB = pred_begin(Header), HPE = pred_end(Header);
+  PHINode *PN = Builder.CreatePHI(ExpandTy, std::distance(HPB, HPE), "lsr.iv");
   rememberInstruction(PN);
 
   // Create the step instructions and populate the PHI.
-  BasicBlock *Header = L->getHeader();
-  for (pred_iterator HPI = pred_begin(Header), HPE = pred_end(Header);
-       HPI != HPE; ++HPI) {
+  for (pred_iterator HPI = HPB; HPI != HPE; ++HPI) {
     BasicBlock *Pred = *HPI;
 
     // Add a start value.
@@ -1141,12 +1141,13 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) \
{  // Create and insert the PHI node for the induction variable in the
     // specified loop.
     BasicBlock *Header = L->getHeader();
-    CanonicalIV = PHINode::Create(Ty, "indvar", Header->begin());
+    pred_iterator HPB = pred_begin(Header), HPE = pred_end(Header);
+    CanonicalIV = PHINode::Create(Ty, std::distance(HPB, HPE), "indvar",
+                                  Header->begin());
     rememberInstruction(CanonicalIV);
 
     Constant *One = ConstantInt::get(Ty, 1);
-    for (pred_iterator HPI = pred_begin(Header), HPE = pred_end(Header);
-         HPI != HPE; ++HPI) {
+    for (pred_iterator HPI = HPB; HPI != HPE; ++HPI) {
       BasicBlock *HP = *HPI;
       if (L->contains(HP)) {
         // Insert a unit add instruction right before the terminator
Modified: lib/AsmParser/LLParser.cpp
===================================================================
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -3634,8 +3634,7 @@ int LLParser::ParsePHI(Instruction *&Inst, PerFunctionState \
&PFS) {  if (!Ty->isFirstClassType())
     return Error(TypeLoc, "phi node must have first class type");
 
-  PHINode *PN = PHINode::Create(Ty);
-  PN->reserveOperandSpace(PHIVals.size());
+  PHINode *PN = PHINode::Create(Ty, PHIVals.size());
   for (unsigned i = 0, e = PHIVals.size(); i != e; ++i)
     PN->addIncoming(PHIVals[i].first, PHIVals[i].second);
   Inst = PN;
Modified: lib/Bitcode/Reader/BitcodeReader.cpp
===================================================================
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -2288,9 +2288,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
       const Type *Ty = getTypeByID(Record[0]);
       if (!Ty) return Error("Invalid PHI record");
 
-      PHINode *PN = PHINode::Create(Ty);
+      PHINode *PN = PHINode::Create(Ty, (Record.size()-1)/2);
       InstructionList.push_back(PN);
-      PN->reserveOperandSpace((Record.size()-1)/2);
 
       for (unsigned i = 0, e = Record.size()-1; i != e; i += 2) {
         Value *V = getFnValueByID(Record[1+i], Ty);
Modified: lib/CodeGen/AsmPrinter/AsmPrinter.cpp
===================================================================
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -70,17 +70,17 @@ static unsigned getGVAlignmentLog2(const GlobalValue *GV, const \
TargetData &TD,  unsigned NumBits = 0;
   if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
     NumBits = TD.getPreferredAlignmentLog(GVar);
-  
+
   // If InBits is specified, round it to it.
   if (InBits > NumBits)
     NumBits = InBits;
-  
+
   // If the GV has a specified alignment, take it into account.
   if (GV->getAlignment() == 0)
     return NumBits;
-  
+
   unsigned GVAlign = Log2_32(GV->getAlignment());
-  
+
   // If the GVAlign is larger than NumBits, or if we are required to obey
   // NumBits because the GV has an assigned section, obey it.
   if (GVAlign > NumBits || GV->hasSection())
@@ -104,16 +104,16 @@ AsmPrinter::AsmPrinter(TargetMachine &tm, MCStreamer &Streamer)
 
 AsmPrinter::~AsmPrinter() {
   assert(DD == 0 && DE == 0 && "Debug/EH info didn't get finalized");
-  
+
   if (GCMetadataPrinters != 0) {
     gcp_map_type &GCMap = getGCMap(GCMetadataPrinters);
-    
+
     for (gcp_map_type::iterator I = GCMap.begin(), E = GCMap.end(); I != E; ++I)
       delete I->second;
     delete &GCMap;
     GCMetadataPrinters = 0;
   }
-  
+
   delete &OutStreamer;
 }
 
@@ -156,9 +156,9 @@ bool AsmPrinter::doInitialization(Module &M) {
   // Initialize TargetLoweringObjectFile.
   const_cast<TargetLoweringObjectFile&>(getObjFileLowering())
     .Initialize(OutContext, TM);
-  
+
   Mang = new Mangler(OutContext, *TM.getTargetData());
-  
+
   // Allow the target to emit any magic that it wants at the start of the file.
   EmitStartOfAsmFile(M);
 
@@ -255,7 +255,7 @@ void AsmPrinter::EmitLinkage(unsigned Linkage, MCSymbol *GVSym) \
const {  void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
   if (!GV->hasInitializer())   // External globals require no code.
     return;
-  
+
   // Check to see if this is a special global used by LLVM, if so, emit it.
   if (EmitSpecialLLVMGlobal(GV))
     return;
@@ -265,44 +265,44 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
                    /*PrintType=*/false, GV->getParent());
     OutStreamer.GetCommentOS() << '\n';
   }
-  
+
   MCSymbol *GVSym = Mang->getSymbol(GV);
   EmitVisibility(GVSym, GV->getVisibility());
 
   if (MAI->hasDotTypeDotSizeDirective())
     OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject);
-  
+
   SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM);
 
   const TargetData *TD = TM.getTargetData();
   uint64_t Size = TD->getTypeAllocSize(GV->getType()->getElementType());
-  
+
   // If the alignment is specified, we *must* obey it.  Overaligning a global
   // with a specified alignment is a prompt way to break globals emitted to
   // sections and expected to be contiguous (e.g. ObjC metadata).
   unsigned AlignLog = getGVAlignmentLog2(GV, *TD);
-  
+
   // Handle common and BSS local symbols (.lcomm).
   if (GVKind.isCommon() || GVKind.isBSSLocal()) {
     if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
-    
+
     if (isVerbose()) {
       WriteAsOperand(OutStreamer.GetCommentOS(), GV,
                      /*PrintType=*/false, GV->getParent());
       OutStreamer.GetCommentOS() << '\n';
     }
-    
+
     // Handle common symbols.
     if (GVKind.isCommon()) {
       unsigned Align = 1 << AlignLog;
       if (!getObjFileLowering().getCommDirectiveSupportsAlignment())
         Align = 0;
-          
+
       // .comm _foo, 42, 4
       OutStreamer.EmitCommonSymbol(GVSym, Size, Align);
       return;
     }
-    
+
     // Handle local BSS symbols.
     if (MAI->hasMachoZeroFillDirective()) {
       const MCSection *TheSection =
@@ -311,7 +311,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
       OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog);
       return;
     }
-    
+
     if (MAI->hasLCOMMDirective()) {
       // .lcomm _foo, 42
       OutStreamer.EmitLocalCommonSymbol(GVSym, Size);
@@ -321,14 +321,14 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
     unsigned Align = 1 << AlignLog;
     if (!getObjFileLowering().getCommDirectiveSupportsAlignment())
       Align = 0;
-    
+
     // .local _foo
     OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Local);
     // .comm _foo, 42, 4
     OutStreamer.EmitCommonSymbol(GVSym, Size, Align);
     return;
   }
-  
+
   const MCSection *TheSection =
     getObjFileLowering().SectionForGlobal(GV, GVKind, Mang, TM);
 
@@ -336,14 +336,14 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
   // emission.
   if (GVKind.isBSSExtern() && MAI->hasMachoZeroFillDirective()) {
     if (Size == 0) Size = 1;  // zerofill of 0 bytes is undefined.
-    
+
     // .globl _foo
     OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
     // .zerofill __DATA, __common, _foo, 400, 5
     OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog);
     return;
   }
-  
+
   // Handle thread local data for mach-o which requires us to output an
   // additional structure of data and mangle the original symbol so that we
   // can reference it later.
@@ -356,31 +356,31 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
   // specific code.
   if (GVKind.isThreadLocal() && MAI->hasMachoTBSSDirective()) {
     // Emit the .tbss symbol
-    MCSymbol *MangSym = 
+    MCSymbol *MangSym =
       OutContext.GetOrCreateSymbol(GVSym->getName() + Twine("$tlv$init"));
-    
+
     if (GVKind.isThreadBSS())
       OutStreamer.EmitTBSSSymbol(TheSection, MangSym, Size, 1 << AlignLog);
     else if (GVKind.isThreadData()) {
       OutStreamer.SwitchSection(TheSection);
 
-      EmitAlignment(AlignLog, GV);      
+      EmitAlignment(AlignLog, GV);
       OutStreamer.EmitLabel(MangSym);
-      
+
       EmitGlobalConstant(GV->getInitializer());
     }
-    
+
     OutStreamer.AddBlankLine();
-    
+
     // Emit the variable struct for the runtime.
-    const MCSection *TLVSect 
+    const MCSection *TLVSect
       = getObjFileLowering().getTLSExtraDataSection();
-      
+
     OutStreamer.SwitchSection(TLVSect);
     // Emit the linkage here.
     EmitLinkage(GV->getLinkage(), GVSym);
     OutStreamer.EmitLabel(GVSym);
-    
+
     // Three pointers in size:
     //   - __tlv_bootstrap - used to make sure support exists
     //   - spare pointer, used when mapped by the runtime
@@ -390,7 +390,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
                           PtrSize, 0);
     OutStreamer.EmitIntValue(0, PtrSize, 0);
     OutStreamer.EmitSymbolValue(MangSym, PtrSize, 0);
-    
+
     OutStreamer.AddBlankLine();
     return;
   }
@@ -407,7 +407,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
   if (MAI->hasDotTypeDotSizeDirective())
     // .size foo, 42
     OutStreamer.EmitELFSize(GVSym, MCConstantExpr::Create(Size, OutContext));
-  
+
   OutStreamer.AddBlankLine();
 }
 
@@ -416,7 +416,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
 void AsmPrinter::EmitFunctionHeader() {
   // Print out constants referenced by the function
   EmitConstantPool();
-  
+
   // Print the 'header' of function.
   const Function *F = MF->getFunction();
 
@@ -438,7 +438,7 @@ void AsmPrinter::EmitFunctionHeader() {
   // Emit the CurrentFnSym.  This is a virtual function to allow targets to
   // do their wild and crazy things as required.
   EmitFunctionEntryLabel();
-  
+
   // If the function had address-taken blocks that got deleted, then we have
   // references to the dangling symbols.  Emit them at the start of the function
   // so that we don't get references to undefined symbols.
@@ -448,17 +448,17 @@ void AsmPrinter::EmitFunctionHeader() {
     OutStreamer.AddComment("Address taken block that was later removed");
     OutStreamer.EmitLabel(DeadBlockSyms[i]);
   }
-  
+
   // Add some workaround for linkonce linkage on Cygwin\MinGW.
   if (MAI->getLinkOnceDirective() != 0 &&
       (F->hasLinkOnceLinkage() || F->hasWeakLinkage())) {
     // FIXME: What is this?
-    MCSymbol *FakeStub = 
+    MCSymbol *FakeStub =
       OutContext.GetOrCreateSymbol(Twine("Lllvm$workaround$fake$stub$")+
                                    CurrentFnSym->getName());
     OutStreamer.EmitLabel(FakeStub);
   }
-  
+
   // Emit pre-function debug and/or EH information.
   if (DE) {
     NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled);
@@ -483,7 +483,7 @@ void AsmPrinter::EmitFunctionEntryLabel() {
 }
 
 
-static void EmitDebugLoc(DebugLoc DL, const MachineFunction *MF, 
+static void EmitDebugLoc(DebugLoc DL, const MachineFunction *MF,
                          raw_ostream &CommentOS) {
   const LLVMContext &Ctx = MF->getFunction()->getContext();
   if (!DL.isUnknown()) {          // Print source line info.
@@ -509,18 +509,18 @@ static void EmitDebugLoc(DebugLoc DL, const MachineFunction \
*MF,  static void EmitComments(const MachineInstr &MI, raw_ostream &CommentOS) {
   const MachineFunction *MF = MI.getParent()->getParent();
   const TargetMachine &TM = MF->getTarget();
-  
+
   DebugLoc DL = MI.getDebugLoc();
   if (!DL.isUnknown()) {          // Print source line info.
     EmitDebugLoc(DL, MF, CommentOS);
     CommentOS << '\n';
   }
-  
+
   // Check for spills and reloads
   int FI;
-  
+
   const MachineFrameInfo *FrameInfo = MF->getFrameInfo();
-  
+
   // We assume a single instruction only has a spill or reload, not
   // both.
   const MachineMemOperand *MMO;
@@ -541,7 +541,7 @@ static void EmitComments(const MachineInstr &MI, raw_ostream \
&CommentOS) {  if (FrameInfo->isSpillSlotObjectIndex(FI))
       CommentOS << MMO->getSize() << "-byte Folded Spill\n";
   }
-  
+
   // Check for spill-induced copies
   if (MI.getAsmPrinterFlag(MachineInstr::ReloadReuse))
     CommentOS << " Reload Reuse\n";
@@ -615,7 +615,7 @@ static bool EmitDebugValueComment(const MachineInstr *MI, \
AsmPrinter &AP) {  }
     OS << AP.TM.getRegisterInfo()->getName(MI->getOperand(0).getReg());
   }
-  
+
   OS << '+' << MI->getOperand(1).getImm();
   // NOTE: Want this comment at start of line, don't emit with AddComment.
   AP.OutStreamer.EmitRawText(OS.str());
@@ -627,9 +627,9 @@ static bool EmitDebugValueComment(const MachineInstr *MI, \
AsmPrinter &AP) {  void AsmPrinter::EmitFunctionBody() {
   // Emit target-specific gunk before the function body.
   EmitFunctionBodyStart();
-  
+
   bool ShouldPrintDebugScopes = DD && MMI->hasDebugInfo();
-  
+
   // Print out code for the function.
   bool HasAnyRealCode = false;
   const MachineInstr *LastMI = 0;
@@ -652,7 +652,7 @@ void AsmPrinter::EmitFunctionBody() {
         NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
         DD->beginInstruction(II);
       }
-      
+
       if (isVerbose())
         EmitComments(*II, OutStreamer.GetCommentOS());
 
@@ -681,7 +681,7 @@ void AsmPrinter::EmitFunctionBody() {
         EmitInstruction(II);
         break;
       }
-      
+
       if (ShouldPrintDebugScopes) {
         NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
         DD->endInstruction(II);
@@ -708,10 +708,10 @@ void AsmPrinter::EmitFunctionBody() {
     } else  // Target not mc-ized yet.
       OutStreamer.EmitRawText(StringRef("\tnop\n"));
   }
-  
+
   // Emit target-specific gunk after the function body.
   EmitFunctionBodyEnd();
-  
+
   // If the target wants a .size directive for the size of the function, emit
   // it.
   if (MAI->hasDotTypeDotSizeDirective()) {
@@ -719,14 +719,14 @@ void AsmPrinter::EmitFunctionBody() {
     // difference between the function label and the temp label.
     MCSymbol *FnEndLabel = OutContext.CreateTempSymbol();
     OutStreamer.EmitLabel(FnEndLabel);
-    
+
     const MCExpr *SizeExp =
       MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(FnEndLabel, OutContext),
                               MCSymbolRefExpr::Create(CurrentFnSym, OutContext),
                               OutContext);
     OutStreamer.EmitELFSize(CurrentFnSym, SizeExp);
   }
-  
+
   // Emit post-function debug information.
   if (DD) {
     NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
@@ -737,16 +737,17 @@ void AsmPrinter::EmitFunctionBody() {
     DE->EndFunction();
   }
   MMI->EndFunction();
-  
+
   // Print out jump tables referenced by the function.
   EmitJumpTableInfo();
-  
+
   OutStreamer.AddBlankLine();
 }
 
 /// getDebugValueLocation - Get location information encoded by DBG_VALUE
 /// operands.
-MachineLocation AsmPrinter::getDebugValueLocation(const MachineInstr *MI) const {
+MachineLocation AsmPrinter::
+getDebugValueLocation(const MachineInstr *MI) const {
   // Target specific DBG_VALUE instructions are handled by each target.
   return MachineLocation();
 }
@@ -785,7 +786,7 @@ bool AsmPrinter::doFinalization(Module &M) {
     }
     delete DD; DD = 0;
   }
-  
+
   // If the target wants to know about weak references, print them all.
   if (MAI->getWeakRefDirective()) {
     // FIXME: This is not lazy, it would be nice to only print weak references
@@ -799,7 +800,7 @@ bool AsmPrinter::doFinalization(Module &M) {
       if (!I->hasExternalWeakLinkage()) continue;
       OutStreamer.EmitSymbolAttribute(Mang->getSymbol(I), MCSA_WeakReference);
     }
-    
+
     for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) {
       if (!I->hasExternalWeakLinkage()) continue;
       OutStreamer.EmitSymbolAttribute(Mang->getSymbol(I), MCSA_WeakReference);
@@ -825,7 +826,7 @@ bool AsmPrinter::doFinalization(Module &M) {
       EmitVisibility(Name, I->getVisibility());
 
       // Emit the directives as assignments aka .set:
-      OutStreamer.EmitAssignment(Name, 
+      OutStreamer.EmitAssignment(Name,
                                  MCSymbolRefExpr::Create(Target, OutContext));
     }
   }
@@ -842,14 +843,14 @@ bool AsmPrinter::doFinalization(Module &M) {
   if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty())
     if (const MCSection *S = MAI->getNonexecutableStackSection(OutContext))
       OutStreamer.SwitchSection(S);
-  
+
   // Allow the target to emit any magic that it wants at the end of the file,
   // after everything else has gone out.
   EmitEndOfAsmFile(M);
-  
+
   delete Mang; Mang = 0;
   MMI = 0;
-  
+
   OutStreamer.Finish();
   return false;
 }
@@ -889,7 +890,7 @@ void AsmPrinter::EmitConstantPool() {
   for (unsigned i = 0, e = CP.size(); i != e; ++i) {
     const MachineConstantPoolEntry &CPE = CP[i];
     unsigned Align = CPE.getAlignment();
-    
+
     SectionKind Kind;
     switch (CPE.getRelocationInfo()) {
     default: llvm_unreachable("Unknown section kind");
@@ -907,7 +908,7 @@ void AsmPrinter::EmitConstantPool() {
     }
 
     const MCSection *S = getObjFileLowering().getSectionForConstant(Kind);
-    
+
     // The number of sections are small, just do a linear search from the
     // last section to the first.
     bool Found = false;
@@ -956,7 +957,7 @@ void AsmPrinter::EmitConstantPool() {
 }
 
 /// EmitJumpTableInfo - Print assembly representations of the jump tables used
-/// by the current function to the current output stream.  
+/// by the current function to the current output stream.
 ///
 void AsmPrinter::EmitJumpTableInfo() {
   const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
@@ -965,7 +966,7 @@ void AsmPrinter::EmitJumpTableInfo() {
   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
   if (JT.empty()) return;
 
-  // Pick the directive to use to print the jump table entries, and switch to 
+  // Pick the directive to use to print the jump table entries, and switch to
   // the appropriate section.
   const Function *F = MF->getFunction();
   bool JTInDiffSection = false;
@@ -981,18 +982,18 @@ void AsmPrinter::EmitJumpTableInfo() {
     OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F,Mang,TM));
   } else {
     // Otherwise, drop it in the readonly section.
-    const MCSection *ReadOnlySection = 
+    const MCSection *ReadOnlySection =
       getObjFileLowering().getSectionForConstant(SectionKind::getReadOnly());
     OutStreamer.SwitchSection(ReadOnlySection);
     JTInDiffSection = true;
   }
 
   EmitAlignment(Log2_32(MJTI->getEntryAlignment(*TM.getTargetData())));
-  
+
   for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) {
     const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
-    
-    // If this jump table was deleted, ignore it. 
+
+    // If this jump table was deleted, ignore it.
     if (JTBBs.empty()) continue;
 
     // For the EK_LabelDifference32 entry, if the target supports .set, emit a
@@ -1006,15 +1007,15 @@ void AsmPrinter::EmitJumpTableInfo() {
       for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) {
         const MachineBasicBlock *MBB = JTBBs[ii];
         if (!EmittedSets.insert(MBB)) continue;
-        
+
         // .set LJTSet, LBB32-base
         const MCExpr *LHS =
           MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
         OutStreamer.EmitAssignment(GetJTSetSymbol(JTI, MBB->getNumber()),
                                 MCBinaryExpr::CreateSub(LHS, Base, OutContext));
       }
-    }          
-    
+    }
+
     // On some targets (e.g. Darwin) we want to emit two consecutive labels
     // before each jump table.  The first label is never referenced, but tells
     // the assembler and linker the extents of the jump table object.  The
@@ -1067,8 +1068,8 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo \
*MJTI,  // If the .set directive is supported, this is emitted as:
     //      .set L4_5_set_123, LBB123 - LJTI1_2
     //      .word L4_5_set_123
-    
-    // If we have emitted set directives for the jump table entries, print 
+
+    // If we have emitted set directives for the jump table entries, print
     // them rather than the entries themselves.  If we're emitting PIC, then
     // emit the table entries as differences between two text section labels.
     if (MAI->hasSetDirective()) {
@@ -1084,9 +1085,9 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo \
*MJTI,  break;
   }
   }
-  
+
   assert(Value && "Unknown entry kind!");
- 
+
   unsigned EntrySize = MJTI->getEntrySize(*TM.getTargetData());
   OutStreamer.EmitValue(Value, EntrySize, /*addrspace*/0);
 }
@@ -1106,18 +1107,18 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable \
*GV) {  if (GV->getSection() == "llvm.metadata" ||
       GV->hasAvailableExternallyLinkage())
     return true;
-  
+
   if (!GV->hasAppendingLinkage()) return false;
 
   assert(GV->hasInitializer() && "Not a special LLVM global!");
-  
+
   const TargetData *TD = TM.getTargetData();
   unsigned Align = Log2_32(TD->getPointerPrefAlignment());
   if (GV->getName() == "llvm.global_ctors") {
     OutStreamer.SwitchSection(getObjFileLowering().getStaticCtorSection());
     EmitAlignment(Align);
     EmitXXStructorList(GV->getInitializer());
-    
+
     if (TM.getRelocationModel() == Reloc::Static &&
         MAI->hasStaticCtorDtorReferenceInStaticMode()) {
       StringRef Sym(".constructors_used");
@@ -1125,8 +1126,8 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable \
*GV) {  MCSA_Reference);
     }
     return true;
-  } 
-  
+  }
+
   if (GV->getName() == "llvm.global_dtors") {
     OutStreamer.SwitchSection(getObjFileLowering().getStaticDtorSection());
     EmitAlignment(Align);
@@ -1140,7 +1141,7 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable \
*GV) {  }
     return true;
   }
-  
+
   return false;
 }
 
@@ -1151,7 +1152,7 @@ void AsmPrinter::EmitLLVMUsedList(Constant *List) {
   // Should be an array of 'i8*'.
   ConstantArray *InitList = dyn_cast<ConstantArray>(List);
   if (InitList == 0) return;
-  
+
   for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
     const GlobalValue *GV =
       dyn_cast<GlobalValue>(InitList->getOperand(i)->stripPointerCasts());
@@ -1160,7 +1161,7 @@ void AsmPrinter::EmitLLVMUsedList(Constant *List) {
   }
 }
 
-/// EmitXXStructorList - Emit the ctor or dtor list.  This just prints out the 
+/// EmitXXStructorList - Emit the ctor or dtor list.  This just prints out the
 /// function pointers, ignoring the init priority.
 void AsmPrinter::EmitXXStructorList(Constant *List) {
   // Should be an array of '{ int, void ()* }' structs.  The first value is the
@@ -1206,11 +1207,11 @@ void AsmPrinter::EmitInt32(int Value) const {
 void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
                                      unsigned Size) const {
   // Get the Hi-Lo expression.
-  const MCExpr *Diff = 
+  const MCExpr *Diff =
     MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(Hi, OutContext),
                             MCSymbolRefExpr::Create(Lo, OutContext),
                             OutContext);
-  
+
   if (!MAI->hasSetDirective()) {
     OutStreamer.EmitValue(Diff, Size, 0/*AddrSpace*/);
     return;
@@ -1222,27 +1223,27 @@ void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, \
const MCSymbol *Lo,  OutStreamer.EmitSymbolValue(SetLabel, Size, 0/*AddrSpace*/);
 }
 
-/// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo" 
+/// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo"
 /// where the size in bytes of the directive is specified by Size and Hi/Lo
 /// specify the labels.  This implicitly uses .set if it is available.
 void AsmPrinter::EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset,
-                                           const MCSymbol *Lo, unsigned Size) 
+                                           const MCSymbol *Lo, unsigned Size)
   const {
-  
+
   // Emit Hi+Offset - Lo
   // Get the Hi+Offset expression.
   const MCExpr *Plus =
-    MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Hi, OutContext), 
+    MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Hi, OutContext),
                             MCConstantExpr::Create(Offset, OutContext),
                             OutContext);
-  
+
   // Get the Hi+Offset-Lo expression.
-  const MCExpr *Diff = 
+  const MCExpr *Diff =
     MCBinaryExpr::CreateSub(Plus,
                             MCSymbolRefExpr::Create(Lo, OutContext),
                             OutContext);
-  
-  if (!MAI->hasSetDirective()) 
+
+  if (!MAI->hasSetDirective())
     OutStreamer.EmitValue(Diff, 4, 0/*AddrSpace*/);
   else {
     // Otherwise, emit with .set (aka assignment).
@@ -1252,22 +1253,22 @@ void AsmPrinter::EmitLabelOffsetDifference(const MCSymbol \
*Hi, uint64_t Offset,  }
 }
 
-/// EmitLabelPlusOffset - Emit something like ".long Label+Offset" 
+/// EmitLabelPlusOffset - Emit something like ".long Label+Offset"
 /// where the size in bytes of the directive is specified by Size and Label
 /// specifies the label.  This implicitly uses .set if it is available.
 void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
-                                      unsigned Size) 
+                                      unsigned Size)
   const {
-  
+
   // Emit Label+Offset
   const MCExpr *Plus =
-    MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Label, OutContext), 
+    MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Label, OutContext),
                             MCConstantExpr::Create(Offset, OutContext),
                             OutContext);
-  
+
   OutStreamer.EmitValue(Plus, 4, 0/*AddrSpace*/);
 }
-    
+
 
 //===----------------------------------------------------------------------===//
 
@@ -1279,9 +1280,9 @@ void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, \
uint64_t Offset,  //
 void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV) const {
   if (GV) NumBits = getGVAlignmentLog2(GV, *TM.getTargetData(), NumBits);
-  
+
   if (NumBits == 0) return;   // 1-byte aligned: no need to emit alignment.
-  
+
   if (getCurrentSection()->getKind().isText())
     OutStreamer.EmitCodeAlignment(1 << NumBits);
   else
@@ -1296,25 +1297,25 @@ void AsmPrinter::EmitAlignment(unsigned NumBits, const \
GlobalValue *GV) const {  ///
 static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) {
   MCContext &Ctx = AP.OutContext;
-  
+
   if (CV->isNullValue() || isa<UndefValue>(CV))
     return MCConstantExpr::Create(0, Ctx);
 
   if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV))
     return MCConstantExpr::Create(CI->getZExtValue(), Ctx);
-  
+
   if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV))
     return MCSymbolRefExpr::Create(AP.Mang->getSymbol(GV), Ctx);
 
   if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV))
     return MCSymbolRefExpr::Create(AP.GetBlockAddressSymbol(BA), Ctx);
-  
+
   const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV);
   if (CE == 0) {
     llvm_unreachable("Unknown constant value to lower!");
     return MCConstantExpr::Create(0, Ctx);
   }
-  
+
   switch (CE->getOpcode()) {
   default:
     // If the code isn't optimized, there may be outstanding folding
@@ -1342,21 +1343,21 @@ static const MCExpr *LowerConstant(const Constant *CV, \
AsmPrinter &AP) {  SmallVector<Value*, 8> IdxVec(CE->op_begin()+1, CE->op_end());
     int64_t Offset = TD.getIndexedOffset(PtrVal->getType(), &IdxVec[0],
                                          IdxVec.size());
-    
+
     const MCExpr *Base = LowerConstant(CE->getOperand(0), AP);
     if (Offset == 0)
       return Base;
-    
+
     // Truncate/sext the offset to the pointer size.
     if (TD.getPointerSizeInBits() != 64) {
       int SExtAmount = 64-TD.getPointerSizeInBits();
       Offset = (Offset << SExtAmount) >> SExtAmount;
     }
-    
+
     return MCBinaryExpr::CreateAdd(Base, MCConstantExpr::Create(Offset, Ctx),
                                    Ctx);
   }
-      
+
   case Instruction::Trunc:
     // We emit the value and depend on the assembler to truncate the generated
     // expression properly.  This is important for differences between
@@ -1375,7 +1376,7 @@ static const MCExpr *LowerConstant(const Constant *CV, \
AsmPrinter &AP) {  false/*ZExt*/);
     return LowerConstant(Op, AP);
   }
-    
+
   case Instruction::PtrToInt: {
     const TargetData &TD = *AP.TM.getTargetData();
     // Support only foldable casts to/from pointers that can be eliminated by
@@ -1397,7 +1398,7 @@ static const MCExpr *LowerConstant(const Constant *CV, \
                AsmPrinter &AP) {
     const MCExpr *MaskExpr = MCConstantExpr::Create(~0ULL >> (64-InBits), Ctx);
     return MCBinaryExpr::CreateAnd(OpExpr, MaskExpr, Ctx);
   }
-      
+
   // The MC library also has a right-shift operator, but it isn't consistently
   // signed or unsigned between different targets.
   case Instruction::Add:
@@ -1438,7 +1439,7 @@ static void EmitGlobalConstantArray(const ConstantArray *CA, \
unsigned AddrSpace,  EmitGlobalConstantImpl(CA->getOperand(i), AddrSpace, AP);
     return;
   }
-  
+
   // Otherwise, it can be emitted as .ascii.
   SmallVector<char, 128> TmpVec;
   TmpVec.reserve(CA->getNumOperands());
@@ -1496,7 +1497,7 @@ static void EmitGlobalConstantFP(const ConstantFP *CFP, \
unsigned AddrSpace,  AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace);
     return;
   }
-  
+
   if (CFP->getType()->isFloatTy()) {
     if (AP.isVerbose()) {
       float Val = CFP->getValueAPF().convertToFloat();
@@ -1506,7 +1507,7 @@ static void EmitGlobalConstantFP(const ConstantFP *CFP, \
unsigned AddrSpace,  AP.OutStreamer.EmitIntValue(Val, 4, AddrSpace);
     return;
   }
-  
+
   if (CFP->getType()->isX86_FP80Ty()) {
     // all long double variants are printed as hex
     // API needed to prevent premature destruction
@@ -1521,7 +1522,7 @@ static void EmitGlobalConstantFP(const ConstantFP *CFP, \
unsigned AddrSpace,  AP.OutStreamer.GetCommentOS() << "x86_fp80 ~= "
         << DoubleVal.convertToDouble() << '\n';
     }
-    
+
     if (AP.TM.getTargetData()->isBigEndian()) {
       AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace);
       AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace);
@@ -1529,14 +1530,14 @@ static void EmitGlobalConstantFP(const ConstantFP *CFP, \
unsigned AddrSpace,  AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace);
       AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace);
     }
-    
+
     // Emit the tail padding for the long double.
     const TargetData &TD = *AP.TM.getTargetData();
     AP.OutStreamer.EmitZeros(TD.getTypeAllocSize(CFP->getType()) -
                              TD.getTypeStoreSize(CFP->getType()), AddrSpace);
     return;
   }
-  
+
   assert(CFP->getType()->isPPC_FP128Ty() &&
          "Floating point constant type not handled");
   // All long double variants are printed as hex
@@ -1591,10 +1592,10 @@ static void EmitGlobalConstantImpl(const Constant *CV, \
unsigned AddrSpace,  return;
     }
   }
-  
+
   if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV))
     return EmitGlobalConstantArray(CVA, AddrSpace, AP);
-  
+
   if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))
     return EmitGlobalConstantStruct(CVS, AddrSpace, AP);
 
@@ -1606,10 +1607,10 @@ static void EmitGlobalConstantImpl(const Constant *CV, \
unsigned AddrSpace,  AP.OutStreamer.EmitIntValue(0, Size, AddrSpace);
     return;
   }
-  
+
   if (const ConstantVector *V = dyn_cast<ConstantVector>(CV))
     return EmitGlobalConstantVector(V, AddrSpace, AP);
-  
+
   // Otherwise, it must be a ConstantExpr.  Lower it to an MCExpr, then emit it
   // thread the streamer with EmitValue.
   AP.OutStreamer.EmitValue(LowerConstant(CV, AP),
@@ -1706,7 +1707,7 @@ MCSymbol *AsmPrinter::GetExternalSymbolSymbol(StringRef Sym) \
const {  SmallString<60> NameStr;
   Mang->getNameWithPrefix(NameStr, Sym);
   return OutContext.GetOrCreateSymbol(NameStr.str());
-}  
+}
 
 
 
@@ -1743,10 +1744,10 @@ static void EmitBasicBlockLoopComments(const \
MachineBasicBlock &MBB,  // Add loop depth information
   const MachineLoop *Loop = LI->getLoopFor(&MBB);
   if (Loop == 0) return;
-  
+
   MachineBasicBlock *Header = Loop->getHeader();
   assert(Header && "No header for loop");
-  
+
   // If this block is not a loop header, just print out what is the loop header
   // and return.
   if (Header != &MBB) {
@@ -1756,21 +1757,21 @@ static void EmitBasicBlockLoopComments(const \
MachineBasicBlock &MBB,  " Depth="+Twine(Loop->getLoopDepth()));
     return;
   }
-  
+
   // Otherwise, it is a loop header.  Print out information about child and
   // parent loops.
   raw_ostream &OS = AP.OutStreamer.GetCommentOS();
-  
-  PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber()); 
-  
+
+  PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber());
+
   OS << "=>";
   OS.indent(Loop->getLoopDepth()*2-2);
-  
+
   OS << "This ";
   if (Loop->empty())
     OS << "Inner ";
   OS << "Loop Header: Depth=" + Twine(Loop->getLoopDepth()) << '\n';
-  
+
   PrintChildLoopComment(OS, Loop, AP.getFunctionNumber());
 }
 
@@ -1791,7 +1792,7 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock \
*MBB) const {  const BasicBlock *BB = MBB->getBasicBlock();
     if (isVerbose())
       OutStreamer.AddComment("Block address taken");
-    
+
     std::vector<MCSymbol*> Syms = MMI->getAddrLabelSymbolToEmit(BB);
 
     for (unsigned i = 0, e = Syms.size(); i != e; ++i)
@@ -1804,9 +1805,9 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock \
*MBB) const {  if (const BasicBlock *BB = MBB->getBasicBlock())
         if (BB->hasName())
           OutStreamer.AddComment("%" + BB->getName());
-      
+
       EmitBasicBlockLoopComments(*MBB, LI, *this);
-      
+
       // NOTE: Want this comment at start of line, don't emit with AddComment.
       OutStreamer.EmitRawText(Twine(MAI->getCommentString()) + " BB#" +
                               Twine(MBB->getNumber()) + ":");
@@ -1826,7 +1827,7 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock \
*MBB) const {  void AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility,
                                 bool IsDefinition) const {
   MCSymbolAttr Attr = MCSA_Invalid;
-  
+
   switch (Visibility) {
   default: break;
   case GlobalValue::HiddenVisibility:
@@ -1853,23 +1854,23 @@ isBlockOnlyReachableByFallthrough(const MachineBasicBlock \
*MBB) const {  // then nothing falls through to it.
   if (MBB->isLandingPad() || MBB->pred_empty())
     return false;
-  
+
   // If there isn't exactly one predecessor, it can't be a fall through.
   MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI;
   ++PI2;
   if (PI2 != MBB->pred_end())
     return false;
-  
+
   // The predecessor has to be immediately before this block.
   const MachineBasicBlock *Pred = *PI;
-  
+
   if (!Pred->isLayoutSuccessor(MBB))
     return false;
-  
+
   // If the block is completely empty, then it definitely does fall through.
   if (Pred->empty())
     return true;
-  
+
   // Otherwise, check the last instruction.
   const MachineInstr &LastInst = Pred->back();
   return !LastInst.getDesc().isBarrier();
@@ -1885,9 +1886,9 @@ GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy \
*S) {  gcp_map_type::iterator GCPI = GCMap.find(S);
   if (GCPI != GCMap.end())
     return GCPI->second;
-  
+
   const char *Name = S->getName().c_str();
-  
+
   for (GCMetadataPrinterRegistry::iterator
          I = GCMetadataPrinterRegistry::begin(),
          E = GCMetadataPrinterRegistry::end(); I != E; ++I)
@@ -1897,7 +1898,7 @@ GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy \
*S) {  GCMap.insert(std::make_pair(S, GMP));
       return GMP;
     }
-  
+
   report_fatal_error("no GCMetadataPrinter registered for GC: " + Twine(Name));
   return 0;
 }
Modified: lib/CodeGen/AsmPrinter/DwarfDebug.cpp
===================================================================
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -516,7 +516,8 @@ void DwarfDebug::addSourceLine(DIE *Die, DIVariable V) {
   unsigned Line = V.getLineNumber();
   if (Line == 0)
     return;
-  unsigned FileID = GetOrCreateSourceID(V.getContext().getFilename());
+  unsigned FileID = GetOrCreateSourceID(V.getContext().getFilename(),
+                                        V.getContext().getDirectory());
   assert(FileID && "Invalid file id");
   addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
   addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@@ -532,7 +533,8 @@ void DwarfDebug::addSourceLine(DIE *Die, DIGlobalVariable G) {
   unsigned Line = G.getLineNumber();
   if (Line == 0)
     return;
-  unsigned FileID = GetOrCreateSourceID(G.getContext().getFilename());
+  unsigned FileID = GetOrCreateSourceID(G.getContext().getFilename(),
+                                        G.getContext().getDirectory());
   assert(FileID && "Invalid file id");
   addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
   addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@@ -551,7 +553,7 @@ void DwarfDebug::addSourceLine(DIE *Die, DISubprogram SP) {
   unsigned Line = SP.getLineNumber();
   if (!SP.getContext().Verify())
     return;
-  unsigned FileID = GetOrCreateSourceID(SP.getFilename());
+  unsigned FileID = GetOrCreateSourceID(SP.getFilename(), SP.getDirectory());
   assert(FileID && "Invalid file id");
   addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
   addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@@ -567,7 +569,7 @@ void DwarfDebug::addSourceLine(DIE *Die, DIType Ty) {
   unsigned Line = Ty.getLineNumber();
   if (Line == 0 || !Ty.getContext().Verify())
     return;
-  unsigned FileID = GetOrCreateSourceID(Ty.getFilename());
+  unsigned FileID = GetOrCreateSourceID(Ty.getFilename(), Ty.getDirectory());
   assert(FileID && "Invalid file id");
   addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
   addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@@ -585,7 +587,7 @@ void DwarfDebug::addSourceLine(DIE *Die, DINameSpace NS) {
     return;
   StringRef FN = NS.getFilename();
 
-  unsigned FileID = GetOrCreateSourceID(FN);
+  unsigned FileID = GetOrCreateSourceID(FN, NS.getDirectory());
   assert(FileID && "Invalid file id");
   addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
   addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@@ -1859,10 +1861,21 @@ DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {
 /// in the SourceIds map. This can update DirectoryNames and SourceFileNames
 /// maps as well.
 
-unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName){
+unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName, 
+                                         StringRef DirName) {
   // If FE did not provide a file name, then assume stdin.
   if (FileName.empty())
-    return GetOrCreateSourceID("<stdin>");
+    return GetOrCreateSourceID("<stdin>", StringRef());
+
+  // MCStream expects full path name as filename.
+  if (!DirName.empty() && !FileName.startswith("/")) {
+    std::string FullPathName(DirName.data());
+    if (!DirName.endswith("/"))
+      FullPathName += "/";
+    FullPathName += FileName.data();
+    // Here FullPathName will be copied into StringMap by GetOrCreateSourceID.
+    return GetOrCreateSourceID(StringRef(FullPathName), StringRef());
+  }
 
   StringMapEntry<unsigned> &Entry = SourceIdMap.GetOrCreateValue(FileName);
   if (Entry.getValue())
@@ -1872,7 +1885,7 @@ unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName){
   Entry.setValue(SrcId);
 
   // Print out a .file directive to specify files for .loc directives.
-  Asm->OutStreamer.EmitDwarfFileDirective(SrcId, FileName);
+  Asm->OutStreamer.EmitDwarfFileDirective(SrcId, Entry.getKey());
 
   return SrcId;
 }
@@ -1898,7 +1911,7 @@ void DwarfDebug::constructCompileUnit(const MDNode *N) {
   DICompileUnit DIUnit(N);
   StringRef FN = DIUnit.getFilename();
   StringRef Dir = DIUnit.getDirectory();
-  unsigned ID = GetOrCreateSourceID(FN);
+  unsigned ID = GetOrCreateSourceID(FN, Dir);
 
   DIE *Die = new DIE(dwarf::DW_TAG_compile_unit);
   addString(Die, dwarf::DW_AT_producer, dwarf::DW_FORM_string,
@@ -2395,38 +2408,21 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
   /// collection info from MMI table.
   collectVariableInfoFromMMITable(MF, Processed);
 
-  SmallVector<const MachineInstr *, 8> DbgValues;
-  // Collect variable information from DBG_VALUE machine instructions;
-  for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
-       I != E; ++I)
-    for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
-         II != IE; ++II) {
-      const MachineInstr *MInsn = II;
-      if (!MInsn->isDebugValue())
-        continue;
-      DbgValues.push_back(MInsn);
-    }
-
-  // This is a collection of DBG_VALUE instructions describing same variable.
-  SmallVector<const MachineInstr *, 4> MultipleValues;
-  for(SmallVector<const MachineInstr *, 8>::iterator I = DbgValues.begin(),
-        E = DbgValues.end(); I != E; ++I) {
-    const MachineInstr *MInsn = *I;
-    MultipleValues.clear();
-    if (isDbgValueInDefinedReg(MInsn))
-      MultipleValues.push_back(MInsn);
-    DIVariable DV(MInsn->getOperand(MInsn->getNumOperands() - 1).getMetadata());
-    if (Processed.count(DV) != 0)
+  for (SmallVectorImpl<const MDNode*>::const_iterator
+         UVI = UserVariables.begin(), UVE = UserVariables.end(); UVI != UVE;
+         ++UVI) {
+    const MDNode *Var = *UVI;
+    if (Processed.count(Var))
       continue;
 
-    for (SmallVector<const MachineInstr *, 8>::iterator MI = I+1,
-           ME = DbgValues.end(); MI != ME; ++MI) {
-      const MDNode *Var =
-        (*MI)->getOperand((*MI)->getNumOperands()-1).getMetadata();
-      if (Var == DV)
-        MultipleValues.push_back(*MI);
-    }
+    // History contains relevant DBG_VALUE instructions for Var and instructions
+    // clobbering it.
+    SmallVectorImpl<const MachineInstr*> &History = DbgValues[Var];
+    if (History.empty())
+      continue;
+    const MachineInstr *MInsn = History.front();
 
+    DIVariable DV(Var);
     DbgScope *Scope = NULL;
     if (DV.getTag() == dwarf::DW_TAG_arg_variable &&
         DISubprogram(DV.getContext()).describes(MF->getFunction()))
@@ -2438,6 +2434,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
       continue;
 
     Processed.insert(DV);
+    assert(MInsn->isDebugValue() && "History must begin with debug value");
     DbgVariable *RegVar = new DbgVariable(DV);
     if (!addCurrentFnArgument(MF, RegVar, Scope))
       Scope->addVariable(RegVar);
@@ -2445,21 +2442,21 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
       DbgVariableToDbgInstMap[AbsVar] = MInsn;
       VarToAbstractVarMap[RegVar] = AbsVar;
     }
-    if (MultipleValues.size() <= 1 && !RegClobberInsn.count(MInsn)) {
+
+    // Simple ranges that are fully coalesced.
+    if (History.size() <= 1 || (History.size() == 2 &&
+                                MInsn->isIdenticalTo(History.back()))) {
       DbgVariableToDbgInstMap[RegVar] = MInsn;
       continue;
     }
 
     // handle multiple DBG_VALUE instructions describing one variable.
-    if (DotDebugLocEntries.empty())
-      RegVar->setDotDebugLocOffset(0);
-    else
-      RegVar->setDotDebugLocOffset(DotDebugLocEntries.size());
+    RegVar->setDotDebugLocOffset(DotDebugLocEntries.size());
 
-    for (SmallVector<const MachineInstr *, 4>::iterator
-           MVI = MultipleValues.begin(), MVE = MultipleValues.end();
-         MVI != MVE; ++MVI) {
-      const MachineInstr *Begin = *MVI;
+    for (SmallVectorImpl<const MachineInstr*>::const_iterator
+           HI = History.begin(), HE = History.end(); HI != HE; ++HI) {
+      const MachineInstr *Begin = *HI;
+      assert(Begin->isDebugValue() && "Invalid History entry");
       MachineLocation MLoc;
       if (Begin->getNumOperands() == 3) {
         if (Begin->getOperand(0).isReg() && Begin->getOperand(1).isImm())
@@ -2467,6 +2464,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
       } else
         MLoc = Asm->getDebugValueLocation(Begin);
 
+      // FIXME: emitDebugLoc only understands registers.
       if (!MLoc.getReg())
         continue;
 
@@ -2474,17 +2472,23 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
       const MCSymbol *FLabel = getLabelBeforeInsn(Begin);
       const MCSymbol *SLabel = 0;
 
-      if (const MachineInstr *ClobberMI = RegClobberInsn.lookup(Begin))
-        // The register range starting at Begin may be clobbered.
-        SLabel = getLabelAfterInsn(ClobberMI);
-      else if (MVI + 1 == MVE)
-        // If Begin is the last instruction then its value is valid
+      if (HI + 1 == HE)
+        // If Begin is the last instruction in History then its value is valid
         // until the end of the funtion.
         SLabel = FunctionEndSym;
-      else
-        // The value is valid until the next DBG_VALUE.
-        SLabel = getLabelBeforeInsn(MVI[1]);
+      else {
+        const MachineInstr *End = HI[1];
+        if (End->isDebugValue())
+          SLabel = getLabelBeforeInsn(End);
+        else {
+          // End is a normal instruction clobbering the range.
+          SLabel = getLabelAfterInsn(End);
+          assert(SLabel && "Forgot label after clobber instruction");
+          ++HI;
+        }
+      }
 
+      // The value is valid until the next DBG_VALUE or clobber.
       DotDebugLocEntries.push_back(DotDebugLocEntry(FLabel, SLabel, MLoc));
     }
     DotDebugLocEntries.push_back(DotDebugLocEntry());
@@ -2506,66 +2510,74 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
 
 /// getLabelBeforeInsn - Return Label preceding the instruction.
 const MCSymbol *DwarfDebug::getLabelBeforeInsn(const MachineInstr *MI) {
-  DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
-    LabelsBeforeInsn.find(MI);
-  if (I == LabelsBeforeInsn.end())
-    // FunctionBeginSym always preceeds all the instruction in current function.
-    return FunctionBeginSym;
-  return I->second;
+  MCSymbol *Label = LabelsBeforeInsn.lookup(MI);
+  assert(Label && "Didn't insert label before instruction");
+  return Label;
 }
 
 /// getLabelAfterInsn - Return Label immediately following the instruction.
 const MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr *MI) {
-  DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
-    LabelsAfterInsn.find(MI);
-  if (I == LabelsAfterInsn.end())
-    return NULL;
-  return I->second;
+  return LabelsAfterInsn.lookup(MI);
 }
 
 /// beginInstruction - Process beginning of an instruction.
 void DwarfDebug::beginInstruction(const MachineInstr *MI) {
-  if (InsnNeedsLabel.count(MI) == 0) {
-    LabelsBeforeInsn[MI] = PrevLabel;
-    return;
+  // Check if source location changes, but ignore DBG_VALUE locations.
+  if (!MI->isDebugValue()) {
+    DebugLoc DL = MI->getDebugLoc();
+    if (DL != PrevInstLoc && (!DL.isUnknown() || UnknownLocations)) {
+      PrevInstLoc = DL;
+      if (!DL.isUnknown()) {
+        const MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext());
+        recordSourceLine(DL.getLine(), DL.getCol(), Scope);
+      } else
+        recordSourceLine(0, 0, 0);
+    }
   }
 
-  // Check location.
-  DebugLoc DL = MI->getDebugLoc();
-  if (!DL.isUnknown()) {
-    const MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext());
-    PrevLabel = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
-    PrevInstLoc = DL;
-    LabelsBeforeInsn[MI] = PrevLabel;
-    return;
-  }
+  // Insert labels where requested.
+  DenseMap<const MachineInstr*, MCSymbol*>::iterator I =
+    LabelsBeforeInsn.find(MI);
 
-  // If location is unknown then use temp label for this DBG_VALUE
-  // instruction.
-  if (MI->isDebugValue()) {
-    PrevLabel = MMI->getContext().CreateTempSymbol();
-    Asm->OutStreamer.EmitLabel(PrevLabel);
-    LabelsBeforeInsn[MI] = PrevLabel;
+  // No label needed.
+  if (I == LabelsBeforeInsn.end())
     return;
-  }
 
-  if (UnknownLocations) {
-    PrevLabel = recordSourceLine(0, 0, 0);
-    LabelsBeforeInsn[MI] = PrevLabel;
+  // Label already assigned.
+  if (I->second)
     return;
-  }
 
-  assert (0 && "Instruction is not processed!");
+  if (!PrevLabel) {
+    PrevLabel = MMI->getContext().CreateTempSymbol();
+    Asm->OutStreamer.EmitLabel(PrevLabel);
+  }
+  I->second = PrevLabel;
 }
 
 /// endInstruction - Process end of an instruction.
 void DwarfDebug::endInstruction(const MachineInstr *MI) {
-  if (InsnsNeedsLabelAfter.count(MI) != 0) {
-    // Emit a label if this instruction ends a scope.
-    MCSymbol *Label = MMI->getContext().CreateTempSymbol();
-    Asm->OutStreamer.EmitLabel(Label);
-    LabelsAfterInsn[MI] = Label;
+  // Don't create a new label after DBG_VALUE instructions.
+  // They don't generate code.
+  if (!MI->isDebugValue())
+    PrevLabel = 0;
+
+  DenseMap<const MachineInstr*, MCSymbol*>::iterator I =
+    LabelsAfterInsn.find(MI);
+
+  // No label needed.
+  if (I == LabelsAfterInsn.end())
+    return;
+
+  // Label already assigned.
+  if (I->second)
+    return;
+
+  // We need a label after this instruction.
+  if (!PrevLabel) {
+    PrevLabel = MMI->getContext().CreateTempSymbol();
+    Asm->OutStreamer.EmitLabel(PrevLabel);
   }
+  I->second = PrevLabel;
 }
 
 /// getOrCreateDbgScope - Create DbgScope for the scope.
@@ -2825,7 +2837,8 @@ void DwarfDebug::identifyScopeMarkers() {
            RE = Ranges.end(); RI != RE; ++RI) {
       assert(RI->first && "DbgRange does not have first instruction!");
       assert(RI->second && "DbgRange does not have second instruction!");
-      InsnsNeedsLabelAfter.insert(RI->second);
+      requestLabelBeforeInsn(RI->first);
+      requestLabelAfterInsn(RI->second);
     }
   }
 }
@@ -2903,55 +2916,77 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
 
   recordSourceLine(Line, Col, TheScope);
 
+  assert(UserVariables.empty() && DbgValues.empty() && "Maps weren't cleaned");
+
   /// ProcessedArgs - Collection of arguments already processed.
   SmallPtrSet<const MDNode *, 8> ProcessedArgs;
 
-  /// LastDbgValue - Refer back to the last DBG_VALUE instruction to mention MD.
-  DenseMap<const MDNode*, const MachineInstr*> LastDbgValue;
-
   const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
 
   /// LiveUserVar - Map physreg numbers to the MDNode they contain.
   std::vector<const MDNode*> LiveUserVar(TRI->getNumRegs());
 
-  DebugLoc PrevLoc;
   for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
-       I != E; ++I)
+       I != E; ++I) {
+    bool AtBlockEntry = true;
     for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
          II != IE; ++II) {
       const MachineInstr *MI = II;
-      DebugLoc DL = MI->getDebugLoc();
+
       if (MI->isDebugValue()) {
         assert (MI->getNumOperands() > 1 && "Invalid machine instruction!");
 
-        // Keep track of variables in registers.
+        // Keep track of user variables.
         const MDNode *Var =
           MI->getOperand(MI->getNumOperands() - 1).getMetadata();
-        LastDbgValue[Var] = MI;
+
+        // Variable is in a register, we need to check for clobbers.
         if (isDbgValueInDefinedReg(MI))
           LiveUserVar[MI->getOperand(0).getReg()] = Var;
 
-        DIVariable DV(Var);
-        if (!DV.Verify()) continue;
-        // If DBG_VALUE is for a local variable then it needs a label.
-        if (DV.getTag() != dwarf::DW_TAG_arg_variable)
-          InsnNeedsLabel.insert(MI);
-        // DBG_VALUE for inlined functions argument needs a label.
-        else if (!DISubprogram(getDISubprogram(DV.getContext())).
-                 describes(MF->getFunction()))
-          InsnNeedsLabel.insert(MI);
-        // DBG_VALUE indicating argument location change needs a label.
-        else if (!ProcessedArgs.insert(DV))
-          InsnNeedsLabel.insert(MI);
+        // Check the history of this variable.
+        SmallVectorImpl<const MachineInstr*> &History = DbgValues[Var];
+        if (History.empty()) {
+          UserVariables.push_back(Var);
+          // The first mention of a function argument gets the FunctionBeginSym
+          // label, so arguments are visible when breaking at function entry.
+          DIVariable DV(Var);
+          if (DV.Verify() && DV.getTag() == dwarf::DW_TAG_arg_variable &&
+              DISubprogram(getDISubprogram(DV.getContext()))
+                .describes(MF->getFunction()))
+            LabelsBeforeInsn[MI] = FunctionBeginSym;
+        } else {
+          // We have seen this variable before. Try to coalesce DBG_VALUEs.
+          const MachineInstr *Prev = History.back();
+          if (Prev->isDebugValue()) {
+            // Coalesce identical entries at the end of History.
+            if (History.size() >= 2 &&
+                Prev->isIdenticalTo(History[History.size() - 2]))
+              History.pop_back();
+
+            // Terminate old register assignments that don't reach MI;
+            MachineFunction::const_iterator PrevMBB = Prev->getParent();
+            if (PrevMBB != I && (!AtBlockEntry || llvm::next(PrevMBB) != I) &&
+                isDbgValueInDefinedReg(Prev)) {
+              // Previous register assignment needs to terminate at the end of
+              // its basic block.
+              MachineBasicBlock::const_iterator LastMI =
+                PrevMBB->getLastNonDebugInstr();
+              if (LastMI == PrevMBB->end())
+                // Drop DBG_VALUE for empty range.
+                History.pop_back();
+              else {
+                // Terminate after LastMI.
+                History.push_back(LastMI);
+              }
+            }
+          }
+        }
+        History.push_back(MI);
       } else {
-        // If location is unknown then instruction needs a location only if
-        // UnknownLocations flag is set.
-        if (DL.isUnknown()) {
-          if (UnknownLocations && !PrevLoc.isUnknown())
-            InsnNeedsLabel.insert(MI);
-        } else if (DL != PrevLoc)
-          // Otherwise, instruction needs a location only if it is new location.
-          InsnNeedsLabel.insert(MI);
+        // Not a DBG_VALUE instruction.
+        if (!MI->isLabel())
+          AtBlockEntry = false;
 
         // Check if the instruction clobbers any registers with debug vars.
         for (MachineInstr::const_mop_iterator MOI = MI->operands_begin(),
@@ -2967,23 +3002,59 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
             LiveUserVar[Reg] = 0;
 
             // Was MD last defined by a DBG_VALUE referring to Reg?
-            const MachineInstr *Last = LastDbgValue.lookup(Var);
-            if (!Last || Last->getParent() != MI->getParent())
+            DbgValueHistoryMap::iterator HistI = DbgValues.find(Var);
+            if (HistI == DbgValues.end())
+              continue;
+            SmallVectorImpl<const MachineInstr*> &History = HistI->second;
+            if (History.empty())
               continue;
-            if (!isDbgValueInDefinedReg(Last) ||
-                Last->getOperand(0).getReg() != Reg)
+            const MachineInstr *Prev = History.back();
+            // Sanity-check: Register assignments are terminated at the end of
+            // their block.
+            if (!Prev->isDebugValue() || Prev->getParent() != MI->getParent())
               continue;
-            // MD is clobbered. Make sure the next instruction gets a label.
-            InsnsNeedsLabelAfter.insert(MI);
-            RegClobberInsn[Last] = MI;
+            // Is the variable still in Reg?
+            if (!isDbgValueInDefinedReg(Prev) ||
+                Prev->getOperand(0).getReg() != Reg)
+              continue;
+            // Var is clobbered. Make sure the next instruction gets a label.
+            History.push_back(MI);
           }
         }
       }
+    }
+  }
+
+  for (DbgValueHistoryMap::iterator I = DbgValues.begin(), E = DbgValues.end();
+       I != E; ++I) {
+    SmallVectorImpl<const MachineInstr*> &History = I->second;
+    if (History.empty())
+      continue;
 
-      if (!DL.isUnknown() || UnknownLocations)
-        PrevLoc = DL;
+    // Make sure the final register assignments are terminated.
+    const MachineInstr *Prev = History.back();
+    if (Prev->isDebugValue() && isDbgValueInDefinedReg(Prev)) {
+      const MachineBasicBlock *PrevMBB = Prev->getParent();
+      MachineBasicBlock::const_iterator LastMI = PrevMBB->getLastNonDebugInstr();
+      if (LastMI == PrevMBB->end())
+        // Drop DBG_VALUE for empty range.
+        History.pop_back();
+      else {
+        // Terminate after LastMI.
+        History.push_back(LastMI);
+      }
+    }
+    // Request labels for the full history.
+    for (unsigned i = 0, e = History.size(); i != e; ++i) {
+      const MachineInstr *MI = History[i];
+      if (MI->isDebugValue())
+        requestLabelBeforeInsn(MI);
+      else
+        requestLabelAfterInsn(MI);
     }
+  }
 
+  PrevInstLoc = DebugLoc();
   PrevLabel = FunctionBeginSym;
 }
 
@@ -3042,13 +3113,12 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
   // Clear debug info
   CurrentFnDbgScope = NULL;
   CurrentFnArguments.clear();
-  InsnNeedsLabel.clear();
   DbgVariableToFrameIndexMap.clear();
   VarToAbstractVarMap.clear();
   DbgVariableToDbgInstMap.clear();
   DeleteContainerSeconds(DbgScopeMap);
-  InsnsNeedsLabelAfter.clear();
-  RegClobberInsn.clear();
+  UserVariables.clear();
+  DbgValues.clear();
   ConcreteScopes.clear();
   DeleteContainerSeconds(AbstractScopes);
   AbstractScopesList.clear();
@@ -3099,10 +3169,9 @@ DbgScope *DwarfDebug::findDbgScope(const MachineInstr *MInsn) \
{  /// recordSourceLine - Register a source line with debug info. Returns the
 /// unique label that was emitted and which provides correspondence to
 /// the source line list.
-MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col,
-                                       const MDNode *S) {
+void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S){
   StringRef Fn;
-
+  StringRef Dir;
   unsigned Src = 1;
   if (S) {
     DIDescriptor Scope(S);
@@ -3110,27 +3179,27 @@ MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, \
unsigned Col,  if (Scope.isCompileUnit()) {
       DICompileUnit CU(S);
       Fn = CU.getFilename();
+      Dir = CU.getDirectory();
     } else if (Scope.isFile()) {
       DIFile F(S);
       Fn = F.getFilename();
+      Dir = F.getDirectory();
     } else if (Scope.isSubprogram()) {
       DISubprogram SP(S);
       Fn = SP.getFilename();
+      Dir = SP.getDirectory();
     } else if (Scope.isLexicalBlock()) {
       DILexicalBlock DB(S);
       Fn = DB.getFilename();
+      Dir = DB.getDirectory();
     } else
       assert(0 && "Unexpected scope info");
 
-    Src = GetOrCreateSourceID(Fn);
+    Src = GetOrCreateSourceID(Fn, Dir);
   }
 
   Asm->OutStreamer.EmitDwarfLocDirective(Src, Line, Col, DWARF2_FLAG_IS_STMT,
                                          0, 0);
-
-  MCSymbol *Label = MMI->getContext().CreateTempSymbol();
-  Asm->OutStreamer.EmitLabel(Label);
-  return Label;
 }
 
 //===----------------------------------------------------------------------===//
Modified: lib/CodeGen/AsmPrinter/DwarfDebug.h
===================================================================
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -218,19 +218,16 @@ class DwarfDebug {
   /// instruction.
   DenseMap<const MachineInstr *, MCSymbol *> LabelsAfterInsn;
 
-  /// insnNeedsLabel - Collection of instructions that need a label to mark
-  /// a debuggging information entity.
-  SmallPtrSet<const MachineInstr *, 8> InsnNeedsLabel;
+  /// UserVariables - Every user variable mentioned by a DBG_VALUE instruction
+  /// in order of appearance.
+  SmallVector<const MDNode*, 8> UserVariables;
 
-  /// InsnsNeedsLabelAfter - Collection of instructions that need a label after
-  /// the instruction because they end a scope of clobber a register.
-  SmallPtrSet<const MachineInstr *, 8> InsnsNeedsLabelAfter;
-
-  /// RegClobberInsn - For each DBG_VALUE instruction referring to a register
-  /// that is clobbered before the variable gets a new DBG_VALUE, map the
-  /// instruction that clobbered the register. This instruction will also be in
-  /// InsnsNeedsLabelAfter.
-  DenseMap<const MachineInstr *, const MachineInstr *> RegClobberInsn;
+  /// DbgValues - For each user variable, keep a list of DBG_VALUE
+  /// instructions in order. The list can also contain normal instructions that
+  /// clobber the previous DBG_VALUE.
+  typedef DenseMap<const MDNode*, SmallVector<const MachineInstr*, 4> >
+    DbgValueHistoryMap;
+  DbgValueHistoryMap DbgValues;
 
   SmallVector<const MCSymbol *, 8> DebugRangeSymbols;
 
@@ -518,7 +515,7 @@ private:
   /// GetOrCreateSourceID - Look up the source id with the given directory and
   /// source file names. If none currently exists, create a new id and insert it
   /// in the SourceIds map.
-  unsigned GetOrCreateSourceID(StringRef FullName);
+  unsigned GetOrCreateSourceID(StringRef DirName, StringRef FullName);
 
   /// constructCompileUnit - Create new CompileUnit for the given 
   /// metadata node with tag DW_TAG_compile_unit.
@@ -536,7 +533,7 @@ private:
   /// recordSourceLine - Register a source line with debug info. Returns the
   /// unique label that was emitted and which provides correspondence to
   /// the source line list.
-  MCSymbol *recordSourceLine(unsigned Line, unsigned Col, const MDNode *Scope);
+  void recordSourceLine(unsigned Line, unsigned Col, const MDNode *Scope);
   
   /// recordVariableFrameIndex - Record a variable's index.
   void recordVariableFrameIndex(const DbgVariable *V, int Index);
@@ -570,6 +567,23 @@ private:
   /// side table maintained by MMI.
   void collectVariableInfoFromMMITable(const MachineFunction * MF,
                                        SmallPtrSet<const MDNode *, 16> &P);
+
+  /// requestLabelBeforeInsn - Ensure that a label will be emitted before MI.
+  void requestLabelBeforeInsn(const MachineInstr *MI) {
+    LabelsBeforeInsn.insert(std::make_pair(MI, (MCSymbol*)0));
+  }
+
+  /// getLabelBeforeInsn - Return Label preceding the instruction.
+  const MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
+
+  /// requestLabelAfterInsn - Ensure that a label will be emitted after MI.
+  void requestLabelAfterInsn(const MachineInstr *MI) {
+    LabelsAfterInsn.insert(std::make_pair(MI, (MCSymbol*)0));
+  }
+
+  /// getLabelAfterInsn - Return Label immediately following the instruction.
+  const MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
+
 public:
   //===--------------------------------------------------------------------===//
   // Main entry points.
@@ -593,12 +607,6 @@ public:
   ///
   void endFunction(const MachineFunction *MF);
 
-  /// getLabelBeforeInsn - Return Label preceding the instruction.
-  const MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
-
-  /// getLabelAfterInsn - Return Label immediately following the instruction.
-  const MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
-
   /// beginInstruction - Process beginning of an instruction.
   void beginInstruction(const MachineInstr *MI);
 
Modified: lib/CodeGen/CalcSpillWeights.cpp
===================================================================
--- a/lib/CodeGen/CalcSpillWeights.cpp
+++ b/lib/CodeGen/CalcSpillWeights.cpp
@@ -103,6 +103,9 @@ void VirtRegAuxInfo::CalculateWeightAndHint(LiveInterval &li) {
   // Don't recompute a target specific hint.
   bool noHint = mri.getRegAllocationHint(li.reg).first != 0;
 
+  // Don't recompute spill weight for an unspillable register.
+  bool Spillable = li.isSpillable();
+
   for (MachineRegisterInfo::reg_iterator I = mri.reg_begin(li.reg);
        MachineInstr *mi = I.skipInstruction();) {
     if (mi->isIdentityCopy() || mi->isImplicitDef() || mi->isDebugValue())
@@ -110,25 +113,28 @@ void VirtRegAuxInfo::CalculateWeightAndHint(LiveInterval &li) {
     if (!visited.insert(mi))
       continue;
 
-    // Get loop info for mi.
-    if (mi->getParent() != mbb) {
-      mbb = mi->getParent();
-      loop = loops_.getLoopFor(mbb);
-      loopDepth = loop ? loop->getLoopDepth() : 0;
-      isExiting = loop ? loop->isLoopExiting(mbb) : false;
+    float weight = 1.0f;
+    if (Spillable) {
+      // Get loop info for mi.
+      if (mi->getParent() != mbb) {
+        mbb = mi->getParent();
+        loop = loops_.getLoopFor(mbb);
+        loopDepth = loop ? loop->getLoopDepth() : 0;
+        isExiting = loop ? loop->isLoopExiting(mbb) : false;
+      }
+
+      // Calculate instr weight.
+      bool reads, writes;
+      tie(reads, writes) = mi->readsWritesVirtualRegister(li.reg);
+      weight = LiveIntervals::getSpillWeight(writes, reads, loopDepth);
+
+      // Give extra weight to what looks like a loop induction variable update.
+      if (writes && isExiting && lis_.isLiveOutOfMBB(li, mbb))
+        weight *= 3;
+
+      totalWeight += weight;
     }
 
-    // Calculate instr weight.
-    bool reads, writes;
-    tie(reads, writes) = mi->readsWritesVirtualRegister(li.reg);
-    float weight = LiveIntervals::getSpillWeight(writes, reads, loopDepth);
-
-    // Give extra weight to what looks like a loop induction variable update.
-    if (writes && isExiting && lis_.isLiveOutOfMBB(li, mbb))
-      weight *= 3;
-
-    totalWeight += weight;
-
     // Get allocation hints from copies.
     if (noHint || !mi->isCopy())
       continue;
@@ -150,10 +156,14 @@ void VirtRegAuxInfo::CalculateWeightAndHint(LiveInterval &li) {
   // Always prefer the physreg hint.
   if (unsigned hint = hintPhys ? hintPhys : hintVirt) {
     mri.setRegAllocationHint(li.reg, 0, hint);
-    // Weakly boost the spill weifght of hinted registers.
+    // Weakly boost the spill weight of hinted registers.
     totalWeight *= 1.01F;
   }
 
+  // If the live interval was already unspillable, leave it that way.
+  if (!Spillable)
+    return;
+
   // Mark li as unspillable if all live ranges are tiny.
   if (li.isZeroLength()) {
     li.markNotSpillable();
Modified: lib/CodeGen/DwarfEHPrepare.cpp
===================================================================
--- a/lib/CodeGen/DwarfEHPrepare.cpp
+++ b/lib/CodeGen/DwarfEHPrepare.cpp
@@ -439,8 +439,9 @@ bool DwarfEHPrepare::NormalizeLandingPads() {
       if (InVal == 0) {
         // Different unwind edges have different values.  Create a new PHI node
         // in NewBB.
-        PHINode *NewPN = PHINode::Create(PN->getType(), PN->getName()+".unwind",
-                                         NewBB);
+        PHINode *NewPN = PHINode::Create(PN->getType(),
+                                         PN->getNumIncomingValues(),
+                                         PN->getName()+".unwind", NewBB);
         // Add an entry for each unwind edge, using the value from the old PHI.
         for (pred_iterator PI = PB; PI != PE; ++PI)
           NewPN->addIncoming(PN->getIncomingValueForBlock(*PI), *PI);
Modified: lib/CodeGen/InlineSpiller.cpp
===================================================================
--- a/lib/CodeGen/InlineSpiller.cpp
+++ b/lib/CodeGen/InlineSpiller.cpp
@@ -48,7 +48,7 @@ class InlineSpiller : public Spiller {
 
   // Variables that are valid during spill(), but used by multiple methods.
   LiveRangeEdit *Edit;
-  const TargetRegisterClass *RC;
+  LiveInterval *StackInt;
   int StackSlot;
   unsigned Original;
 
@@ -120,13 +120,14 @@ private:
   }
 
   bool isSibling(unsigned Reg);
-  void traceSiblingValue(unsigned, VNInfo*, VNInfo*);
+  MachineInstr *traceSiblingValue(unsigned, VNInfo*, VNInfo*);
   void analyzeSiblingValues();
 
   bool hoistSpill(LiveInterval &SpillLI, MachineInstr *CopyMI);
   void eliminateRedundantSpills(LiveInterval &LI, VNInfo *VNI);
 
-  bool reMaterializeFor(MachineBasicBlock::iterator MI);
+  void markValueUsed(LiveInterval*, VNInfo*);
+  bool reMaterializeFor(LiveInterval&, MachineBasicBlock::iterator MI);
   void reMaterializeAll();
 
   bool coalesceStackAccess(MachineInstr *MI, unsigned Reg);
@@ -138,6 +139,7 @@ private:
                    MachineBasicBlock::iterator MI);
 
   void spillAroundUses(unsigned Reg);
+  void spillAll();
 };
 }
 
@@ -277,10 +279,10 @@ bool InlineSpiller::isSibling(unsigned Reg) {
 /// Determine if the value is defined by all reloads, so spilling isn't
 /// necessary - the value is already in the stack slot.
 ///
-/// Find a defining instruction that may be a candidate for rematerialization.
+/// Return a defining instruction that may be a candidate for rematerialization.
 ///
-void InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo *UseVNI,
-                                      VNInfo *OrigVNI) {
+MachineInstr *InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo *UseVNI,
+                                               VNInfo *OrigVNI) {
   DEBUG(dbgs() << "Tracing value " << PrintReg(UseReg) << ':'
                << UseVNI->id << '@' << UseVNI->def << '\n');
   SmallPtrSet<VNInfo*, 8> Visited;
@@ -365,7 +367,7 @@ void InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo \
*UseVNI,  // We have an 'original' def. Don't record trivial cases.
     if (VNI == UseVNI) {
       DEBUG(dbgs() << "Not a sibling copy.\n");
-      return;
+      return MI;
     }
 
     // Potential remat candidate.
@@ -385,10 +387,13 @@ void InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo \
*UseVNI,  << SVI.SpillVNI->id << '@' << SVI.SpillVNI->def << '\n';
   });
   SibValues.insert(std::make_pair(UseVNI, SVI));
+  return SVI.DefMI;
 }
 
 /// analyzeSiblingValues - Trace values defined by sibling copies back to
 /// something that isn't a sibling copy.
+///
+/// Keep track of values that may be rematerializable.
 void InlineSpiller::analyzeSiblingValues() {
   SibValues.clear();
 
@@ -403,11 +408,19 @@ void InlineSpiller::analyzeSiblingValues() {
     for (LiveInterval::const_vni_iterator VI = LI.vni_begin(),
          VE = LI.vni_end(); VI != VE; ++VI) {
       VNInfo *VNI = *VI;
-      if (VNI->isUnused() || !(VNI->isPHIDef() || VNI->getCopy()))
+      if (VNI->isUnused())
         continue;
-      VNInfo *OrigVNI = OrigLI.getVNInfoAt(VNI->def);
-      if (OrigVNI->def != VNI->def)
-        traceSiblingValue(Reg, VNI, OrigVNI);
+      MachineInstr *DefMI = 0;
+      // Check possible sibling copies.
+      if (VNI->isPHIDef() || VNI->getCopy()) {
+        VNInfo *OrigVNI = OrigLI.getVNInfoAt(VNI->def);
+        if (OrigVNI->def != VNI->def)
+          DefMI = traceSiblingValue(Reg, VNI, OrigVNI);
+      }
+      if (!DefMI && !VNI->isPHIDef())
+        DefMI = LIS.getInstructionFromIndex(VNI->def);
+      if (DefMI)
+        Edit->checkRematerializable(VNI, DefMI, TII, AA);
     }
   }
 }
@@ -431,12 +444,12 @@ bool InlineSpiller::hoistSpill(LiveInterval &SpillLI, \
MachineInstr *CopyMI) {  // Conservatively extend the stack slot range to the range \
of the original  // value. We may be able to do better with stack slot coloring by \
being more  // careful here.
-  LiveInterval &StackInt = LSS.getInterval(StackSlot);
+  assert(StackInt && "No stack slot assigned yet.");
   LiveInterval &OrigLI = LIS.getInterval(Original);
   VNInfo *OrigVNI = OrigLI.getVNInfoAt(Idx);
-  StackInt.MergeValueInAsValue(OrigLI, OrigVNI, StackInt.getValNumInfo(0));
+  StackInt->MergeValueInAsValue(OrigLI, OrigVNI, StackInt->getValNumInfo(0));
   DEBUG(dbgs() << "\tmerged orig valno " << OrigVNI->id << ": "
-               << StackInt << '\n');
+               << *StackInt << '\n');
 
   // Already spilled everywhere.
   if (SVI.AllDefsAreReloads)
@@ -455,7 +468,8 @@ bool InlineSpiller::hoistSpill(LiveInterval &SpillLI, \
MachineInstr *CopyMI) {  ++MII;
   }
   // Insert spill without kill flag immediately after def.
-  TII.storeRegToStackSlot(*MBB, MII, SVI.SpillReg, false, StackSlot, RC, &TRI);
+  TII.storeRegToStackSlot(*MBB, MII, SVI.SpillReg, false, StackSlot,
+                          MRI.getRegClass(SVI.SpillReg), &TRI);
   --MII; // Point to store instruction.
   LIS.InsertMachineInstrInMaps(MII);
   VRM.addSpillSlotUse(StackSlot, MII);
@@ -469,7 +483,7 @@ void InlineSpiller::eliminateRedundantSpills(LiveInterval &SLI, \
VNInfo *VNI) {  assert(VNI && "Missing value");
   SmallVector<std::pair<LiveInterval*, VNInfo*>, 8> WorkList;
   WorkList.push_back(std::make_pair(&SLI, VNI));
-  LiveInterval &StackInt = LSS.getInterval(StackSlot);
+  assert(StackInt && "No stack slot assigned yet.");
 
   do {
     LiveInterval *LI;
@@ -483,8 +497,8 @@ void InlineSpiller::eliminateRedundantSpills(LiveInterval &SLI, \
VNInfo *VNI) {  continue;
 
     // Add all of VNI's live range to StackInt.
-    StackInt.MergeValueInAsValue(*LI, VNI, StackInt.getValNumInfo(0));
-    DEBUG(dbgs() << "Merged to stack int: " << StackInt << '\n');
+    StackInt->MergeValueInAsValue(*LI, VNI, StackInt->getValNumInfo(0));
+    DEBUG(dbgs() << "Merged to stack int: " << *StackInt << '\n');
 
     // Find all spills and copies of VNI.
     for (MachineRegisterInfo::use_nodbg_iterator UI = MRI.use_nodbg_begin(Reg);
@@ -519,45 +533,85 @@ void InlineSpiller::eliminateRedundantSpills(LiveInterval &SLI, \
VNInfo *VNI) {  } while (!WorkList.empty());
 }
 
+
+//===----------------------------------------------------------------------===//
+//                            Rematerialization
+//===----------------------------------------------------------------------===//
+
+/// markValueUsed - Remember that VNI failed to rematerialize, so its defining
+/// instruction cannot be eliminated. See through snippet copies
+void InlineSpiller::markValueUsed(LiveInterval *LI, VNInfo *VNI) {
+  SmallVector<std::pair<LiveInterval*, VNInfo*>, 8> WorkList;
+  WorkList.push_back(std::make_pair(LI, VNI));
+  do {
+    tie(LI, VNI) = WorkList.pop_back_val();
+    if (!UsedValues.insert(VNI))
+      continue;
+
+    if (VNI->isPHIDef()) {
+      MachineBasicBlock *MBB = LIS.getMBBFromIndex(VNI->def);
+      for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
+             PE = MBB->pred_end(); PI != PE; ++PI) {
+        VNInfo *PVNI = LI->getVNInfoAt(LIS.getMBBEndIdx(*PI).getPrevSlot());
+        if (PVNI)
+          WorkList.push_back(std::make_pair(LI, PVNI));
+      }
+      continue;
+    }
+
+    // Follow snippet copies.
+    MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def);
+    if (!SnippetCopies.count(MI))
+      continue;
+    LiveInterval &SnipLI = LIS.getInterval(MI->getOperand(1).getReg());
+    assert(isRegToSpill(SnipLI.reg) && "Unexpected register in copy");
+    VNInfo *SnipVNI = SnipLI.getVNInfoAt(VNI->def.getUseIndex());
+    assert(SnipVNI && "Snippet undefined before copy");
+    WorkList.push_back(std::make_pair(&SnipLI, SnipVNI));
+  } while (!WorkList.empty());
+}
+
 /// reMaterializeFor - Attempt to rematerialize before MI instead of reloading.
-bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) {
+bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg,
+                                     MachineBasicBlock::iterator MI) {
   SlotIndex UseIdx = LIS.getInstructionIndex(MI).getUseIndex();
-  VNInfo *OrigVNI = Edit->getParent().getVNInfoAt(UseIdx);
+  VNInfo *ParentVNI = VirtReg.getVNInfoAt(UseIdx);
 
-  if (!OrigVNI) {
+  if (!ParentVNI) {
     DEBUG(dbgs() << "\tadding <undef> flags: ");
     for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
       MachineOperand &MO = MI->getOperand(i);
-      if (MO.isReg() && MO.isUse() && MO.getReg() == Edit->getReg())
+      if (MO.isReg() && MO.isUse() && MO.getReg() == VirtReg.reg)
         MO.setIsUndef();
     }
     DEBUG(dbgs() << UseIdx << '\t' << *MI);
     return true;
   }
 
-  // FIXME: Properly remat for snippets as well.
-  if (SnippetCopies.count(MI)) {
-    UsedValues.insert(OrigVNI);
+  if (SnippetCopies.count(MI))
     return false;
-  }
 
-  LiveRangeEdit::Remat RM(OrigVNI);
+  // Use an OrigVNI from traceSiblingValue when ParentVNI is a sibling copy.
+  LiveRangeEdit::Remat RM(ParentVNI);
+  SibValueMap::const_iterator SibI = SibValues.find(ParentVNI);
+  if (SibI != SibValues.end())
+    RM.OrigMI = SibI->second.DefMI;
   if (!Edit->canRematerializeAt(RM, UseIdx, false, LIS)) {
-    UsedValues.insert(OrigVNI);
+    markValueUsed(&VirtReg, ParentVNI);
     DEBUG(dbgs() << "\tcannot remat for " << UseIdx << '\t' << *MI);
     return false;
   }
 
-  // If the instruction also writes Edit->getReg(), it had better not require
-  // the same register for uses and defs.
+  // If the instruction also writes VirtReg.reg, it had better not require the
+  // same register for uses and defs.
   bool Reads, Writes;
   SmallVector<unsigned, 8> Ops;
-  tie(Reads, Writes) = MI->readsWritesVirtualRegister(Edit->getReg(), &Ops);
+  tie(Reads, Writes) = MI->readsWritesVirtualRegister(VirtReg.reg, &Ops);
   if (Writes) {
     for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
       MachineOperand &MO = MI->getOperand(Ops[i]);
       if (MO.isUse() ? MI->isRegTiedToDefOperand(Ops[i]) : MO.getSubReg()) {
-        UsedValues.insert(OrigVNI);
+        markValueUsed(&VirtReg, ParentVNI);
         DEBUG(dbgs() << "\tcannot remat tied reg: " << UseIdx << '\t' << *MI);
         return false;
       }
@@ -573,13 +627,9 @@ bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator \
MI) {  }
 
   // Alocate a new register for the remat.
-  LiveInterval &NewLI = Edit->create(LIS, VRM);
+  LiveInterval &NewLI = Edit->createFrom(Original, LIS, VRM);
   NewLI.markNotSpillable();
 
-  // Rematting for a copy: Set allocation hint to be the destination register.
-  if (MI->isCopy())
-    MRI.setRegAllocationHint(NewLI.reg, 0, MI->getOperand(0).getReg());
-
   // Finally we can rematerialize OrigMI before MI.
   SlotIndex DefIdx = Edit->rematerializeAt(*MI->getParent(), MI, NewLI.reg, RM,
                                            LIS, TII, TRI);
@@ -589,7 +639,7 @@ bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator \
MI) {  // Replace operands
   for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
     MachineOperand &MO = MI->getOperand(Ops[i]);
-    if (MO.isReg() && MO.isUse() && MO.getReg() == Edit->getReg()) {
+    if (MO.isReg() && MO.isUse() && MO.getReg() == VirtReg.reg) {
       MO.setReg(NewLI.reg);
       MO.setIsKill();
     }
@@ -605,61 +655,71 @@ bool \
InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) {  /// \
reMaterializeAll - Try to rematerialize as many uses as possible,  /// and trim the \
live ranges after.  void InlineSpiller::reMaterializeAll() {
-  // Do a quick scan of the interval values to find if any are remattable.
+  // analyzeSiblingValues has already tested all relevant defining instructions.
   if (!Edit->anyRematerializable(LIS, TII, AA))
     return;
 
   UsedValues.clear();
 
-  // Try to remat before all uses of Edit->getReg().
+  // Try to remat before all uses of snippets.
   bool anyRemat = false;
-  for (MachineRegisterInfo::use_nodbg_iterator
-       RI = MRI.use_nodbg_begin(Edit->getReg());
-       MachineInstr *MI = RI.skipInstruction();)
-     anyRemat |= reMaterializeFor(MI);
-
+  for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i) {
+    unsigned Reg = RegsToSpill[i];
+    LiveInterval &LI = LIS.getInterval(Reg);
+    for (MachineRegisterInfo::use_nodbg_iterator
+         RI = MRI.use_nodbg_begin(Reg);
+         MachineInstr *MI = RI.skipInstruction();)
+      anyRemat |= reMaterializeFor(LI, MI);
+  }
   if (!anyRemat)
     return;
 
   // Remove any values that were completely rematted.
-  bool anyRemoved = false;
-  for (LiveInterval::vni_iterator I = Edit->getParent().vni_begin(),
-       E = Edit->getParent().vni_end(); I != E; ++I) {
-    VNInfo *VNI = *I;
-    if (VNI->hasPHIKill() || !Edit->didRematerialize(VNI) ||
-        UsedValues.count(VNI))
-      continue;
-    MachineInstr *DefMI = LIS.getInstructionFromIndex(VNI->def);
-    DEBUG(dbgs() << "\tremoving dead def: " << VNI->def << '\t' << *DefMI);
-    LIS.RemoveMachineInstrFromMaps(DefMI);
-    VRM.RemoveMachineInstrFromMaps(DefMI);
-    DefMI->eraseFromParent();
-    VNI->def = SlotIndex();
-    anyRemoved = true;
+  for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i) {
+    unsigned Reg = RegsToSpill[i];
+    LiveInterval &LI = LIS.getInterval(Reg);
+    for (LiveInterval::vni_iterator I = LI.vni_begin(), E = LI.vni_end();
+         I != E; ++I) {
+      VNInfo *VNI = *I;
+      if (VNI->isUnused() || VNI->isPHIDef() || UsedValues.count(VNI))
+        continue;
+      MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def);
+      MI->addRegisterDead(Reg, &TRI);
+      if (!MI->allDefsAreDead())
+        continue;
+      DEBUG(dbgs() << "All defs dead: " << *MI);
+      DeadDefs.push_back(MI);
+    }
   }
 
-  if (!anyRemoved)
+  // Eliminate dead code after remat. Note that some snippet copies may be
+  // deleted here.
+  if (DeadDefs.empty())
     return;
-
-  // Removing values may cause debug uses where parent is not live.
-  for (MachineRegisterInfo::use_iterator RI = MRI.use_begin(Edit->getReg());
-       MachineInstr *MI = RI.skipInstruction();) {
-    if (!MI->isDebugValue())
+  DEBUG(dbgs() << "Remat created " << DeadDefs.size() << " dead defs.\n");
+  Edit->eliminateDeadDefs(DeadDefs, LIS, VRM, TII);
+
+  // Get rid of deleted and empty intervals.
+  for (unsigned i = RegsToSpill.size(); i != 0; --i) {
+    unsigned Reg = RegsToSpill[i-1];
+    if (!LIS.hasInterval(Reg)) {
+      RegsToSpill.erase(RegsToSpill.begin() + (i - 1));
       continue;
-    // Try to preserve the debug value if parent is live immediately after it.
-    MachineBasicBlock::iterator NextMI = MI;
-    ++NextMI;
-    if (NextMI != MI->getParent()->end() && !LIS.isNotInMIMap(NextMI)) {
-      SlotIndex Idx = LIS.getInstructionIndex(NextMI);
-      VNInfo *VNI = Edit->getParent().getVNInfoAt(Idx);
-      if (VNI && (VNI->hasPHIKill() || UsedValues.count(VNI)))
-        continue;
     }
-    DEBUG(dbgs() << "Removing debug info due to remat:" << "\t" << *MI);
-    MI->eraseFromParent();
+    LiveInterval &LI = LIS.getInterval(Reg);
+    if (!LI.empty())
+      continue;
+    Edit->eraseVirtReg(Reg, LIS);
+    RegsToSpill.erase(RegsToSpill.begin() + (i - 1));
   }
+  DEBUG(dbgs() << RegsToSpill.size() << " registers to spill after remat.\n");
 }
 
+
+//===----------------------------------------------------------------------===//
+//                                 Spilling
+//===----------------------------------------------------------------------===//
+
 /// If MI is a load or store of StackSlot, it can be removed.
 bool InlineSpiller::coalesceStackAccess(MachineInstr *MI, unsigned Reg) {
   int FI = 0;
@@ -723,7 +783,8 @@ void InlineSpiller::insertReload(LiveInterval &NewLI,
                                  MachineBasicBlock::iterator MI) {
   MachineBasicBlock &MBB = *MI->getParent();
   SlotIndex Idx = LIS.getInstructionIndex(MI).getDefIndex();
-  TII.loadRegFromStackSlot(MBB, MI, NewLI.reg, StackSlot, RC, &TRI);
+  TII.loadRegFromStackSlot(MBB, MI, NewLI.reg, StackSlot,
+                           MRI.getRegClass(NewLI.reg), &TRI);
   --MI; // Point to load instruction.
   SlotIndex LoadIdx = LIS.InsertMachineInstrInMaps(MI).getDefIndex();
   VRM.addSpillSlotUse(StackSlot, MI);
@@ -744,7 +805,8 @@ void InlineSpiller::insertSpill(LiveInterval &NewLI, const \
LiveInterval &OldLI,  assert(VNI && VNI->def.getDefIndex() == Idx && "Inconsistent \
VNInfo");  Idx = VNI->def;
 
-  TII.storeRegToStackSlot(MBB, ++MI, NewLI.reg, true, StackSlot, RC, &TRI);
+  TII.storeRegToStackSlot(MBB, ++MI, NewLI.reg, true, StackSlot,
+                          MRI.getRegClass(NewLI.reg), &TRI);
   --MI; // Point to store instruction.
   SlotIndex StoreIdx = LIS.InsertMachineInstrInMaps(MI).getDefIndex();
   VRM.addSpillSlotUse(StackSlot, MI);
@@ -818,7 +880,7 @@ void InlineSpiller::spillAroundUses(unsigned Reg) {
 
     // Allocate interval around instruction.
     // FIXME: Infer regclass from instruction alone.
-    LiveInterval &NewLI = Edit->create(LIS, VRM);
+    LiveInterval &NewLI = Edit->createFrom(Reg, LIS, VRM);
     NewLI.markNotSpillable();
 
     if (Reads)
@@ -846,46 +908,24 @@ void InlineSpiller::spillAroundUses(unsigned Reg) {
   }
 }
 
-void InlineSpiller::spill(LiveRangeEdit &edit) {
-  Edit = &edit;
-  assert(!TargetRegisterInfo::isStackSlot(edit.getReg())
-         && "Trying to spill a stack slot.");
-  // Share a stack slot among all descendants of Original.
-  Original = VRM.getOriginal(edit.getReg());
-  StackSlot = VRM.getStackSlot(Original);
-
-  DEBUG(dbgs() << "Inline spilling "
-               << MRI.getRegClass(edit.getReg())->getName()
-               << ':' << edit.getParent() << "\nFrom original "
-               << LIS.getInterval(Original) << '\n');
-  assert(edit.getParent().isSpillable() &&
-         "Attempting to spill already spilled value.");
-  assert(DeadDefs.empty() && "Previous spill didn't remove dead defs");
-
-  collectRegsToSpill();
-  analyzeSiblingValues();
-  reMaterializeAll();
-
-  // Remat may handle everything.
-  if (Edit->getParent().empty())
-    return;
-
-  RC = MRI.getRegClass(edit.getReg());
-
-  if (StackSlot == VirtRegMap::NO_STACK_SLOT)
+/// spillAll - Spill all registers remaining after rematerialization.
+void InlineSpiller::spillAll() {
+  // Update LiveStacks now that we are committed to spilling.
+  if (StackSlot == VirtRegMap::NO_STACK_SLOT) {
     StackSlot = VRM.assignVirt2StackSlot(Original);
+    StackInt = &LSS.getOrCreateInterval(StackSlot, MRI.getRegClass(Original));
+    StackInt->getNextValue(SlotIndex(), 0, LSS.getVNInfoAllocator());
+  } else
+    StackInt = &LSS.getInterval(StackSlot);
 
-  if (Original != edit.getReg())
-    VRM.assignVirt2StackSlot(edit.getReg(), StackSlot);
+  if (Original != Edit->getReg())
+    VRM.assignVirt2StackSlot(Edit->getReg(), StackSlot);
 
-  // Update LiveStacks now that we are committed to spilling.
-  LiveInterval &stacklvr = LSS.getOrCreateInterval(StackSlot, RC);
-  if (!stacklvr.hasAtLeastOneValue())
-    stacklvr.getNextValue(SlotIndex(), 0, LSS.getVNInfoAllocator());
+  assert(StackInt->getNumValNums() == 1 && "Bad stack interval values");
   for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i)
-    stacklvr.MergeRangesInAsValue(LIS.getInterval(RegsToSpill[i]),
-                                  stacklvr.getValNumInfo(0));
-  DEBUG(dbgs() << "Merged spilled regs: " << stacklvr << '\n');
+    StackInt->MergeRangesInAsValue(LIS.getInterval(RegsToSpill[i]),
+                                   StackInt->getValNumInfo(0));
+  DEBUG(dbgs() << "Merged spilled regs: " << *StackInt << '\n');
 
   // Spill around uses of all RegsToSpill.
   for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i)
@@ -898,7 +938,7 @@ void InlineSpiller::spill(LiveRangeEdit &edit) {
   }
 
   // Finally delete the SnippetCopies.
-  for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(edit.getReg());
+  for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Edit->getReg());
        MachineInstr *MI = RI.skipInstruction();) {
     assert(SnippetCopies.count(MI) && "Remaining use wasn't a snippet copy");
     // FIXME: Do this with a LiveRangeEdit callback.
@@ -907,6 +947,35 @@ void InlineSpiller::spill(LiveRangeEdit &edit) {
     MI->eraseFromParent();
   }
 
+  // Delete all spilled registers.
   for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i)
-    edit.eraseVirtReg(RegsToSpill[i], LIS);
+    Edit->eraseVirtReg(RegsToSpill[i], LIS);
+}
+
+void InlineSpiller::spill(LiveRangeEdit &edit) {
+  Edit = &edit;
+  assert(!TargetRegisterInfo::isStackSlot(edit.getReg())
+         && "Trying to spill a stack slot.");
+  // Share a stack slot among all descendants of Original.
+  Original = VRM.getOriginal(edit.getReg());
+  StackSlot = VRM.getStackSlot(Original);
+  StackInt = 0;
+
+  DEBUG(dbgs() << "Inline spilling "
+               << MRI.getRegClass(edit.getReg())->getName()
+               << ':' << edit.getParent() << "\nFrom original "
+               << LIS.getInterval(Original) << '\n');
+  assert(edit.getParent().isSpillable() &&
+         "Attempting to spill already spilled value.");
+  assert(DeadDefs.empty() && "Previous spill didn't remove dead defs");
+
+  collectRegsToSpill();
+  analyzeSiblingValues();
+  reMaterializeAll();
+
+  // Remat may handle everything.
+  if (!RegsToSpill.empty())
+    spillAll();
+
+  Edit->calculateRegClassAndHint(MF, LIS, Loops);
 }
Modified: lib/CodeGen/LLVMTargetMachine.cpp
===================================================================
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -126,6 +126,9 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
     return true;
   assert(Context != 0 && "Failed to get MCContext");
 
+  if (hasMCSaveTempLabels())
+    Context->setAllowTemporaryLabels(false);
+
   const MCAsmInfo &MAI = *getMCAsmInfo();
   OwningPtr<MCStreamer> AsmStreamer;
 
@@ -231,6 +234,9 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
   if (addCommonCodeGenPasses(PM, OptLevel, DisableVerify, Ctx))
     return true;
 
+  if (hasMCSaveTempLabels())
+    Ctx->setAllowTemporaryLabels(false);
+
   // Create the code emitter for the target if it exists.  If not, .o file
   // emission fails.
   MCCodeEmitter *MCE = getTarget().createCodeEmitter(*this, *Ctx);
Modified: lib/CodeGen/LiveIntervalAnalysis.cpp
===================================================================
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -1715,7 +1715,9 @@ LiveIntervals::getSpillWeight(bool isDef, bool isUse, unsigned \
loopDepth) {  // overflow a float. This expression behaves like 10^d for small d, but \
is  // more tempered for large d. At d=200 we get 6.7e33 which leaves a bit of
   // headroom before overflow.
-  float lc = std::pow(1 + (100.0f / (loopDepth+10)), (float)loopDepth);
+  // By the way, powf() might be unavailable here. For consistency,
+  // We may take pow(double,double).
+  float lc = std::pow(1 + (100.0 / (loopDepth + 10)), (double)loopDepth);
 
   return (isDef + isUse) * lc;
 }
Modified: lib/CodeGen/LiveIntervalUnion.h
===================================================================
--- a/lib/CodeGen/LiveIntervalUnion.h
+++ b/lib/CodeGen/LiveIntervalUnion.h
@@ -166,7 +166,7 @@ public:
     unsigned Tag, UserTag;
 
   public:
-    Query(): LiveUnion(), VirtReg() {}
+    Query(): LiveUnion(), VirtReg(), Tag(0), UserTag(0) {}
 
     Query(LiveInterval *VReg, LiveIntervalUnion *LIU):
       LiveUnion(LIU), VirtReg(VReg), CheckedFirstInterference(false),
Modified: lib/CodeGen/LiveRangeEdit.cpp
===================================================================
--- a/lib/CodeGen/LiveRangeEdit.cpp
+++ b/lib/CodeGen/LiveRangeEdit.cpp
@@ -11,9 +11,11 @@
 // is spilled or split.
 //===----------------------------------------------------------------------===//
 
+#define DEBUG_TYPE "regalloc"
 #include "LiveRangeEdit.h"
 #include "VirtRegMap.h"
 #include "llvm/ADT/SetVector.h"
+#include "llvm/CodeGen/CalcSpillWeights.h"
 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
@@ -34,6 +36,16 @@ LiveInterval &LiveRangeEdit::createFrom(unsigned OldReg,
   return LI;
 }
 
+void LiveRangeEdit::checkRematerializable(VNInfo *VNI,
+                                          const MachineInstr *DefMI,
+                                          const TargetInstrInfo &tii,
+                                          AliasAnalysis *aa) {
+  assert(DefMI && "Missing instruction");
+  if (tii.isTriviallyReMaterializable(DefMI, aa))
+    remattable_.insert(VNI);
+  scannedRemattable_ = true;
+}
+
 void LiveRangeEdit::scanRemattable(LiveIntervals &lis,
                                    const TargetInstrInfo &tii,
                                    AliasAnalysis *aa) {
@@ -45,10 +57,8 @@ void LiveRangeEdit::scanRemattable(LiveIntervals &lis,
     MachineInstr *DefMI = lis.getInstructionFromIndex(VNI->def);
     if (!DefMI)
       continue;
-    if (tii.isTriviallyReMaterializable(DefMI, aa))
-      remattable_.insert(VNI);
+    checkRematerializable(VNI, DefMI, tii, aa);
   }
-  scannedRemattable_ = true;
 }
 
 bool LiveRangeEdit::anyRematerializable(LiveIntervals &lis,
@@ -69,14 +79,11 @@ bool LiveRangeEdit::allUsesAvailableAt(const MachineInstr \
*OrigMI,  UseIdx = UseIdx.getUseIndex();
   for (unsigned i = 0, e = OrigMI->getNumOperands(); i != e; ++i) {
     const MachineOperand &MO = OrigMI->getOperand(i);
-    if (!MO.isReg() || !MO.getReg() || MO.getReg() == getReg())
+    if (!MO.isReg() || !MO.getReg() || MO.isDef())
       continue;
     // Reserved registers are OK.
     if (MO.isUndef() || !lis.hasInterval(MO.getReg()))
       continue;
-    // We don't want to move any defs.
-    if (MO.isDef())
-      return false;
     // We cannot depend on virtual registers in uselessRegs_.
     if (uselessRegs_)
       for (unsigned ui = 0, ue = uselessRegs_->size(); ui != ue; ++ui)
@@ -103,16 +110,22 @@ bool LiveRangeEdit::canRematerializeAt(Remat &RM,
   if (!remattable_.count(RM.ParentVNI))
     return false;
 
-  // No defining instruction.
-  RM.OrigMI = lis.getInstructionFromIndex(RM.ParentVNI->def);
-  assert(RM.OrigMI && "Defining instruction for remattable value disappeared");
+  // No defining instruction provided.
+  SlotIndex DefIdx;
+  if (RM.OrigMI)
+    DefIdx = lis.getInstructionIndex(RM.OrigMI);
+  else {
+    DefIdx = RM.ParentVNI->def;
+    RM.OrigMI = lis.getInstructionFromIndex(DefIdx);
+    assert(RM.OrigMI && "No defining instruction for remattable value");
+  }
 
   // If only cheap remats were requested, bail out early.
   if (cheapAsAMove && !RM.OrigMI->getDesc().isAsCheapAsAMove())
     return false;
 
   // Verify that all used registers are available with the same values.
-  if (!allUsesAvailableAt(RM.OrigMI, RM.ParentVNI->def, UseIdx, lis))
+  if (!allUsesAvailableAt(RM.OrigMI, DefIdx, UseIdx, lis))
     return false;
 
   return true;
@@ -218,9 +231,22 @@ void \
LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,  continue;
     DEBUG(dbgs() << NumComp << " components: " << *LI << '\n');
     SmallVector<LiveInterval*, 8> Dups(1, LI);
-    for (unsigned i = 1; i != NumComp; ++i)
+    for (unsigned i = 1; i != NumComp; ++i) {
       Dups.push_back(&createFrom(LI->reg, LIS, VRM));
+      if (delegate_)
+        delegate_->LRE_DidCloneVirtReg(Dups.back()->reg, LI->reg);
+    }
     ConEQ.Distribute(&Dups[0], VRM.getRegInfo());
   }
 }
 
+void LiveRangeEdit::calculateRegClassAndHint(MachineFunction &MF,
+                                             LiveIntervals &LIS,
+                                             const MachineLoopInfo &Loops) {
+  VirtRegAuxInfo VRAI(MF, LIS, Loops);
+  for (iterator I = begin(), E = end(); I != E; ++I) {
+    LiveInterval &LI = **I;
+    VRAI.CalculateRegClass(LI.reg);
+    VRAI.CalculateWeightAndHint(LI);
+  }
+}
Modified: lib/CodeGen/LiveRangeEdit.h
===================================================================
--- a/lib/CodeGen/LiveRangeEdit.h
+++ b/lib/CodeGen/LiveRangeEdit.h
@@ -25,6 +25,7 @@ namespace llvm {
 
 class AliasAnalysis;
 class LiveIntervals;
+class MachineLoopInfo;
 class MachineRegisterInfo;
 class VirtRegMap;
 
@@ -42,6 +43,10 @@ public:
     /// Called before shrinking the live range of a virtual register.
     virtual void LRE_WillShrinkVirtReg(unsigned) {}
 
+    /// Called after cloning a virtual register.
+    /// This is used for new registers representing connected components of Old.
+    virtual void LRE_DidCloneVirtReg(unsigned New, unsigned Old) {}
+
     virtual ~Delegate() {}
   };
 
@@ -65,9 +70,6 @@ private:
   /// live range trimmed or entirely removed.
   SmallPtrSet<const VNInfo*,4> rematted_;
 
-  /// createFrom - Create a new virtual register based on OldReg.
-  LiveInterval &createFrom(unsigned, LiveIntervals&, VirtRegMap &);
-
   /// scanRemattable - Identify the parent_ values that may rematerialize.
   void scanRemattable(LiveIntervals &lis,
                       const TargetInstrInfo &tii,
@@ -113,6 +115,9 @@ public:
     return uselessRegs_;
   }
 
+  /// createFrom - Create a new virtual register based on OldReg.
+  LiveInterval &createFrom(unsigned OldReg, LiveIntervals&, VirtRegMap&);
+
   /// create - Create a new register with the same class and original slot as
   /// parent.
   LiveInterval &create(LiveIntervals &LIS, VirtRegMap &VRM) {
@@ -125,6 +130,11 @@ public:
   bool anyRematerializable(LiveIntervals&, const TargetInstrInfo&,
                            AliasAnalysis*);
 
+  /// checkRematerializable - Manually add VNI to the list of rematerializable
+  /// values if DefMI may be rematerializable.
+  void checkRematerializable(VNInfo *VNI, const MachineInstr *DefMI,
+                             const TargetInstrInfo&, AliasAnalysis*);
+
   /// Remat - Information needed to rematerialize at a specific location.
   struct Remat {
     VNInfo *ParentVNI;      // parent_'s value at the remat location.
@@ -174,6 +184,10 @@ public:
                          LiveIntervals&, VirtRegMap&,
                          const TargetInstrInfo&);
 
+  /// calculateRegClassAndHint - Recompute register class and hint for each new
+  /// register.
+  void calculateRegClassAndHint(MachineFunction&, LiveIntervals&,
+                                const MachineLoopInfo&);
 };
 
 }
Modified: lib/CodeGen/RegAllocGreedy.cpp
===================================================================
--- a/lib/CodeGen/RegAllocGreedy.cpp
+++ b/lib/CodeGen/RegAllocGreedy.cpp
@@ -49,7 +49,6 @@ using namespace llvm;
 
 STATISTIC(NumGlobalSplits, "Number of split global live ranges");
 STATISTIC(NumLocalSplits,  "Number of split local live ranges");
-STATISTIC(NumReassigned,   "Number of interferences reassigned");
 STATISTIC(NumEvicted,      "Number of interferences evicted");
 
 static RegisterRegAlloc greedyRegAlloc("greedy", "greedy register allocator",
@@ -91,7 +90,8 @@ class RAGreedy : public MachineFunctionPass,
   // range splitting algorithm terminates, something that is otherwise hard to
   // ensure.
   enum LiveRangeStage {
-    RS_Original, ///< Never seen before, never split.
+    RS_New,      ///< Never seen before.
+    RS_First,    ///< First time in the queue.
     RS_Second,   ///< Second time in the queue.
     RS_Region,   ///< Produced by region splitting.
     RS_Block,    ///< Produced by per-block splitting.
@@ -108,8 +108,11 @@ class RAGreedy : public MachineFunctionPass,
   template<typename Iterator>
   void setStage(Iterator Begin, Iterator End, LiveRangeStage NewStage) {
     LRStage.resize(MRI->getNumVirtRegs());
-    for (;Begin != End; ++Begin)
-      LRStage[(*Begin)->reg] = NewStage;
+    for (;Begin != End; ++Begin) {
+      unsigned Reg = (*Begin)->reg;
+      if (LRStage[Reg] == RS_New)
+        LRStage[Reg] = NewStage;
+    }
   }
 
   // splitting state.
@@ -163,10 +166,7 @@ private:
   void LRE_WillEraseInstruction(MachineInstr*);
   bool LRE_CanEraseVirtReg(unsigned);
   void LRE_WillShrinkVirtReg(unsigned);
-
-  bool checkUncachedInterference(LiveInterval&, unsigned);
-  LiveInterval *getSingleInterference(LiveInterval&, unsigned);
-  bool reassignVReg(LiveInterval &InterferingVReg, unsigned OldPhysReg);
+  void LRE_DidCloneVirtReg(unsigned, unsigned);
 
   void mapGlobalInterference(unsigned, SmallVectorImpl<IndexPair>&);
   float calcSplitConstraints(const SmallVectorImpl<IndexPair>&);
@@ -180,8 +180,6 @@ private:
   unsigned nextSplitPoint(unsigned);
   bool canEvictInterference(LiveInterval&, unsigned, float&);
 
-  unsigned tryReassign(LiveInterval&, AllocationOrder&,
-                              SmallVectorImpl<LiveInterval*>&);
   unsigned tryEvict(LiveInterval&, AllocationOrder&,
                     SmallVectorImpl<LiveInterval*>&);
   unsigned tryRegionSplit(LiveInterval&, AllocationOrder&,
@@ -199,7 +197,7 @@ FunctionPass* llvm::createGreedyRegisterAllocator() {
   return new RAGreedy();
 }
 
-RAGreedy::RAGreedy(): MachineFunctionPass(ID), LRStage(RS_Original) {
+RAGreedy::RAGreedy(): MachineFunctionPass(ID), LRStage(RS_New) {
   initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
   initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
   initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
@@ -272,6 +270,14 @@ void RAGreedy::LRE_WillShrinkVirtReg(unsigned VirtReg) {
   enqueue(&LI);
 }
 
+void RAGreedy::LRE_DidCloneVirtReg(unsigned New, unsigned Old) {
+  // LRE may clone a virtual register because dead code elimination causes it to
+  // be split into connected components. Ensure that the new register gets the
+  // same stage as the parent.
+  LRStage.grow(New);
+  LRStage[New] = LRStage[Old];
+}
+
 void RAGreedy::releaseMemory() {
   SpillerInstance.reset(0);
   LRStage.clear();
@@ -288,17 +294,23 @@ void RAGreedy::enqueue(LiveInterval *LI) {
   unsigned Prio;
 
   LRStage.grow(Reg);
-  if (LRStage[Reg] == RS_Original)
-    // 1st generation ranges are handled first, long -> short.
+  if (LRStage[Reg] == RS_New)
+    LRStage[Reg] = RS_First;
+
+  if (LRStage[Reg] == RS_Second)
+    // Unsplit ranges that couldn't be allocated immediately are deferred until
+    // everything else has been allocated. Long ranges are allocated last so
+    // they are split against realistic interference.
+    Prio = (1u << 31) - Size;
+  else {
+    // Everything else is allocated in long->short order. Long ranges that don't
+    // fit should be spilled ASAP so they don't create interference.
     Prio = (1u << 31) + Size;
-  else
-    // Repeat offenders are handled second, short -> long
-    Prio = (1u << 30) - Size;
 
-  // Boost ranges that have a physical register hint.
-  const unsigned Hint = VRM->getRegAllocPref(Reg);
-  if (TargetRegisterInfo::isPhysicalRegister(Hint))
-    Prio |= (1u << 30);
+    // Boost ranges that have a physical register hint.
+    if (TargetRegisterInfo::isPhysicalRegister(VRM->getRegAllocPref(Reg)))
+      Prio |= (1u << 30);
+  }
 
   Queue.push(std::make_pair(Prio, Reg));
 }
@@ -312,100 +324,6 @@ LiveInterval *RAGreedy::dequeue() {
 }
 
 //===----------------------------------------------------------------------===//
-//                         Register Reassignment
-//===----------------------------------------------------------------------===//
-
-// Check interference without using the cache.
-bool RAGreedy::checkUncachedInterference(LiveInterval &VirtReg,
-                                         unsigned PhysReg) {
-  for (const unsigned *AliasI = TRI->getOverlaps(PhysReg); *AliasI; ++AliasI) {
-    LiveIntervalUnion::Query subQ(&VirtReg, &PhysReg2LiveUnion[*AliasI]);
-    if (subQ.checkInterference())
-      return true;
-  }
-  return false;
-}
-
-/// getSingleInterference - Return the single interfering virtual register
-/// assigned to PhysReg. Return 0 if more than one virtual register is
-/// interfering.
-LiveInterval *RAGreedy::getSingleInterference(LiveInterval &VirtReg,
-                                              unsigned PhysReg) {
-  // Check physreg and aliases.
-  LiveInterval *Interference = 0;
-  for (const unsigned *AliasI = TRI->getOverlaps(PhysReg); *AliasI; ++AliasI) {
-    LiveIntervalUnion::Query &Q = query(VirtReg, *AliasI);
-    if (Q.checkInterference()) {
-      if (Interference)
-        return 0;
-      if (Q.collectInterferingVRegs(2) > 1)
-        return 0;
-      Interference = Q.interferingVRegs().front();
-    }
-  }
-  return Interference;
-}
-
-// Attempt to reassign this virtual register to a different physical register.
-//
-// FIXME: we are not yet caching these "second-level" interferences discovered
-// in the sub-queries. These interferences can change with each call to
-// selectOrSplit. However, we could implement a "may-interfere" cache that
-// could be conservatively dirtied when we reassign or split.
-//
-// FIXME: This may result in a lot of alias queries. We could summarize alias
-// live intervals in their parent register's live union, but it's messy.
-bool RAGreedy::reassignVReg(LiveInterval &InterferingVReg,
-                            unsigned WantedPhysReg) {
-  assert(TargetRegisterInfo::isVirtualRegister(InterferingVReg.reg) &&
-         "Can only reassign virtual registers");
-  assert(TRI->regsOverlap(WantedPhysReg, VRM->getPhys(InterferingVReg.reg)) &&
-         "inconsistent phys reg assigment");
-
-  AllocationOrder Order(InterferingVReg.reg, *VRM, ReservedRegs);
-  while (unsigned PhysReg = Order.next()) {
-    // Don't reassign to a WantedPhysReg alias.
-    if (TRI->regsOverlap(PhysReg, WantedPhysReg))
-      continue;
-
-    if (checkUncachedInterference(InterferingVReg, PhysReg))
-      continue;
-
-    // Reassign the interfering virtual reg to this physical reg.
-    unsigned OldAssign = VRM->getPhys(InterferingVReg.reg);
-    DEBUG(dbgs() << "reassigning: " << InterferingVReg << " from " <<
-          TRI->getName(OldAssign) << " to " << TRI->getName(PhysReg) << '\n');
-    unassign(InterferingVReg, OldAssign);
-    assign(InterferingVReg, PhysReg);
-    ++NumReassigned;
-    return true;
-  }
-  return false;
-}
-
-/// tryReassign - Try to reassign a single interference to a different physreg.
-/// @param  VirtReg Currently unassigned virtual register.
-/// @param  Order   Physregs to try.
-/// @return         Physreg to assign VirtReg, or 0.
-unsigned RAGreedy::tryReassign(LiveInterval &VirtReg, AllocationOrder &Order,
-                               SmallVectorImpl<LiveInterval*> &NewVRegs){
-  NamedRegionTimer T("Reassign", TimerGroupName, TimePassesIsEnabled);
-
-  Order.rewind();
-  while (unsigned PhysReg = Order.next()) {
-    LiveInterval *InterferingVReg = getSingleInterference(VirtReg, PhysReg);
-    if (!InterferingVReg)
-      continue;
-    if (TargetRegisterInfo::isPhysicalRegister(InterferingVReg->reg))
-      continue;
-    if (reassignVReg(*InterferingVReg, PhysReg))
-      return PhysReg;
-  }
-  return 0;
-}
-
-
-//===----------------------------------------------------------------------===//
 //                         Interference eviction
 //===----------------------------------------------------------------------===//
 
@@ -851,22 +769,8 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned \
PhysReg,  SE->finish();
   ++NumGlobalSplits;
 
-  if (VerifyEnabled) {
+  if (VerifyEnabled)
     MF->verify(this, "After splitting live range around region");
-
-#ifndef NDEBUG
-    // Make sure that at least one of the new intervals can allocate to PhysReg.
-    // That was the whole point of splitting the live range.
-    bool found = false;
-    for (LiveRangeEdit::iterator I = LREdit.begin(), E = LREdit.end(); I != E;
-         ++I)
-      if (!checkUncachedInterference(**I, PhysReg)) {
-        found = true;
-        break;
-      }
-    assert(found && "No allocatable intervals after pointless splitting");
-#endif
-  }
 }
 
 unsigned RAGreedy::tryRegionSplit(LiveInterval &VirtReg, AllocationOrder &Order,
@@ -1242,10 +1146,6 @@ unsigned RAGreedy::trySplit(LiveInterval &VirtReg, \
AllocationOrder &Order,  
 unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg,
                                  SmallVectorImpl<LiveInterval*> &NewVRegs) {
-  LiveRangeStage Stage = getStage(VirtReg);
-  if (Stage == RS_Original)
-    LRStage[VirtReg.reg] = RS_Second;
-
   // First try assigning a free register.
   AllocationOrder Order(VirtReg.reg, *VRM, ReservedRegs);
   while (unsigned PhysReg = Order.next()) {
@@ -1253,9 +1153,6 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg,
       return PhysReg;
   }
 
-  if (unsigned PhysReg = tryReassign(VirtReg, Order, NewVRegs))
-    return PhysReg;
-
   if (unsigned PhysReg = tryEvict(VirtReg, Order, NewVRegs))
     return PhysReg;
 
@@ -1264,7 +1161,9 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg,
   // The first time we see a live range, don't try to split or spill.
   // Wait until the second time, when all smaller ranges have been allocated.
   // This gives a better picture of the interference to split around.
-  if (Stage == RS_Original) {
+  LiveRangeStage Stage = getStage(VirtReg);
+  if (Stage == RS_First) {
+    LRStage[VirtReg.reg] = RS_Second;
     DEBUG(dbgs() << "wait for second round\n");
     NewVRegs.push_back(&VirtReg);
     return 0;
@@ -1281,6 +1180,7 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg,
   NamedRegionTimer T("Spiller", TimerGroupName, TimePassesIsEnabled);
   LiveRangeEdit LRE(VirtReg, NewVRegs, this);
   spiller().spill(LRE);
+  setStage(NewVRegs.begin(), NewVRegs.end(), RS_Spill);
 
   if (VerifyEnabled)
     MF->verify(this, "After spilling");
Modified: lib/CodeGen/RegAllocLinearScan.cpp
===================================================================
--- a/lib/CodeGen/RegAllocLinearScan.cpp
+++ b/lib/CodeGen/RegAllocLinearScan.cpp
@@ -375,7 +375,7 @@ namespace {
             dbgs() << str << " intervals:\n";
 
           for (; i != e; ++i) {
-            dbgs() << "\t" << *i->first << " -> ";
+            dbgs() << '\t' << *i->first << " -> ";
 
             unsigned reg = i->first->reg;
             if (TargetRegisterInfo::isVirtualRegister(reg))
@@ -390,7 +390,7 @@ namespace {
 }
 
 INITIALIZE_PASS_BEGIN(RALinScan, "linearscan-regalloc",
-                "Linear Scan Register Allocator", false, false)
+                      "Linear Scan Register Allocator", false, false)
 INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
 INITIALIZE_PASS_DEPENDENCY(StrongPHIElimination)
 INITIALIZE_PASS_DEPENDENCY(CalculateSpillWeights)
@@ -401,7 +401,7 @@ INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
 INITIALIZE_AG_DEPENDENCY(RegisterCoalescer)
 INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
 INITIALIZE_PASS_END(RALinScan, "linearscan-regalloc",
-                "Linear Scan Register Allocator", false, false)
+                    "Linear Scan Register Allocator", false, false)
 
 void RALinScan::ComputeRelatedRegClasses() {
   // First pass, add all reg classes to the union, and determine at least one
@@ -1110,6 +1110,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* \
cur) {  // list.
   if (physReg) {
     DEBUG(dbgs() <<  tri_->getName(physReg) << '\n');
+    assert(RC->contains(physReg) && "Invalid candidate");
     vrm_->assignVirt2Phys(cur->reg, physReg);
     addRegUse(physReg);
     active_.push_back(std::make_pair(cur, cur->begin()));
Modified: lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
===================================================================
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -1500,6 +1500,8 @@ public:
   unsigned getNodePriority(const SUnit *SU) const;
 
   unsigned getNodeOrdering(const SUnit *SU) const {
+    if (!SU->getNode()) return 0;
+
     return scheduleDAG->DAG->GetOrdering(SU->getNode());
   }
 
Modified: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===================================================================
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -50,7 +50,6 @@
 #include "llvm/Target/TargetIntrinsicInfo.h"
 #include "llvm/Target/TargetLowering.h"
 #include "llvm/Target/TargetOptions.h"
-#include "llvm/Support/Compiler.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -5343,12 +5342,11 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
   LowerCallTo(&I, Callee, I.isTailCall());
 }
 
-namespace llvm {
+namespace {
 
 /// AsmOperandInfo - This contains information for each constraint that we are
 /// lowering.
-class LLVM_LIBRARY_VISIBILITY SDISelAsmOperandInfo :
-    public TargetLowering::AsmOperandInfo {
+class SDISelAsmOperandInfo : public TargetLowering::AsmOperandInfo {
 public:
   /// CallOperand - If this is the result output operand or a clobber
   /// this is null, otherwise it is the incoming operand to the CallInst.
@@ -5436,7 +5434,7 @@ private:
 
 typedef SmallVector<SDISelAsmOperandInfo,16> SDISelAsmOperandInfoVector;
 
-} // end llvm namespace.
+} // end anonymous namespace
 
 /// isAllocatableRegister - If the specified register is safe to allocate,
 /// i.e. it isn't a stack pointer or some other special register, return the
@@ -5495,11 +5493,13 @@ isAllocatableRegister(unsigned Reg, MachineFunction &MF,
 ///   OpInfo describes the operand.
 ///   Input and OutputRegs are the set of already allocated physical registers.
 ///
-void SelectionDAGBuilder::
-GetRegistersForValue(SDISelAsmOperandInfo &OpInfo,
-                     std::set<unsigned> &OutputRegs,
-                     std::set<unsigned> &InputRegs) {
-  LLVMContext &Context = FuncInfo.Fn->getContext();
+static void GetRegistersForValue(SelectionDAG &DAG,
+                                 const TargetLowering &TLI,
+                                 DebugLoc DL,
+                                 SDISelAsmOperandInfo &OpInfo,
+                                 std::set<unsigned> &OutputRegs,
+                                 std::set<unsigned> &InputRegs) {
+  LLVMContext &Context = *DAG.getContext();
 
   // Compute whether this value requires an input register, an output register,
   // or both.
@@ -5545,7 +5545,7 @@ GetRegistersForValue(SDISelAsmOperandInfo &OpInfo,
       // vector types).
       EVT RegVT = *PhysReg.second->vt_begin();
       if (RegVT.getSizeInBits() == OpInfo.ConstraintVT.getSizeInBits()) {
-        OpInfo.CallOperand = DAG.getNode(ISD::BITCAST, getCurDebugLoc(),
+        OpInfo.CallOperand = DAG.getNode(ISD::BITCAST, DL,
                                          RegVT, OpInfo.CallOperand);
         OpInfo.ConstraintVT = RegVT;
       } else if (RegVT.isInteger() && OpInfo.ConstraintVT.isFloatingPoint()) {
@@ -5555,7 +5555,7 @@ GetRegistersForValue(SDISelAsmOperandInfo &OpInfo,
         // machine.
         RegVT = EVT::getIntegerVT(Context,
                                   OpInfo.ConstraintVT.getSizeInBits());
-        OpInfo.CallOperand = DAG.getNode(ISD::BITCAST, getCurDebugLoc(),
+        OpInfo.CallOperand = DAG.getNode(ISD::BITCAST, DL,
                                          RegVT, OpInfo.CallOperand);
         OpInfo.ConstraintVT = RegVT;
       }
@@ -5826,7 +5826,8 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) \
{  // If this constraint is for a specific register, allocate it before
     // anything else.
     if (OpInfo.ConstraintType == TargetLowering::C_Register)
-      GetRegistersForValue(OpInfo, OutputRegs, InputRegs);
+      GetRegistersForValue(DAG, TLI, getCurDebugLoc(), OpInfo, OutputRegs,
+                           InputRegs);
   }
 
   // Second pass - Loop over all of the operands, assigning virtual or physregs
@@ -5837,7 +5838,8 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) \
                {
     // C_Register operands have already been allocated, Other/Memory don't need
     // to be.
     if (OpInfo.ConstraintType == TargetLowering::C_RegisterClass)
-      GetRegistersForValue(OpInfo, OutputRegs, InputRegs);
+      GetRegistersForValue(DAG, TLI, getCurDebugLoc(), OpInfo, OutputRegs,
+                           InputRegs);
   }
 
   // AsmNodeOperands - The operands for the ISD::INLINEASM node.
Modified: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
===================================================================
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -60,7 +60,6 @@ class MDNode;
 class PHINode;
 class PtrToIntInst;
 class ReturnInst;
-class SDISelAsmOperandInfo;
 class SDDbgValue;
 class SExtInst;
 class SelectInst;
@@ -380,10 +379,6 @@ public:
     assert(N.getNode() == 0 && "Already set a value for this node!");
     N = NewN;
   }
-  
-  void GetRegistersForValue(SDISelAsmOperandInfo &OpInfo,
-                            std::set<unsigned> &OutputRegs, 
-                            std::set<unsigned> &InputRegs);
 
   void FindMergedConditions(const Value *Cond, MachineBasicBlock *TBB,
                             MachineBasicBlock *FBB, MachineBasicBlock *CurBB,
Modified: lib/CodeGen/SplitKit.cpp
===================================================================
--- a/lib/CodeGen/SplitKit.cpp
+++ b/lib/CodeGen/SplitKit.cpp
@@ -17,7 +17,6 @@
 #include "LiveRangeEdit.h"
 #include "VirtRegMap.h"
 #include "llvm/ADT/Statistic.h"
-#include "llvm/CodeGen/CalcSpillWeights.h"
 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
 #include "llvm/CodeGen/MachineDominators.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -95,9 +94,10 @@ void SplitAnalysis::analyzeUses() {
     assert(fixed && "Couldn't fix broken live interval");
   }
 
-  DEBUG(dbgs() << "  counted "
+  DEBUG(dbgs() << "Analyze counted "
                << UsingInstrs.size() << " instrs, "
-               << UsingBlocks.size() << " blocks.\n");
+               << UsingBlocks.size() << " blocks, "
+               << LiveBlocks.size() << " spanned.\n");
 }
 
 /// calcLiveBlockInfo - Fill the LiveBlocks array with information about blocks
@@ -880,14 +880,7 @@ void SplitEditor::finish() {
   }
 
   // Calculate spill weight and allocation hints for new intervals.
-  VirtRegAuxInfo vrai(VRM.getMachineFunction(), LIS, SA.Loops);
-  for (LiveRangeEdit::iterator I = Edit->begin(), E = Edit->end(); I != E; ++I){
-    LiveInterval &li = **I;
-    vrai.CalculateRegClass(li.reg);
-    vrai.CalculateWeightAndHint(li);
-    DEBUG(dbgs() << "  new interval " << MRI.getRegClass(li.reg)->getName()
-                 << ":" << li << '\n');
-  }
+  Edit->calculateRegClassAndHint(VRM.getMachineFunction(), LIS, SA.Loops);
 }
 
 
@@ -927,7 +920,8 @@ void SplitEditor::splitSingleBlocks(const \
SplitAnalysis::BlockPtrSet &Blocks) {  continue;
 
     openIntv();
-    SlotIndex SegStart = enterIntvBefore(BI.FirstUse);
+    SlotIndex SegStart = enterIntvBefore(std::min(BI.FirstUse,
+                                                  BI.LastSplitPoint));
     if (!BI.LiveOut || BI.LastUse < BI.LastSplitPoint) {
       useIntv(SegStart, leaveIntvAfter(BI.LastUse));
     } else {
Modified: lib/CodeGen/StackProtector.cpp
===================================================================
--- a/lib/CodeGen/StackProtector.cpp
+++ b/lib/CodeGen/StackProtector.cpp
@@ -153,7 +153,6 @@ bool StackProtector::InsertStackProtectors() {
 
   for (Function::iterator I = F->begin(), E = F->end(); I != E; ) {
     BasicBlock *BB = I++;
-
     ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator());
     if (!RI) continue;
 
@@ -191,8 +190,6 @@ bool StackProtector::InsertStackProtectors() {
 
       // Create the basic block to jump to when the guard check fails.
       FailBB = CreateFailBB();
-      if (DT)
-        FailBBDom = DT->isReachableFromEntry(BB) ? BB : 0;
     }
 
     // For each block with a return instruction, convert this:
@@ -219,9 +216,10 @@ bool StackProtector::InsertStackProtectors() {
 
     // Split the basic block before the return instruction.
     BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return");
+
     if (DT && DT->isReachableFromEntry(BB)) {
       DT->addNewBlock(NewBB, BB);
-      FailBBDom = DT->findNearestCommonDominator(FailBBDom, BB);
+      FailBBDom = FailBBDom ? DT->findNearestCommonDominator(FailBBDom, BB) :BB;
     }
 
     // Remove default branch instruction to the new BB.
Modified: lib/CodeGen/VirtRegRewriter.cpp
===================================================================
--- a/lib/CodeGen/VirtRegRewriter.cpp
+++ b/lib/CodeGen/VirtRegRewriter.cpp
@@ -261,6 +261,10 @@ public:
   /// now).
   void ModifyStackSlotOrReMat(int SlotOrReMat);
 
+  /// ClobberSharingStackSlots - When a register mapped to a stack slot changes,
+  /// other stack slots sharing the same register are no longer valid.
+  void ClobberSharingStackSlots(int StackSlot);
+
   /// AddAvailableRegsToLiveIn - Availability information is being kept coming
   /// into the specified MBB. Add available physical registers as potential
   /// live-in's. If they are reused in the MBB, they will be added to the
@@ -831,6 +835,26 @@ void AvailableSpills::ModifyStackSlotOrReMat(int SlotOrReMat) {
   PhysRegsAvailable.erase(I);
 }
 
+void AvailableSpills::ClobberSharingStackSlots(int StackSlot) {
+  std::map<int, unsigned>::iterator It =
+    SpillSlotsOrReMatsAvailable.find(StackSlot);
+  if (It == SpillSlotsOrReMatsAvailable.end()) return;
+  unsigned Reg = It->second >> 1;
+
+  // Erase entries in PhysRegsAvailable for other stack slots.
+  std::multimap<unsigned, int>::iterator I = PhysRegsAvailable.lower_bound(Reg);
+  while (I != PhysRegsAvailable.end() && I->first == Reg) {
+    std::multimap<unsigned, int>::iterator NextI = llvm::next(I);
+    if (I->second != StackSlot) {
+      DEBUG(dbgs() << "Clobbered sharing SS#" << I->second << " in "
+                   << PrintReg(Reg, TRI) << '\n');
+      SpillSlotsOrReMatsAvailable.erase(I->second);
+      PhysRegsAvailable.erase(I);
+    }
+    I = NextI;
+  }
+}
+
 // ************************** //
 // Reuse Info Implementation  //
 // ************************** //
@@ -1791,8 +1815,8 @@ bool LocalRewriter::InsertRestores(MachineInstr *MI,
       else
         DEBUG(dbgs() << "Reusing SS#" << SSorRMId);
       DEBUG(dbgs() << " from physreg "
-                   << TRI->getName(InReg) << " for vreg"
-                   << VirtReg <<" instead of reloading into physreg "
+                   << TRI->getName(InReg) << " for " << PrintReg(VirtReg)
+                   <<" instead of reloading into physreg "
                    << TRI->getName(Phys) << '\n');
 
       // Reusing a physreg may resurrect it. But we expect ProcessUses to update
@@ -1807,8 +1831,8 @@ bool LocalRewriter::InsertRestores(MachineInstr *MI,
       else
         DEBUG(dbgs() << "Reusing SS#" << SSorRMId);
       DEBUG(dbgs() << " from physreg "
-                   << TRI->getName(InReg) << " for vreg"
-                   << VirtReg <<" by copying it into physreg "
+                   << TRI->getName(InReg) << " for " << PrintReg(VirtReg)
+                   <<" by copying it into physreg "
                    << TRI->getName(Phys) << '\n');
 
       // If the reloaded / remat value is available in another register,
@@ -2025,7 +2049,8 @@ void LocalRewriter::ProcessUses(MachineInstr &MI, \
AvailableSpills &Spills,  TRI->regsOverlap(MOk.getReg(), PhysReg)) {
             CanReuse = false;
             DEBUG(dbgs() << "Not reusing physreg " << TRI->getName(PhysReg)
-                         << " for vreg" << VirtReg << ": " << MOk << '\n');
+                         << " for " << PrintReg(VirtReg) << ": " << MOk
+                         << '\n');
             break;
           }
         }
@@ -2039,9 +2064,9 @@ void LocalRewriter::ProcessUses(MachineInstr &MI, \
AvailableSpills &Spills,  else
           DEBUG(dbgs() << "Reusing SS#" << ReuseSlot);
         DEBUG(dbgs() << " from physreg "
-              << TRI->getName(PhysReg) << " for vreg"
-              << VirtReg <<" instead of reloading into physreg "
-              << TRI->getName(VRM->getPhys(VirtReg)) << '\n');
+              << TRI->getName(PhysReg) << " for " << PrintReg(VirtReg)
+              << " instead of reloading into "
+              << PrintReg(VRM->getPhys(VirtReg), TRI) << '\n');
         unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
         MI.getOperand(i).setReg(RReg);
         MI.getOperand(i).setSubReg(0);
@@ -2126,7 +2151,7 @@ void LocalRewriter::ProcessUses(MachineInstr &MI, \
AvailableSpills &Spills,  else
           DEBUG(dbgs() << "Reusing SS#" << ReuseSlot);
         DEBUG(dbgs() << " from physreg " << TRI->getName(PhysReg)
-              << " for vreg" << VirtReg
+              << " for " << PrintReg(VirtReg)
               << " instead of reloading into same physreg.\n");
         unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
         MI.getOperand(i).setReg(RReg);
@@ -2315,7 +2340,7 @@ LocalRewriter::RewriteMBB(LiveIntervals *LIs,
     for (unsigned FVI = 0, FVE = FoldedVirts.size(); FVI != FVE; ++FVI) {
       unsigned VirtReg = FoldedVirts[FVI].first;
       VirtRegMap::ModRef MR = FoldedVirts[FVI].second;
-      DEBUG(dbgs() << "Folded vreg: " << VirtReg << "  MR: " << MR);
+      DEBUG(dbgs() << "Folded " << PrintReg(VirtReg) << "  MR: " << MR);
 
       int SS = VRM->getStackSlot(VirtReg);
       if (SS == VirtRegMap::NO_STACK_SLOT)
@@ -2549,6 +2574,10 @@ LocalRewriter::RewriteMBB(LiveIntervals *LIs,
         }
       }
 
+      // If StackSlot is available in a register that also holds other stack
+      // slots, clobber those stack slots now.
+      Spills.ClobberSharingStackSlots(StackSlot);
+
       assert(PhysReg && "VR not assigned a physical register?");
       MRI->setPhysRegUsed(PhysReg);
       unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
Modified: lib/ExecutionEngine/MCJIT/MCJIT.cpp
===================================================================
--- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp
+++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp
@@ -67,7 +67,7 @@ ExecutionEngine *MCJIT::createJIT(Module *M,
 MCJIT::MCJIT(Module *m, TargetMachine *tm, TargetJITInfo &tji,
              JITMemoryManager *JMM, CodeGenOpt::Level OptLevel,
              bool AllocateGVsWithCode)
-  : ExecutionEngine(m), TM(tm), M(m), OS(Buffer) {
+  : ExecutionEngine(m), TM(tm), M(m), OS(Buffer), Dyld(JMM) {
 
   PM.add(new TargetData(*TM->getTargetData()));
 
Modified: lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
===================================================================
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -18,6 +18,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/ExecutionEngine/JITMemoryManager.h"
 #include "llvm/Object/MachOObject.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -34,6 +35,9 @@ class RuntimeDyldImpl {
   unsigned CPUType;
   unsigned CPUSubtype;
 
+  // The JITMemoryManager to load objects into.
+  JITMemoryManager *JMM;
+
   // Master symbol table. As modules are loaded and external symbols are
   // resolved, their addresses are stored here.
   StringMap<void*> SymbolTable;
@@ -68,7 +72,7 @@ class RuntimeDyldImpl {
                      const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC);
 
 public:
-  RuntimeDyldImpl() : HasError(false) {}
+  RuntimeDyldImpl(JITMemoryManager *jmm) : JMM(jmm), HasError(false) {}
 
   bool loadObject(MemoryBuffer *InputBuffer);
 
@@ -526,8 +530,8 @@ bool RuntimeDyldImpl::loadObject(MemoryBuffer *InputBuffer) {
 
 //===----------------------------------------------------------------------===//
 // RuntimeDyld class implementation
-RuntimeDyld::RuntimeDyld() {
-  Dyld = new RuntimeDyldImpl;
+RuntimeDyld::RuntimeDyld(JITMemoryManager *JMM) {
+  Dyld = new RuntimeDyldImpl(JMM);
 }
 
 RuntimeDyld::~RuntimeDyld() {
Modified: lib/Linker/LinkModules.cpp
===================================================================
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -505,6 +505,7 @@ static bool LinkGlobals(Module *Dest, const Module *Src,
                            SGV->getType()->getAddressSpace());
       // Propagate alignment, visibility and section info.
       CopyGVAttributes(NewDGV, SGV);
+      NewDGV->setUnnamedAddr(SGV->hasUnnamedAddr());
 
       // If the LLVM runtime renamed the global, but it is an externally visible
       // symbol, DGV must be an existing global with internal linkage.  Rename
Modified: lib/MC/MCAsmInfo.cpp
===================================================================
--- a/lib/MC/MCAsmInfo.cpp
+++ b/lib/MC/MCAsmInfo.cpp
@@ -26,7 +26,7 @@ MCAsmInfo::MCAsmInfo() {
   LinkerRequiresNonEmptyDwarfLines = false;
   MaxInstLength = 4;
   PCSymbol = "$";
-  SeparatorChar = ';';
+  SeparatorString = ";";
   CommentColumn = 40;
   CommentString = "#";
   LabelSuffix = ":";
Modified: lib/MC/MCAsmStreamer.cpp
===================================================================
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -844,13 +844,13 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
       OS << "0b";
       for (unsigned j = 8; j--;) {
         unsigned Bit = (Code[i] >> j) & 1;
-        
+
         unsigned FixupBit;
         if (getContext().getTargetAsmInfo().isLittleEndian())
           FixupBit = i * 8 + j;
         else
           FixupBit = i * 8 + (7-j);
-        
+
         if (uint8_t MapEntry = FixupMap[FixupBit]) {
           assert(Bit == 0 && "Encoder wrote into fixed up bit!");
           OS << char('A' + MapEntry - 1);
Modified: lib/MC/MCContext.cpp
===================================================================
--- a/lib/MC/MCContext.cpp
+++ b/lib/MC/MCContext.cpp
@@ -28,7 +28,8 @@ typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;
 
 MCContext::MCContext(const MCAsmInfo &mai, const TargetAsmInfo *tai) :
   MAI(mai), TAI(tai), NextUniqueID(0),
-  CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0) {
+  CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0),
+  AllowTemporaryLabels(true) {
   MachOUniquingMap = 0;
   ELFUniquingMap = 0;
   COFFUniquingMap = 0;
@@ -76,8 +77,10 @@ MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) {
 }
 
 MCSymbol *MCContext::CreateSymbol(StringRef Name) {
-  // Determine whether this is an assembler temporary or normal label.
-  bool isTemporary = Name.startswith(MAI.getPrivateGlobalPrefix());
+  // Determine whether this is an assembler temporary or normal label, if used.
+  bool isTemporary = false;
+  if (AllowTemporaryLabels)
+    isTemporary = Name.startswith(MAI.getPrivateGlobalPrefix());
 
   StringMapEntry<bool> *NameEntry = &UsedNames.GetOrCreateValue(Name);
   if (NameEntry->getValue()) {
Modified: lib/MC/MCDisassembler/CMakeLists.txt
===================================================================
--- a/lib/MC/MCDisassembler/CMakeLists.txt
+++ b/lib/MC/MCDisassembler/CMakeLists.txt
@@ -1,7 +1,8 @@
 
 add_llvm_library(LLVMMCDisassembler
+  Disassembler.cpp
   EDDisassembler.cpp
-  EDOperand.cpp
   EDInst.cpp
+  EDOperand.cpp
   EDToken.cpp
   )
Modified: lib/MC/MCDisassembler/EDInfo.h
===================================================================
--- a/lib/MC/MCDisassembler/EDInfo.h
+++ b/lib/MC/MCDisassembler/EDInfo.h
@@ -35,6 +35,7 @@ enum OperandTypes {
   kOperandTypeARMAddrMode5,
   kOperandTypeARMAddrMode6,
   kOperandTypeARMAddrMode6Offset,
+  kOperandTypeARMAddrMode7,
   kOperandTypeARMAddrModePC,
   kOperandTypeARMRegisterList,
   kOperandTypeARMTBAddrMode,
@@ -51,7 +52,8 @@ enum OperandTypes {
   kOperandTypeThumb2AddrModeImm12,
   kOperandTypeThumb2AddrModeSoReg,
   kOperandTypeThumb2AddrModeImm8s4,
-  kOperandTypeThumb2AddrModeImm8s4Offset
+  kOperandTypeThumb2AddrModeImm8s4Offset,
+  kOperandTypeThumb2AddrModeReg
 };
 
 enum OperandFlags {
Modified: lib/MC/MCDisassembler/EDOperand.cpp
===================================================================
--- a/lib/MC/MCDisassembler/EDOperand.cpp
+++ b/lib/MC/MCDisassembler/EDOperand.cpp
@@ -73,6 +73,8 @@ EDOperand::EDOperand(const EDDisassembler &disassembler,
     case kOperandTypeThumb2AddrModeImm8Offset:
     case kOperandTypeARMTBAddrMode:
     case kOperandTypeThumb2AddrModeImm8s4Offset:
+    case kOperandTypeARMAddrMode7:
+    case kOperandTypeThumb2AddrModeReg:
       numMCOperands = 1;
       break;
     case kOperandTypeThumb2SoReg:
@@ -256,6 +258,7 @@ int EDOperand::isMemory() {
   case kOperandTypeARMAddrMode4:
   case kOperandTypeARMAddrMode5:
   case kOperandTypeARMAddrMode6:
+  case kOperandTypeARMAddrMode7:
   case kOperandTypeARMAddrModePC:
   case kOperandTypeARMBranchTarget:
   case kOperandTypeThumbAddrModeS1:
@@ -269,6 +272,7 @@ int EDOperand::isMemory() {
   case kOperandTypeThumb2AddrModeImm12:
   case kOperandTypeThumb2AddrModeSoReg:
   case kOperandTypeThumb2AddrModeImm8s4:
+  case kOperandTypeThumb2AddrModeReg:
     return 1;
   }
 }
Modified: lib/MC/MCParser/AsmLexer.cpp
===================================================================
--- a/lib/MC/MCParser/AsmLexer.cpp
+++ b/lib/MC/MCParser/AsmLexer.cpp
@@ -324,8 +324,8 @@ AsmToken AsmLexer::LexQuote() {
 StringRef AsmLexer::LexUntilEndOfStatement() {
   TokStart = CurPtr;
 
-  while (!isAtStartOfComment(*CurPtr) && // Start of line comment.
-          *CurPtr != ';' &&  // End of statement marker.
+  while (!isAtStartOfComment(*CurPtr) &&    // Start of line comment.
+         !isAtStatementSeparator(CurPtr) && // End of statement marker.
          *CurPtr != '\n' &&
          *CurPtr != '\r' &&
          (*CurPtr != 0 || CurPtr != CurBuf->getBufferEnd())) {
@@ -339,6 +339,11 @@ bool AsmLexer::isAtStartOfComment(char Char) {
   return Char == *MAI.getCommentString();
 }
 
+bool AsmLexer::isAtStatementSeparator(const char *Ptr) {
+  return strncmp(Ptr, MAI.getSeparatorString(),
+                 strlen(MAI.getSeparatorString())) == 0;
+}
+
 AsmToken AsmLexer::LexToken() {
   TokStart = CurPtr;
   // This always consumes at least one character.
@@ -346,6 +351,11 @@ AsmToken AsmLexer::LexToken() {
 
   if (isAtStartOfComment(CurChar))
     return LexLineComment();
+  if (isAtStatementSeparator(TokStart)) {
+    CurPtr += strlen(MAI.getSeparatorString()) - 1;
+    return AsmToken(AsmToken::EndOfStatement,
+                    StringRef(TokStart, strlen(MAI.getSeparatorString())));
+  }
 
   switch (CurChar) {
   default:
@@ -362,8 +372,8 @@ AsmToken AsmLexer::LexToken() {
     // Ignore whitespace.
     return LexToken();
   case '\n': // FALL THROUGH.
-  case '\r': // FALL THROUGH.
-  case ';': return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1));
+  case '\r':
+    return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1));
   case ':': return AsmToken(AsmToken::Colon, StringRef(TokStart, 1));
   case '+': return AsmToken(AsmToken::Plus, StringRef(TokStart, 1));
   case '-': return AsmToken(AsmToken::Minus, StringRef(TokStart, 1));
Modified: lib/MC/MCParser/AsmParser.cpp
===================================================================
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -880,6 +880,7 @@ bool AsmParser::ParseStatement() {
     EatToEndOfStatement();
     return false;
   }
+
   // Allow an integer followed by a ':' as a directional local label.
   if (Lexer.is(AsmToken::Integer)) {
     LocalLabelVal = getTok().getIntVal();
@@ -896,13 +897,19 @@ bool AsmParser::ParseStatement() {
           return TokError("unexpected token at start of statement");
       }
     }
-  }
-  else if (ParseIdentifier(IDVal)) {
+
+  } else if (Lexer.is(AsmToken::Dot)) {
+    // Treat '.' as a valid identifier in this context.
+    Lex();
+    IDVal = ".";
+
+  } else if (ParseIdentifier(IDVal)) {
     if (!TheCondState.Ignore)
       return TokError("unexpected token at start of statement");
     IDVal = "";
   }
 
+
   // Handle conditional assembly here before checking for skipping.  We
   // have to do this so that .endif isn't skipped in a ".if 0" block for
   // example.
@@ -935,6 +942,10 @@ bool AsmParser::ParseStatement() {
     // identifier ':'   -> Label.
     Lex();
 
+    // Diagnose attempt to use '.' as a label.
+    if (IDVal == ".")
+      return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label");
+
     // Diagnose attempt to use a variable as a label.
     //
     // FIXME: Diagnostics. Note the location of the definition as a label.
@@ -978,7 +989,7 @@ bool AsmParser::ParseStatement() {
       return HandleMacroEntry(IDVal, IDLoc, M);
 
   // Otherwise, we have a normal instruction or directive.
-  if (IDVal[0] == '.') {
+  if (IDVal[0] == '.' && IDVal != ".") {
     // Assembler features
     if (IDVal == ".set" || IDVal == ".equ")
       return ParseDirectiveSet(IDVal, true);
@@ -1306,6 +1317,12 @@ bool AsmParser::ParseAssignment(StringRef Name, bool \
allow_redef) {  if (Lexer.isNot(AsmToken::EndOfStatement))
     return TokError("unexpected token in assignment");
 
+  // Error on assignment to '.'.
+  if (Name == ".") {
+    return Error(EqualLoc, ("assignment to pseudo-symbol '.' is unsupported "
+                            "(use '.space' or '.org').)"));
+  }
+
   // Eat the end of statement marker.
   Lex();
 
@@ -1535,13 +1552,21 @@ bool AsmParser::ParseDirectiveRealValue(const fltSemantics \
&Semantics) {  Lex();
 
       if (getLexer().isNot(AsmToken::Integer) &&
-          getLexer().isNot(AsmToken::Real))
+          getLexer().isNot(AsmToken::Real) &&
+          getLexer().isNot(AsmToken::Identifier))
         return TokError("unexpected token in directive");
 
       // Convert to an APFloat.
       APFloat Value(Semantics);
-      if (Value.convertFromString(getTok().getString(),
-                                  APFloat::rmNearestTiesToEven) ==
+      StringRef IDVal = getTok().getString();
+      if (getLexer().is(AsmToken::Identifier)) {
+        if (!IDVal.compare_lower("infinity") || !IDVal.compare_lower("inf"))
+          Value = APFloat::getInf(Semantics);
+        else if (!IDVal.compare_lower("nan"))
+          Value = APFloat::getNaN(Semantics, false, ~0);
+        else
+          return TokError("invalid floating point literal");
+      } else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) ==
           APFloat::opInvalidOp)
         return TokError("invalid floating point literal");
       if (IsNeg)
Modified: lib/Support/APFloat.cpp
===================================================================
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -3562,3 +3562,37 @@ void APFloat::toString(SmallVectorImpl<char> &Str,
   for (; I != NDigits; ++I)
     Str.push_back(buffer[NDigits-I-1]);
 }
+
+bool APFloat::getExactInverse(APFloat *inv) const {
+  // We can only guarantee the existance of an exact inverse for IEEE floats.
+  if (semantics != &IEEEhalf && semantics != &IEEEsingle &&
+      semantics != &IEEEdouble && semantics != &IEEEquad)
+    return false;
+
+  // Special floats and denormals have no exact inverse.
+  if (category != fcNormal)
+    return false;
+
+  // Check that the number is a power of two by making sure that only the
+  // integer bit is set in the significand.
+  if (significandLSB() != semantics->precision - 1)
+    return false;
+
+  // Get the inverse.
+  APFloat reciprocal(*semantics, 1ULL);
+  if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK)
+    return false;
+
+  // Avoid multiplication with a denormal, it is not safe on all platforms and
+  // may be slower than a normal division.
+  if (reciprocal.significandMSB() + 1 < reciprocal.semantics->precision)
+    return false;
+
+  assert(reciprocal.category == fcNormal &&
+         reciprocal.significandLSB() == reciprocal.semantics->precision - 1);
+
+  if (inv)
+    *inv = reciprocal;
+
+  return true;
+}
Modified: lib/Support/APInt.cpp
===================================================================
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -2078,6 +2078,16 @@ APInt APInt::smul_ov(const APInt &RHS, bool &Overflow) const {
   return Res;
 }
 
+APInt APInt::umul_ov(const APInt &RHS, bool &Overflow) const {
+  APInt Res = *this * RHS;
+
+  if (*this != 0 && RHS != 0)
+    Overflow = Res.udiv(RHS) != *this || Res.udiv(*this) != RHS;
+  else
+    Overflow = false;
+  return Res;
+}
+
 APInt APInt::sshl_ov(unsigned ShAmt, bool &Overflow) const {
   Overflow = ShAmt >= getBitWidth();
   if (Overflow)
Modified: lib/Support/SmallPtrSet.cpp
===================================================================
--- a/lib/Support/SmallPtrSet.cpp
+++ b/lib/Support/SmallPtrSet.cpp
@@ -52,10 +52,14 @@ bool SmallPtrSetImpl::insert_imp(const void * Ptr) {
     // Otherwise, hit the big set case, which will call grow.
   }
   
-  // If more than 3/4 of the array is full, grow.
-  if (NumElements*4 >= CurArraySize*3 ||
-      CurArraySize-(NumElements+NumTombstones) < CurArraySize/8)
-    Grow();
+  if (NumElements*4 >= CurArraySize*3) {
+    // If more than 3/4 of the array is full, grow.
+    Grow(CurArraySize < 64 ? 128 : CurArraySize*2);
+  } else if (CurArraySize-(NumElements+NumTombstones) < CurArraySize/8) {
+    // If fewer of 1/8 of the array is empty (meaning that many are filled with
+    // tombstones), rehash.
+    Grow(CurArraySize);
+  }
   
   // Okay, we know we have space.  Find a hash bucket.
   const void **Bucket = const_cast<const void**>(FindBucketFor(Ptr));
@@ -125,10 +129,9 @@ const void * const *SmallPtrSetImpl::FindBucketFor(const void \
*Ptr) const {  
 /// Grow - Allocate a larger backing store for the buckets and move it over.
 ///
-void SmallPtrSetImpl::Grow() {
+void SmallPtrSetImpl::Grow(unsigned NewSize) {
   // Allocate at twice as many buckets, but at least 128.
   unsigned OldSize = CurArraySize;
-  unsigned NewSize = OldSize < 64 ? 128 : OldSize*2;
   
   const void **OldBuckets = CurArray;
   bool WasSmall = isSmall();
Modified: lib/Support/StringMap.cpp
===================================================================
--- a/lib/Support/StringMap.cpp
+++ b/lib/Support/StringMap.cpp
@@ -169,6 +169,8 @@ StringMapEntryBase *StringMapImpl::RemoveKey(StringRef Key) {
   TheTable[Bucket].Item = getTombstoneVal();
   --NumItems;
   ++NumTombstones;
+  assert(NumItems + NumTombstones <= NumBuckets);
+
   return Result;
 }
 
@@ -177,7 +179,19 @@ StringMapEntryBase *StringMapImpl::RemoveKey(StringRef Key) {
 /// RehashTable - Grow the table, redistributing values into the buckets with
 /// the appropriate mod-of-hashtable-size.
 void StringMapImpl::RehashTable() {
-  unsigned NewSize = NumBuckets*2;
+  unsigned NewSize;
+
+  // If the hash table is now more than 3/4 full, or if fewer than 1/8 of
+  // the buckets are empty (meaning that many are filled with tombstones),
+  // grow/rehash the table.
+  if (NumItems*4 > NumBuckets*3) {
+    NewSize = NumBuckets*2;
+  } else if (NumBuckets-(NumItems+NumTombstones) < NumBuckets/8) {
+    NewSize = NumBuckets;
+  } else {
+    return;
+  }
+
   // Allocate one extra bucket which will always be non-empty.  This allows the
   // iterators to stop at end.
   ItemBucket *NewTableArray =(ItemBucket*)calloc(NewSize+1, sizeof(ItemBucket));
@@ -212,4 +226,5 @@ void StringMapImpl::RehashTable() {
   
   TheTable = NewTableArray;
   NumBuckets = NewSize;
+  NumTombstones = 0;
 }
Modified: lib/Target/ARM/ARMAddressingModes.h
===================================================================
--- a/lib/Target/ARM/ARMAddressingModes.h
+++ b/lib/Target/ARM/ARMAddressingModes.h
@@ -408,16 +408,18 @@ namespace ARM_AM {
   //
   // The first operand is always a Reg.  The second operand is a reg if in
   // reg/reg form, otherwise it's reg#0.  The third field encodes the operation
-  // in bit 12, the immediate in bits 0-11, and the shift op in 13-15.
+  // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The
+  // forth operand 16-17 encodes the index mode.
   //
   // If this addressing mode is a frame index (before prolog/epilog insertion
   // and code rewriting), this operand will have the form:  FI#, reg0, <offs>
   // with no shift amount for the frame offset.
   //
-  static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO) {
+  static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO,
+                                   unsigned IdxMode = 0) {
     assert(Imm12 < (1 << 12) && "Imm too large!");
     bool isSub = Opc == sub;
-    return Imm12 | ((int)isSub << 12) | (SO << 13);
+    return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ;
   }
   static inline unsigned getAM2Offset(unsigned AM2Opc) {
     return AM2Opc & ((1 << 12)-1);
@@ -426,7 +428,10 @@ namespace ARM_AM {
     return ((AM2Opc >> 12) & 1) ? sub : add;
   }
   static inline ShiftOpc getAM2ShiftOpc(unsigned AM2Opc) {
-    return (ShiftOpc)(AM2Opc >> 13);
+    return (ShiftOpc)((AM2Opc >> 13) & 7);
+  }
+  static inline unsigned getAM2IdxMode(unsigned AM2Opc) {
+    return (AM2Opc >> 16);
   }
 
 
Modified: lib/Target/ARM/ARMBaseInfo.h
===================================================================
--- a/lib/Target/ARM/ARMBaseInfo.h
+++ b/lib/Target/ARM/ARMBaseInfo.h
@@ -200,6 +200,59 @@ inline static unsigned getARMRegisterNumbering(unsigned Reg) {
 }
 
 namespace ARMII {
+
+  /// ARM Index Modes
+  enum IndexMode {
+    IndexModeNone  = 0,
+    IndexModePre   = 1,
+    IndexModePost  = 2,
+    IndexModeUpd   = 3
+  };
+
+  /// ARM Addressing Modes
+  enum AddrMode {
+    AddrModeNone    = 0,
+    AddrMode1       = 1,
+    AddrMode2       = 2,
+    AddrMode3       = 3,
+    AddrMode4       = 4,
+    AddrMode5       = 5,
+    AddrMode6       = 6,
+    AddrModeT1_1    = 7,
+    AddrModeT1_2    = 8,
+    AddrModeT1_4    = 9,
+    AddrModeT1_s    = 10, // i8 * 4 for pc and sp relative data
+    AddrModeT2_i12  = 11,
+    AddrModeT2_i8   = 12,
+    AddrModeT2_so   = 13,
+    AddrModeT2_pc   = 14, // +/- i12 for pc relative data
+    AddrModeT2_i8s4 = 15, // i8 * 4
+    AddrMode_i12    = 16
+  };
+
+  inline static const char *AddrModeToString(AddrMode addrmode) {
+    switch (addrmode) {
+    default: llvm_unreachable("Unknown memory operation");
+    case AddrModeNone:    return "AddrModeNone";
+    case AddrMode1:       return "AddrMode1";
+    case AddrMode2:       return "AddrMode2";
+    case AddrMode3:       return "AddrMode3";
+    case AddrMode4:       return "AddrMode4";
+    case AddrMode5:       return "AddrMode5";
+    case AddrMode6:       return "AddrMode6";
+    case AddrModeT1_1:    return "AddrModeT1_1";
+    case AddrModeT1_2:    return "AddrModeT1_2";
+    case AddrModeT1_4:    return "AddrModeT1_4";
+    case AddrModeT1_s:    return "AddrModeT1_s";
+    case AddrModeT2_i12:  return "AddrModeT2_i12";
+    case AddrModeT2_i8:   return "AddrModeT2_i8";
+    case AddrModeT2_so:   return "AddrModeT2_so";
+    case AddrModeT2_pc:   return "AddrModeT2_pc";
+    case AddrModeT2_i8s4: return "AddrModeT2_i8s4";
+    case AddrMode_i12:    return "AddrMode_i12";
+    }
+  }
+
   /// Target Operand Flag enum.
   enum TOF {
     //===------------------------------------------------------------------===//
Modified: lib/Target/ARM/ARMBaseInstrInfo.cpp
===================================================================
--- a/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -1789,9 +1789,7 @@ ARMBaseInstrInfo::getNumMicroOps(const InstrItineraryData \
*ItinData,  llvm_unreachable("Unexpected multi-uops instruction!");
     break;
   case ARM::VLDMQIA:
-  case ARM::VLDMQDB:
   case ARM::VSTMQIA:
-  case ARM::VSTMQDB:
     return 2;
 
   // The number of uOps for load / store multiple are determined by the number
@@ -1805,19 +1803,15 @@ ARMBaseInstrInfo::getNumMicroOps(const InstrItineraryData \
*ItinData,  // is not 64-bit aligned, then AGU would take an extra cycle.  For VFP / \
NEON  // load / store multiple, the formula is (#reg / 2) + (#reg % 2) + 1.
   case ARM::VLDMDIA:
-  case ARM::VLDMDDB:
   case ARM::VLDMDIA_UPD:
   case ARM::VLDMDDB_UPD:
   case ARM::VLDMSIA:
-  case ARM::VLDMSDB:
   case ARM::VLDMSIA_UPD:
   case ARM::VLDMSDB_UPD:
   case ARM::VSTMDIA:
-  case ARM::VSTMDDB:
   case ARM::VSTMDIA_UPD:
   case ARM::VSTMDDB_UPD:
   case ARM::VSTMSIA:
-  case ARM::VSTMSDB:
   case ARM::VSTMSIA_UPD:
   case ARM::VSTMSDB_UPD: {
     unsigned NumRegs = MI->getNumOperands() - Desc.getNumOperands();
@@ -1907,7 +1901,6 @@ ARMBaseInstrInfo::getVLDMDefCycle(const InstrItineraryData \
*ItinData,  switch (DefTID.getOpcode()) {
     default: break;
     case ARM::VLDMSIA:
-    case ARM::VLDMSDB:
     case ARM::VLDMSIA_UPD:
     case ARM::VLDMSDB_UPD:
       isSLoad = true;
@@ -1983,7 +1976,6 @@ ARMBaseInstrInfo::getVSTMUseCycle(const InstrItineraryData \
*ItinData,  switch (UseTID.getOpcode()) {
     default: break;
     case ARM::VSTMSIA:
-    case ARM::VSTMSDB:
     case ARM::VSTMSIA_UPD:
     case ARM::VSTMSDB_UPD:
       isSStore = true;
@@ -2054,11 +2046,9 @@ ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData \
*ItinData,  break;
 
   case ARM::VLDMDIA:
-  case ARM::VLDMDDB:
   case ARM::VLDMDIA_UPD:
   case ARM::VLDMDDB_UPD:
   case ARM::VLDMSIA:
-  case ARM::VLDMSDB:
   case ARM::VLDMSIA_UPD:
   case ARM::VLDMSDB_UPD:
     DefCycle = getVLDMDefCycle(ItinData, DefTID, DefClass, DefIdx, DefAlign);
@@ -2097,11 +2087,9 @@ ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData \
*ItinData,  break;
 
   case ARM::VSTMDIA:
-  case ARM::VSTMDDB:
   case ARM::VSTMDIA_UPD:
   case ARM::VSTMDDB_UPD:
   case ARM::VSTMSIA:
-  case ARM::VSTMSDB:
   case ARM::VSTMSIA_UPD:
   case ARM::VSTMSDB_UPD:
     UseCycle = getVSTMUseCycle(ItinData, UseTID, UseClass, UseIdx, UseAlign);
@@ -2312,9 +2300,7 @@ int ARMBaseInstrInfo::getInstrLatency(const InstrItineraryData \
*ItinData,  default:
     return ItinData->getStageLatency(get(Opcode).getSchedClass());
   case ARM::VLDMQIA:
-  case ARM::VLDMQDB:
   case ARM::VSTMQIA:
-  case ARM::VSTMQDB:
     return 2;
   }
 }
Modified: lib/Target/ARM/ARMBaseInstrInfo.h
===================================================================
--- a/lib/Target/ARM/ARMBaseInstrInfo.h
+++ b/lib/Target/ARM/ARMBaseInstrInfo.h
@@ -34,25 +34,7 @@ namespace ARMII {
 
     //===------------------------------------------------------------------===//
     // This four-bit field describes the addressing mode used.
-
-    AddrModeMask  = 0x1f,
-    AddrModeNone    = 0,
-    AddrMode1       = 1,
-    AddrMode2       = 2,
-    AddrMode3       = 3,
-    AddrMode4       = 4,
-    AddrMode5       = 5,
-    AddrMode6       = 6,
-    AddrModeT1_1    = 7,
-    AddrModeT1_2    = 8,
-    AddrModeT1_4    = 9,
-    AddrModeT1_s    = 10, // i8 * 4 for pc and sp relative data
-    AddrModeT2_i12  = 11,
-    AddrModeT2_i8   = 12,
-    AddrModeT2_so   = 13,
-    AddrModeT2_pc   = 14, // +/- i12 for pc relative data
-    AddrModeT2_i8s4 = 15, // i8 * 4
-    AddrMode_i12    = 16,
+    AddrModeMask  = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h
 
     // Size* - Flags to keep track of the size of an instruction.
     SizeShift     = 5,
@@ -64,11 +46,9 @@ namespace ARMII {
 
     // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load
     // and store ops only.  Generic "updating" flag is used for ld/st multiple.
+    // The index mode enums are declared in ARMBaseInfo.h
     IndexModeShift = 8,
     IndexModeMask  = 3 << IndexModeShift,
-    IndexModePre   = 1,
-    IndexModePost  = 2,
-    IndexModeUpd   = 3,
 
     //===------------------------------------------------------------------===//
     // Instruction encoding formats.
Modified: lib/Target/ARM/ARMBaseRegisterInfo.cpp
===================================================================
--- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -458,6 +458,10 @@ ARMBaseRegisterInfo::getAllocationOrder(const \
                TargetRegisterClass *RC,
     ARM::R0, ARM::R2, ARM::R10,ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8
   };
 
+  // We only support even/odd hints for GPR and rGPR.
+  if (RC != ARM::GPRRegisterClass && RC != ARM::rGPRRegisterClass)
+    return std::make_pair(RC->allocation_order_begin(MF),
+                          RC->allocation_order_end(MF));
 
   if (HintType == ARMRI::RegPairEven) {
     if (isPhysicalRegister(HintReg) && getRegisterPairEven(HintReg, MF) == 0)
Modified: lib/Target/ARM/ARMExpandPseudoInsts.cpp
===================================================================
--- a/lib/Target/ARM/ARMExpandPseudoInsts.cpp
+++ b/lib/Target/ARM/ARMExpandPseudoInsts.cpp
@@ -967,9 +967,8 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
       return true;
     }
 
-    case ARM::VLDMQIA:
-    case ARM::VLDMQDB: {
-      unsigned NewOpc = (Opcode == ARM::VLDMQIA) ? ARM::VLDMDIA : ARM::VLDMDDB;
+    case ARM::VLDMQIA: {
+      unsigned NewOpc = ARM::VLDMDIA;
       MachineInstrBuilder MIB =
         BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc));
       unsigned OpIdx = 0;
@@ -998,9 +997,8 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
       return true;
     }
 
-    case ARM::VSTMQIA:
-    case ARM::VSTMQDB: {
-      unsigned NewOpc = (Opcode == ARM::VSTMQIA) ? ARM::VSTMDIA : ARM::VSTMDDB;
+    case ARM::VSTMQIA: {
+      unsigned NewOpc = ARM::VSTMDIA;
       MachineInstrBuilder MIB =
         BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc));
       unsigned OpIdx = 0;
Modified: lib/Target/ARM/ARMFastISel.cpp
===================================================================
--- a/lib/Target/ARM/ARMFastISel.cpp
+++ b/lib/Target/ARM/ARMFastISel.cpp
@@ -115,6 +115,11 @@ class ARMFastISel : public FastISel {
                                      const TargetRegisterClass *RC,
                                      unsigned Op0, bool Op0IsKill,
                                      unsigned Op1, bool Op1IsKill);
+    virtual unsigned FastEmitInst_rrr(unsigned MachineInstOpcode,
+                                      const TargetRegisterClass *RC,
+                                      unsigned Op0, bool Op0IsKill,
+                                      unsigned Op1, bool Op1IsKill,
+                                      unsigned Op2, bool Op2IsKill);
     virtual unsigned FastEmitInst_ri(unsigned MachineInstOpcode,
                                      const TargetRegisterClass *RC,
                                      unsigned Op0, bool Op0IsKill,
@@ -315,6 +320,31 @@ unsigned ARMFastISel::FastEmitInst_rr(unsigned \
MachineInstOpcode,  return ResultReg;
 }
 
+unsigned ARMFastISel::FastEmitInst_rrr(unsigned MachineInstOpcode,
+                                       const TargetRegisterClass *RC,
+                                       unsigned Op0, bool Op0IsKill,
+                                       unsigned Op1, bool Op1IsKill,
+                                       unsigned Op2, bool Op2IsKill) {
+  unsigned ResultReg = createResultReg(RC);
+  const TargetInstrDesc &II = TII.get(MachineInstOpcode);
+
+  if (II.getNumDefs() >= 1)
+    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
+                   .addReg(Op0, Op0IsKill * RegState::Kill)
+                   .addReg(Op1, Op1IsKill * RegState::Kill)
+                   .addReg(Op2, Op2IsKill * RegState::Kill));
+  else {
+    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
+                   .addReg(Op0, Op0IsKill * RegState::Kill)
+                   .addReg(Op1, Op1IsKill * RegState::Kill)
+                   .addReg(Op2, Op2IsKill * RegState::Kill));
+    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
+                           TII.get(TargetOpcode::COPY), ResultReg)
+                   .addReg(II.ImplicitDefs[0]));
+  }
+  return ResultReg;
+}
+
 unsigned ARMFastISel::FastEmitInst_ri(unsigned MachineInstOpcode,
                                       const TargetRegisterClass *RC,
                                       unsigned Op0, bool Op0IsKill,
Modified: lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -461,6 +461,10 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
     setOperationAction(ISD::UDIV, MVT::v8i8, Custom);
     setOperationAction(ISD::VSETCC, MVT::v1i64, Expand);
     setOperationAction(ISD::VSETCC, MVT::v2i64, Expand);
+    // Neon does not have single instruction SINT_TO_FP and UINT_TO_FP with
+    // a destination type that is wider than the source.
+    setOperationAction(ISD::SINT_TO_FP, MVT::v4i16, Custom);
+    setOperationAction(ISD::UINT_TO_FP, MVT::v4i16, Custom);
 
     setTargetDAGCombine(ISD::INTRINSIC_VOID);
     setTargetDAGCombine(ISD::INTRINSIC_W_CHAIN);
@@ -862,6 +866,7 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) \
const {  case ARMISD::BFI:           return "ARMISD::BFI";
   case ARMISD::VORRIMM:       return "ARMISD::VORRIMM";
   case ARMISD::VBICIMM:       return "ARMISD::VBICIMM";
+  case ARMISD::VBSL:          return "ARMISD::VBSL";
   case ARMISD::VLD2DUP:       return "ARMISD::VLD2DUP";
   case ARMISD::VLD3DUP:       return "ARMISD::VLD3DUP";
   case ARMISD::VLD4DUP:       return "ARMISD::VLD4DUP";
@@ -2163,6 +2168,13 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, \
SelectionDAG &DAG,  }
     return Result;
   }
+  case Intrinsic::arm_neon_vmulls:
+  case Intrinsic::arm_neon_vmullu: {
+    unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmulls)
+      ? ARMISD::VMULLs : ARMISD::VMULLu;
+    return DAG.getNode(NewOpc, Op.getDebugLoc(), Op.getValueType(),
+                       Op.getOperand(1), Op.getOperand(2));
+  }
   }
 }
 
@@ -2389,8 +2401,9 @@ ARMTargetLowering::LowerFormalArguments(SDValue Chain,
           // In case of tail call optimization mark all arguments mutable. Since \
                they
           // could be overwritten by lowering of arguments in case of a tail call.
           if (Flags.isByVal()) {
-            int FI = MFI->CreateFixedObject(Flags.getByValSize(),
-                                            VA.getLocMemOffset(), false);
+            unsigned Bytes = Flags.getByValSize();
+            if (Bytes == 0) Bytes = 1; // Don't create zero-sized stack objects.
+            int FI = MFI->CreateFixedObject(Bytes, VA.getLocMemOffset(), false);
             InVals.push_back(DAG.getFrameIndex(FI, getPointerTy()));
           } else {
             int FI = MFI->CreateFixedObject(VA.getLocVT().getSizeInBits()/8,
@@ -2864,8 +2877,39 @@ static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) {
   return DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op);
 }
 
+static SDValue LowerVectorINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
+  EVT VT = Op.getValueType();
+  DebugLoc dl = Op.getDebugLoc();
+
+  EVT OperandVT = Op.getOperand(0).getValueType();
+  assert(OperandVT == MVT::v4i16 && "Invalid type for custom lowering!");
+  if (VT != MVT::v4f32)
+    return DAG.UnrollVectorOp(Op.getNode());
+
+  unsigned CastOpc;
+  unsigned Opc;
+  switch (Op.getOpcode()) {
+  default:
+    assert(0 && "Invalid opcode!");
+  case ISD::SINT_TO_FP:
+    CastOpc = ISD::SIGN_EXTEND;
+    Opc = ISD::SINT_TO_FP;
+    break;
+  case ISD::UINT_TO_FP:
+    CastOpc = ISD::ZERO_EXTEND;
+    Opc = ISD::UINT_TO_FP;
+    break;
+  }
+
+  Op = DAG.getNode(CastOpc, dl, MVT::v4i32, Op.getOperand(0));
+  return DAG.getNode(Opc, dl, VT, Op);
+}
+
 static SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
   EVT VT = Op.getValueType();
+  if (VT.isVector())
+    return LowerVectorINT_TO_FP(Op, DAG);
+
   DebugLoc dl = Op.getDebugLoc();
   unsigned Opc;
 
@@ -4380,6 +4424,28 @@ static SDValue SkipExtension(SDNode *N, SelectionDAG &DAG) {
                      MVT::getVectorVT(TruncVT, NumElts), Ops.data(), NumElts);
 }
 
+static bool isAddSubSExt(SDNode *N, SelectionDAG &DAG) {
+  unsigned Opcode = N->getOpcode();
+  if (Opcode == ISD::ADD || Opcode == ISD::SUB) {
+    SDNode *N0 = N->getOperand(0).getNode();
+    SDNode *N1 = N->getOperand(1).getNode();
+    return N0->hasOneUse() && N1->hasOneUse() &&
+      isSignExtended(N0, DAG) && isSignExtended(N1, DAG);
+  }
+  return false;
+}
+
+static bool isAddSubZExt(SDNode *N, SelectionDAG &DAG) {
+  unsigned Opcode = N->getOpcode();
+  if (Opcode == ISD::ADD || Opcode == ISD::SUB) {
+    SDNode *N0 = N->getOperand(0).getNode();
+    SDNode *N1 = N->getOperand(1).getNode();
+    return N0->hasOneUse() && N1->hasOneUse() &&
+      isZeroExtended(N0, DAG) && isZeroExtended(N1, DAG);
+  }
+  return false;
+}
+
 static SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) {
   // Multiplications are only custom-lowered for 128-bit vectors so that
   // VMULL can be detected.  Otherwise v2i64 multiplications are not legal.
@@ -4388,26 +4454,70 @@ static SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) {
   SDNode *N0 = Op.getOperand(0).getNode();
   SDNode *N1 = Op.getOperand(1).getNode();
   unsigned NewOpc = 0;
-  if (isSignExtended(N0, DAG) && isSignExtended(N1, DAG))
+  bool isMLA = false;
+  bool isN0SExt = isSignExtended(N0, DAG);
+  bool isN1SExt = isSignExtended(N1, DAG);
+  if (isN0SExt && isN1SExt)
     NewOpc = ARMISD::VMULLs;
-  else if (isZeroExtended(N0, DAG) && isZeroExtended(N1, DAG))
-    NewOpc = ARMISD::VMULLu;
-  else if (VT == MVT::v2i64)
-    // Fall through to expand this.  It is not legal.
-    return SDValue();
-  else
-    // Other vector multiplications are legal.
-    return Op;
+  else {
+    bool isN0ZExt = isZeroExtended(N0, DAG);
+    bool isN1ZExt = isZeroExtended(N1, DAG);
+    if (isN0ZExt && isN1ZExt)
+      NewOpc = ARMISD::VMULLu;
+    else if (isN1SExt || isN1ZExt) {
+      // Look for (s/zext A + s/zext B) * (s/zext C). We want to turn these
+      // into (s/zext A * s/zext C) + (s/zext B * s/zext C)
+      if (isN1SExt && isAddSubSExt(N0, DAG)) {
+        NewOpc = ARMISD::VMULLs;
+        isMLA = true;
+      } else if (isN1ZExt && isAddSubZExt(N0, DAG)) {
+        NewOpc = ARMISD::VMULLu;
+        isMLA = true;
+      } else if (isN0ZExt && isAddSubZExt(N1, DAG)) {
+        std::swap(N0, N1);
+        NewOpc = ARMISD::VMULLu;
+        isMLA = true;
+      }
+    }
+
+    if (!NewOpc) {
+      if (VT == MVT::v2i64)
+        // Fall through to expand this.  It is not legal.
+        return SDValue();
+      else
+        // Other vector multiplications are legal.
+        return Op;
+    }
+  }
 
   // Legalize to a VMULL instruction.
   DebugLoc DL = Op.getDebugLoc();
-  SDValue Op0 = SkipExtension(N0, DAG);
+  SDValue Op0;
   SDValue Op1 = SkipExtension(N1, DAG);
-
-  assert(Op0.getValueType().is64BitVector() &&
-         Op1.getValueType().is64BitVector() &&
-         "unexpected types for extended operands to VMULL");
-  return DAG.getNode(NewOpc, DL, VT, Op0, Op1);
+  if (!isMLA) {
+    Op0 = SkipExtension(N0, DAG);
+    assert(Op0.getValueType().is64BitVector() &&
+           Op1.getValueType().is64BitVector() &&
+           "unexpected types for extended operands to VMULL");
+    return DAG.getNode(NewOpc, DL, VT, Op0, Op1);
+  }
+
+  // Optimizing (zext A + zext B) * C, to (VMULL A, C) + (VMULL B, C) during
+  // isel lowering to take advantage of no-stall back to back vmul + vmla.
+  //   vmull q0, d4, d6
+  //   vmlal q0, d5, d6
+  // is faster than
+  //   vaddl q0, d4, d5
+  //   vmovl q1, d6
+  //   vmul  q0, q0, q1
+  SDValue N00 = SkipExtension(N0->getOperand(0).getNode(), DAG);
+  SDValue N01 = SkipExtension(N0->getOperand(1).getNode(), DAG);
+  EVT Op1VT = Op1.getValueType();
+  return DAG.getNode(N0->getOpcode(), DL, VT,
+                     DAG.getNode(NewOpc, DL, VT,
+                               DAG.getNode(ISD::BITCAST, DL, Op1VT, N00), Op1),
+                     DAG.getNode(NewOpc, DL, VT,
+                               DAG.getNode(ISD::BITCAST, DL, Op1VT, N01), Op1));
 }
 
 static SDValue 
@@ -5178,6 +5288,7 @@ static SDValue PerformMULCombine(SDNode *N,
 
 static SDValue PerformANDCombine(SDNode *N,
                                 TargetLowering::DAGCombinerInfo &DCI) {
+  
   // Attempt to use immediate-form VBIC
   BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
   DebugLoc dl = N->getDebugLoc();
@@ -5237,6 +5348,37 @@ static SDValue PerformORCombine(SDNode *N,
     }
   }
 
+  SDValue N0 = N->getOperand(0);
+  if (N0.getOpcode() != ISD::AND)
+    return SDValue();
+  SDValue N1 = N->getOperand(1);
+
+  // (or (and B, A), (and C, ~A)) => (VBSL A, B, C) when A is a constant.
+  if (Subtarget->hasNEON() && N1.getOpcode() == ISD::AND && VT.isVector() &&
+      DAG.getTargetLoweringInfo().isTypeLegal(VT)) {
+    APInt SplatUndef;
+    unsigned SplatBitSize;
+    bool HasAnyUndefs;
+
+    BuildVectorSDNode *BVN0 = dyn_cast<BuildVectorSDNode>(N0->getOperand(1));
+    APInt SplatBits0;
+    if (BVN0 && BVN0->isConstantSplat(SplatBits0, SplatUndef, SplatBitSize,
+                                  HasAnyUndefs) && !HasAnyUndefs) {
+      BuildVectorSDNode *BVN1 = dyn_cast<BuildVectorSDNode>(N1->getOperand(1));
+      APInt SplatBits1;
+      if (BVN1 && BVN1->isConstantSplat(SplatBits1, SplatUndef, SplatBitSize,
+                                    HasAnyUndefs) && !HasAnyUndefs &&
+          SplatBits0 == ~SplatBits1) {
+        // Canonicalize the vector type to make instruction selection simpler.
+        EVT CanonicalVT = VT.is128BitVector() ? MVT::v4i32 : MVT::v2i32;
+        SDValue Result = DAG.getNode(ARMISD::VBSL, dl, CanonicalVT,
+                                     N0->getOperand(1), N0->getOperand(0),
+                                     N1->getOperand(1));
+        return DAG.getNode(ISD::BITCAST, dl, VT, Result);
+      }
+    }
+  }
+
   // Try to use the ARM/Thumb2 BFI (bitfield insert) instruction when
   // reasonable.
 
@@ -5244,19 +5386,16 @@ static SDValue PerformORCombine(SDNode *N,
   if (Subtarget->isThumb1Only() || !Subtarget->hasV6T2Ops())
     return SDValue();
 
-  SDValue N0 = N->getOperand(0), N1 = N->getOperand(1);
   DebugLoc DL = N->getDebugLoc();
   // 1) or (and A, mask), val => ARMbfi A, val, mask
   //      iff (val & mask) == val
   //
   // 2) or (and A, mask), (and B, mask2) => ARMbfi A, (lsr B, amt), mask
   //  2a) iff isBitFieldInvertedMask(mask) && isBitFieldInvertedMask(~mask2)
-  //          && CountPopulation_32(mask) == CountPopulation_32(~mask2)
+  //          && mask == ~mask2
   //  2b) iff isBitFieldInvertedMask(~mask) && isBitFieldInvertedMask(mask2)
-  //          && CountPopulation_32(mask) == CountPopulation_32(~mask2)
+  //          && ~mask == mask2
   //  (i.e., copy a bitfield value into another bitfield of the same width)
-  if (N0.getOpcode() != ISD::AND)
-    return SDValue();
 
   if (VT != MVT::i32)
     return SDValue();
@@ -5299,26 +5438,26 @@ static SDValue PerformORCombine(SDNode *N,
       return SDValue();
     unsigned Mask2 = N11C->getZExtValue();
 
+    // Mask and ~Mask2 (or reverse) must be equivalent for the BFI pattern
+    // as is to match.
     if (ARM::isBitFieldInvertedMask(Mask) &&
-        ARM::isBitFieldInvertedMask(~Mask2) &&
-        (CountPopulation_32(Mask) == CountPopulation_32(~Mask2))) {
+        (Mask == ~Mask2)) {
       // The pack halfword instruction works better for masks that fit it,
       // so use that when it's available.
       if (Subtarget->hasT2ExtractPack() &&
           (Mask == 0xffff || Mask == 0xffff0000))
         return SDValue();
       // 2a
-      unsigned lsb = CountTrailingZeros_32(Mask2);
+      unsigned amt = CountTrailingZeros_32(Mask2);
       Res = DAG.getNode(ISD::SRL, DL, VT, N1.getOperand(0),
-                        DAG.getConstant(lsb, MVT::i32));
+                        DAG.getConstant(amt, MVT::i32));
       Res = DAG.getNode(ARMISD::BFI, DL, VT, N00, Res,
                         DAG.getConstant(Mask, MVT::i32));
       // Do not add new nodes to DAG combiner worklist.
       DCI.CombineTo(N, Res, false);
       return SDValue();
     } else if (ARM::isBitFieldInvertedMask(~Mask) &&
-               ARM::isBitFieldInvertedMask(Mask2) &&
-               (CountPopulation_32(~Mask) == CountPopulation_32(Mask2))) {
+               (~Mask == Mask2)) {
       // The pack halfword instruction works better for masks that fit it,
       // so use that when it's available.
       if (Subtarget->hasT2ExtractPack() &&
@@ -5329,7 +5468,7 @@ static SDValue PerformORCombine(SDNode *N,
       Res = DAG.getNode(ISD::SRL, DL, VT, N00,
                         DAG.getConstant(lsb, MVT::i32));
       Res = DAG.getNode(ARMISD::BFI, DL, VT, N1.getOperand(0), Res,
-                                DAG.getConstant(Mask2, MVT::i32));
+                        DAG.getConstant(Mask2, MVT::i32));
       // Do not add new nodes to DAG combiner worklist.
       DCI.CombineTo(N, Res, false);
       return SDValue();
Modified: lib/Target/ARM/ARMISelLowering.h
===================================================================
--- a/lib/Target/ARM/ARMISelLowering.h
+++ b/lib/Target/ARM/ARMISelLowering.h
@@ -179,6 +179,9 @@ namespace llvm {
       // Vector AND with NOT of immediate
       VBICIMM,
 
+      // Vector bitwise select
+      VBSL,
+
       // Vector load N-element structure to all lanes:
       VLD2DUP = ISD::FIRST_TARGET_MEMORY_OPCODE,
       VLD3DUP,
Modified: lib/Target/ARM/ARMInstrFormats.td
===================================================================
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -434,11 +434,11 @@ class AIstrex<bits<2> opcod, dag oops, dag iops, InstrItinClass \
itin,  opc, asm, "", pattern> {
   bits<4> Rd;
   bits<4> Rt;
-  bits<4> Rn;
+  bits<4> addr;
   let Inst{27-23} = 0b00011;
   let Inst{22-21} = opcod;
   let Inst{20}    = 0;
-  let Inst{19-16} = Rn;
+  let Inst{19-16} = addr;
   let Inst{15-12} = Rd;
   let Inst{11-4}  = 0b11111001;
   let Inst{3-0}   = Rt;
@@ -515,15 +515,15 @@ class AI2stridx<bit isByte, bit isPre, dag oops, dag iops,
   : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
                pattern> {
   // AM2 store w/ two operands: (GPR, am2offset)
+  // {17-14}  Rn
   // {13}     1 == Rm, 0 == imm12
   // {12}     isAdd
   // {11-0}   imm12/Rm
-  bits<14> offset;
-  bits<4> Rn;
-  let Inst{25} = offset{13};
-  let Inst{23} = offset{12};
-  let Inst{19-16} = Rn;
-  let Inst{11-0} = offset{11-0};
+  bits<18> addr;
+  let Inst{25} = addr{13};
+  let Inst{23} = addr{12};
+  let Inst{19-16} = addr{17-14};
+  let Inst{11-0} = addr{11-0};
 }
 
 // addrmode3 instructions
@@ -1682,7 +1682,8 @@ class N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit \
op6, bit op4,  }
 
 // NEON 3 vector register format.
-class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
+
+class N3VCommon<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit \
op4,  dag oops, dag iops, Format f, InstrItinClass itin,
           string opc, string dt, string asm, string cstr, list<dag> pattern>
   : NDataI<oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
@@ -1692,6 +1693,13 @@ class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, \
bit op6, bit op4,  let Inst{11-8}  = op11_8;
   let Inst{6}     = op6;
   let Inst{4}     = op4;
+}
+
+class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
+          dag oops, dag iops, Format f, InstrItinClass itin,
+          string opc, string dt, string asm, string cstr, list<dag> pattern>
+  : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
+              oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
 
   // Instruction operands.
   bits<5> Vd;
@@ -1706,6 +1714,47 @@ class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, \
bit op6, bit op4,  let Inst{5}     = Vm{4};
 }
 
+class N3VLane32<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit \
op4, +          dag oops, dag iops, Format f, InstrItinClass itin,
+          string opc, string dt, string asm, string cstr, list<dag> pattern>
+  : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
+              oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
+
+  // Instruction operands.
+  bits<5> Vd;
+  bits<5> Vn;
+  bits<5> Vm;
+  bit lane;
+
+  let Inst{15-12} = Vd{3-0};
+  let Inst{22}    = Vd{4};
+  let Inst{19-16} = Vn{3-0};
+  let Inst{7}     = Vn{4};
+  let Inst{3-0}   = Vm{3-0};
+  let Inst{5}     = lane;
+}
+
+class N3VLane16<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit \
op4, +          dag oops, dag iops, Format f, InstrItinClass itin,
+          string opc, string dt, string asm, string cstr, list<dag> pattern>
+  : N3VCommon<op24, op23, op21_20, op11_8, op6, op4,
+              oops, iops, f, itin, opc, dt, asm, cstr, pattern> {
+
+  // Instruction operands.
+  bits<5> Vd;
+  bits<5> Vn;
+  bits<5> Vm;
+  bits<2> lane;
+
+  let Inst{15-12} = Vd{3-0};
+  let Inst{22}    = Vd{4};
+  let Inst{19-16} = Vn{3-0};
+  let Inst{7}     = Vn{4};
+  let Inst{2-0}   = Vm{2-0};
+  let Inst{5}     = lane{1};
+  let Inst{3}     = lane{0};
+}
+
 // Same as N3V except it doesn't have a data type suffix.
 class N3VX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
            bit op4,
Modified: lib/Target/ARM/ARMInstrInfo.td
===================================================================
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -498,6 +498,12 @@ def ldst_so_reg : Operand<i32>,
   let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
 }
 
+def MemMode2AsmOperand : AsmOperandClass {
+  let Name = "MemMode2";
+  let SuperClasses = [];
+  let ParserMethod = "tryParseMemMode2Operand";
+}
+
 // addrmode2 := reg +/- imm12
 //           := reg +/- reg shop imm
 //
@@ -505,6 +511,7 @@ def addrmode2 : Operand<i32>,
                 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
   let EncoderMethod = "getAddrMode2OpValue";
   let PrintMethod = "printAddrMode2Operand";
+  let ParserMatchClass = MemMode2AsmOperand;
   let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
 }
 
@@ -590,6 +597,21 @@ def addrmodepc : Operand<i32>,
   let MIOperandInfo = (ops GPR, i32imm);
 }
 
+def MemMode7AsmOperand : AsmOperandClass {
+  let Name = "MemMode7";
+  let SuperClasses = [];
+}
+
+// addrmode7 := reg
+// Used by load/store exclusive instructions. Useful to enable right assembly
+// parsing and printing. Not used for any codegen matching.
+//
+def addrmode7 : Operand<i32> {
+  let PrintMethod = "printAddrMode7Operand";
+  let MIOperandInfo = (ops GPR);
+  let ParserMatchClass = MemMode7AsmOperand;
+}
+
 def nohash_imm : Operand<i32> {
   let PrintMethod = "printNoHashImmediate";
 }
@@ -1253,7 +1275,7 @@ let neverHasSideEffects = 1, isReMaterializable = 1 in
 // The 'adr' mnemonic encodes differently if the label is before or after
 // the instruction. The {24-21} opcode bits are set by the fixup, as we don't
 // know until then which form of the instruction will be used.
-def ADR : AI1<0, (outs GPR:$Rd), (ins adrlabel:$label),
+def ADR : AI1<{0,?,?,0}, (outs GPR:$Rd), (ins adrlabel:$label),
                  MiscFrm, IIC_iALUi, "adr", "\t$Rd, #$label", []> {
   bits<4> Rd;
   bits<12> label;
@@ -1641,20 +1663,21 @@ multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass \
itin> {  let Inst{23} = addr{12};
     let Inst{19-16} = addr{17-14};
     let Inst{11-0} = addr{11-0};
+    let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
   }
   def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
-                      (ins GPR:$Rn, am2offset:$offset),
-                      IndexModePost, LdFrm, itin,
-                      opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
+                      (ins addrmode2:$addr), IndexModePost, LdFrm, itin,
+                      opc, "\t$Rt, $addr", "$addr.base = $Rn_wb", []> {
+    // {17-14}  Rn
     // {13}     1 == Rm, 0 == imm12
     // {12}     isAdd
     // {11-0}   imm12/Rm
-    bits<14> offset;
-    bits<4> Rn;
-    let Inst{25} = offset{13};
-    let Inst{23} = offset{12};
-    let Inst{19-16} = Rn;
-    let Inst{11-0} = offset{11-0};
+    bits<18> addr;
+    let Inst{25} = addr{13};
+    let Inst{23} = addr{12};
+    let Inst{19-16} = addr{17-14};
+    let Inst{11-0} = addr{11-0};
+    let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
   }
 }
 
@@ -1699,17 +1722,35 @@ defm LDRD :  AI3_ldridx<0b1101, 0, "ldrd", IIC_iLoad_d_ru>;
 
 // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
 let mayLoad = 1, neverHasSideEffects = 1 in {
-def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
-                   (ins GPR:$base, am2offset:$offset), IndexModePost,
-                   LdFrm, IIC_iLoad_ru,
-                   "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
+def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb),
+                   (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_ru,
+                   "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
+  // {17-14}  Rn
+  // {13}     1 == Rm, 0 == imm12
+  // {12}     isAdd
+  // {11-0}   imm12/Rm
+  bits<18> addr;
+  let Inst{25} = addr{13};
+  let Inst{23} = addr{12};
   let Inst{21} = 1; // overwrite
-}
-def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
-                  (ins GPR:$base, am2offset:$offset), IndexModePost,
-                  LdFrm, IIC_iLoad_bh_ru,
-                  "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
+  let Inst{19-16} = addr{17-14};
+  let Inst{11-0} = addr{11-0};
+  let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
+}
+def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb),
+                  (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_bh_ru,
+                  "ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
+  // {17-14}  Rn
+  // {13}     1 == Rm, 0 == imm12
+  // {12}     isAdd
+  // {11-0}   imm12/Rm
+  bits<18> addr;
+  let Inst{25} = addr{13};
+  let Inst{23} = addr{12};
   let Inst{21} = 1; // overwrite
+  let Inst{19-16} = addr{17-14};
+  let Inst{11-0} = addr{11-0};
+  let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
 }
 def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
                  (ins GPR:$base, am3offset:$offset), IndexModePost,
@@ -1803,20 +1844,20 @@ def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
 
 // STRT, STRBT, and STRHT are for disassembly only.
 
-def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb),
-                    (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
+def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr),
                     IndexModePost, StFrm, IIC_iStore_ru,
-                    "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
+                    "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb",
                     [/* For disassembly only; pattern left blank */]> {
   let Inst{21} = 1; // overwrite
+  let AsmMatchConverter = "CvtStWriteBackRegAddrMode2";
 }
 
-def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb),
-                     (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
+def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr),
                      IndexModePost, StFrm, IIC_iStore_bh_ru,
-                     "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
+                     "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb",
                      [/* For disassembly only; pattern left blank */]> {
   let Inst{21} = 1; // overwrite
+  let AsmMatchConverter = "CvtStWriteBackRegAddrMode2";
 }
 
 def STRHT: AI3sthpo<(outs GPR:$base_wb),
@@ -3294,39 +3335,26 @@ let usesCustomInserter = 1 in {
 }
 
 let mayLoad = 1 in {
-def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
-                    "ldrexb", "\t$Rt, [$Rn]",
-                    []>;
-def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
-                    "ldrexh", "\t$Rt, [$Rn]",
-                    []>;
-def LDREX  : AIldrex<0b00, (outs GPR:$Rt), (ins GPR:$Rn), NoItinerary,
-                    "ldrex", "\t$Rt, [$Rn]",
-                    []>;
-def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins GPR:$Rn),
-                    NoItinerary,
-                    "ldrexd", "\t$Rt, $Rt2, [$Rn]",
-                    []>;
+def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins addrmode7:$addr), NoItinerary,
+                    "ldrexb", "\t$Rt, $addr", []>;
+def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins addrmode7:$addr), NoItinerary,
+                    "ldrexh", "\t$Rt, $addr", []>;
+def LDREX  : AIldrex<0b00, (outs GPR:$Rt), (ins addrmode7:$addr), NoItinerary,
+                    "ldrex", "\t$Rt, $addr", []>;
+def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins addrmode7:$addr),
+                    NoItinerary, "ldrexd", "\t$Rt, $Rt2, $addr", []>;
 }
 
 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
-def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$src, GPR:$Rn),
-                    NoItinerary,
-                    "strexb", "\t$Rd, $src, [$Rn]",
-                    []>;
-def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
-                    NoItinerary,
-                    "strexh", "\t$Rd, $Rt, [$Rn]",
-                    []>;
-def STREX  : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, GPR:$Rn),
-                    NoItinerary,
-                    "strex", "\t$Rd, $Rt, [$Rn]",
-                    []>;
+def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$Rt, addrmode7:$addr),
+                    NoItinerary, "strexb", "\t$Rd, $Rt, $addr", []>;
+def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, addrmode7:$addr),
+                    NoItinerary, "strexh", "\t$Rd, $Rt, $addr", []>;
+def STREX  : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, addrmode7:$addr),
+                    NoItinerary, "strex", "\t$Rd, $Rt, $addr", []>;
 def STREXD : AIstrex<0b01, (outs GPR:$Rd),
-                    (ins GPR:$Rt, GPR:$Rt2, GPR:$Rn),
-                    NoItinerary,
-                    "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]",
-                    []>;
+                    (ins GPR:$Rt, GPR:$Rt2, addrmode7:$addr),
+                    NoItinerary, "strexd", "\t$Rd, $Rt, $Rt2, $addr", []>;
 }
 
 // Clear-Exclusive is for disassembly only.
@@ -3389,8 +3417,9 @@ def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
   let Inst{23-20} = opc1;
 }
 
-class ACI<dag oops, dag iops, string opc, string asm>
-  : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
+class ACI<dag oops, dag iops, string opc, string asm,
+          IndexMode im = IndexModeNone>
+  : I<oops, iops, AddrModeNone, Size4Bytes, im, BrFrm, NoItinerary,
       opc, asm, "", [/* For disassembly only; pattern left blank */]> {
   let Inst{27-25} = 0b110;
 }
@@ -3409,7 +3438,7 @@ multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
 
   def _PRE : ACI<(outs),
       (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
-      opc, "\tp$cop, cr$CRd, $addr!"> {
+      opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> {
     let Inst{31-28} = op31_28;
     let Inst{24} = 1; // P = 1
     let Inst{21} = 1; // W = 1
@@ -3418,8 +3447,8 @@ multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
   }
 
   def _POST : ACI<(outs),
-      (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
-      opc, "\tp$cop, cr$CRd, [$base], $offset"> {
+      (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
+      opc, "\tp$cop, cr$CRd, $addr", IndexModePost> {
     let Inst{31-28} = op31_28;
     let Inst{24} = 0; // P = 0
     let Inst{21} = 1; // W = 1
@@ -3428,8 +3457,8 @@ multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
   }
 
   def _OPTION : ACI<(outs),
-      (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, i32imm:$option),
-      opc, "\tp$cop, cr$CRd, [$base], $option"> {
+      (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
+      opc, "\tp$cop, cr$CRd, [$base], \\{$option\\}"> {
     let Inst{31-28} = op31_28;
     let Inst{24} = 0; // P = 0
     let Inst{23} = 1; // U = 1
@@ -3450,7 +3479,7 @@ multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
 
   def L_PRE : ACI<(outs),
       (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
-      !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
+      !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> {
     let Inst{31-28} = op31_28;
     let Inst{24} = 1; // P = 1
     let Inst{21} = 1; // W = 1
@@ -3459,8 +3488,8 @@ multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
   }
 
   def L_POST : ACI<(outs),
-      (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
-      !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
+      (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
+      !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr", IndexModePost> {
     let Inst{31-28} = op31_28;
     let Inst{24} = 0; // P = 0
     let Inst{21} = 1; // W = 1
@@ -3470,7 +3499,7 @@ multiclass LdStCop<bits<4> op31_28, bit load, string opc> {
 
   def L_OPTION : ACI<(outs),
       (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, nohash_imm:$option),
-      !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $option"> {
+      !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], \\{$option\\}"> {
     let Inst{31-28} = op31_28;
     let Inst{24} = 0; // P = 0
     let Inst{23} = 1; // U = 1
Modified: lib/Target/ARM/ARMInstrNEON.td
===================================================================
--- a/lib/Target/ARM/ARMInstrNEON.td
+++ b/lib/Target/ARM/ARMInstrNEON.td
@@ -80,6 +80,12 @@ def SDTARMVORRIMM : SDTypeProfile<1, 2, [SDTCisVec<0>, \
SDTCisSameAs<0, 1>,  def NEONvorrImm   : SDNode<"ARMISD::VORRIMM", SDTARMVORRIMM>;
 def NEONvbicImm   : SDNode<"ARMISD::VBICIMM", SDTARMVORRIMM>;
 
+def NEONvbsl      : SDNode<"ARMISD::VBSL",
+                           SDTypeProfile<1, 3, [SDTCisVec<0>,
+                                                SDTCisSameAs<0, 1>,
+                                                SDTCisSameAs<0, 2>,
+                                                SDTCisSameAs<0, 3>]>>;
+
 def NEONvdup      : SDNode<"ARMISD::VDUP", SDTypeProfile<1, 1, [SDTCisVec<0>]>>;
 
 // VDUPLANE can produce a quad-register result from a double-register source,
@@ -146,10 +152,6 @@ def VLDMQIA
   : PseudoVFPLdStM<(outs QPR:$dst), (ins GPR:$Rn),
                     IIC_fpLoad_m, "",
                    [(set QPR:$dst, (v2f64 (load GPR:$Rn)))]>;
-def VLDMQDB
-  : PseudoVFPLdStM<(outs QPR:$dst), (ins GPR:$Rn),
-                    IIC_fpLoad_m, "",
-                   [(set QPR:$dst, (v2f64 (load GPR:$Rn)))]>;
 
 // Use VSTM to store a Q register as a D register pair.
 // This is a pseudo instruction that is expanded to VSTMD after reg alloc.
@@ -157,10 +159,6 @@ def VSTMQIA
   : PseudoVFPLdStM<(outs), (ins QPR:$src, GPR:$Rn),
                     IIC_fpStore_m, "",
                    [(store (v2f64 QPR:$src), GPR:$Rn)]>;
-def VSTMQDB
-  : PseudoVFPLdStM<(outs), (ins QPR:$src, GPR:$Rn),
-                    IIC_fpStore_m, "",
-                   [(store (v2f64 QPR:$src), GPR:$Rn)]>;
 
 // Classes for VLD* pseudo-instructions with multi-register operands.
 // These are expanded to real instructions after register allocation.
@@ -1801,7 +1799,7 @@ class N3VDX<bit op24, bit op23, bits<2> op21_20, bits<4> \
op11_8, bit op4,  class N3VDSL<bits<2> op21_20, bits<4> op11_8,
              InstrItinClass itin, string OpcodeStr, string Dt,
              ValueType Ty, SDNode ShOp>
-  : N3V<0, 1, op21_20, op11_8, 1, 0,
+  : N3VLane32<0, 1, op21_20, op11_8, 1, 0,
         (outs DPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set (Ty DPR:$Vd),
@@ -1811,7 +1809,7 @@ class N3VDSL<bits<2> op21_20, bits<4> op11_8,
 }
 class N3VDSL16<bits<2> op21_20, bits<4> op11_8,
                string OpcodeStr, string Dt, ValueType Ty, SDNode ShOp>
-  : N3V<0, 1, op21_20, op11_8, 1, 0,
+  : N3VLane16<0, 1, op21_20, op11_8, 1, 0,
         (outs DPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, IIC_VMULi16D, OpcodeStr, Dt,"$Vd, $Vn, $Vm[$lane]","",
         [(set (Ty DPR:$Vd),
@@ -1841,7 +1839,7 @@ class N3VQX<bit op24, bit op23, bits<2> op21_20, bits<4> \
op11_8, bit op4,  class N3VQSL<bits<2> op21_20, bits<4> op11_8,
              InstrItinClass itin, string OpcodeStr, string Dt,
              ValueType ResTy, ValueType OpTy, SDNode ShOp>
-  : N3V<1, 1, op21_20, op11_8, 1, 0,
+  : N3VLane32<1, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd), (ins QPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set (ResTy QPR:$Vd),
@@ -1852,7 +1850,7 @@ class N3VQSL<bits<2> op21_20, bits<4> op11_8,
 }
 class N3VQSL16<bits<2> op21_20, bits<4> op11_8, string OpcodeStr, string Dt,
                ValueType ResTy, ValueType OpTy, SDNode ShOp>
-  : N3V<1, 1, op21_20, op11_8, 1, 0,
+  : N3VLane16<1, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd), (ins QPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, IIC_VMULi16Q, OpcodeStr, Dt,"$Vd, $Vn, $Vm[$lane]","",
         [(set (ResTy QPR:$Vd),
@@ -1874,7 +1872,7 @@ class N3VDInt<bit op24, bit op23, bits<2> op21_20, bits<4> \
op11_8, bit op4,  }
 class N3VDIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
                 string OpcodeStr, string Dt, ValueType Ty, Intrinsic IntOp>
-  : N3V<0, 1, op21_20, op11_8, 1, 0,
+  : N3VLane32<0, 1, op21_20, op11_8, 1, 0,
         (outs DPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set (Ty DPR:$Vd),
@@ -1885,7 +1883,7 @@ class N3VDIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass \
itin,  }
 class N3VDIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
                   string OpcodeStr, string Dt, ValueType Ty, Intrinsic IntOp>
-  : N3V<0, 1, op21_20, op11_8, 1, 0,
+  : N3VLane16<0, 1, op21_20, op11_8, 1, 0,
         (outs DPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set (Ty DPR:$Vd),
@@ -1915,7 +1913,7 @@ class N3VQInt<bit op24, bit op23, bits<2> op21_20, bits<4> \
op11_8, bit op4,  class N3VQIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass \
itin,  string OpcodeStr, string Dt,
                 ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
-  : N3V<1, 1, op21_20, op11_8, 1, 0,
+  : N3VLane32<1, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd), (ins QPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set (ResTy QPR:$Vd),
@@ -1927,7 +1925,7 @@ class N3VQIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass \
itin,  class N3VQIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
                   string OpcodeStr, string Dt,
                   ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
-  : N3V<1, 1, op21_20, op11_8, 1, 0,
+  : N3VLane16<1, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd), (ins QPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set (ResTy QPR:$Vd),
@@ -1959,7 +1957,7 @@ class N3VDMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> \
op11_8, bit op4,  class N3VDMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass \
itin,  string OpcodeStr, string Dt,
                   ValueType Ty, SDPatternOperator MulOp, SDPatternOperator ShOp>
-  : N3V<0, 1, op21_20, op11_8, 1, 0,
+  : N3VLane32<0, 1, op21_20, op11_8, 1, 0,
         (outs DPR:$Vd),
         (ins DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin,
@@ -1972,7 +1970,7 @@ class N3VDMulOpSL<bits<2> op21_20, bits<4> op11_8, \
InstrItinClass itin,  class N3VDMulOpSL16<bits<2> op21_20, bits<4> op11_8, \
InstrItinClass itin,  string OpcodeStr, string Dt,
                     ValueType Ty, SDNode MulOp, SDNode ShOp>
-  : N3V<0, 1, op21_20, op11_8, 1, 0,
+  : N3VLane16<0, 1, op21_20, op11_8, 1, 0,
         (outs DPR:$Vd),
         (ins DPR:$src1, DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin,
@@ -1994,7 +1992,7 @@ class N3VQMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> \
op11_8, bit op4,  class N3VQMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass \
                itin,
                   string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
                   SDPatternOperator MulOp, SDPatternOperator ShOp>
-  : N3V<1, 1, op21_20, op11_8, 1, 0,
+  : N3VLane32<1, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd),
         (ins QPR:$src1, QPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin,
@@ -2008,7 +2006,7 @@ class N3VQMulOpSL16<bits<2> op21_20, bits<4> op11_8, \
InstrItinClass itin,  string OpcodeStr, string Dt,
                     ValueType ResTy, ValueType OpTy,
                     SDNode MulOp, SDNode ShOp>
-  : N3V<1, 1, op21_20, op11_8, 1, 0,
+  : N3VLane16<1, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd),
         (ins QPR:$src1, QPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin,
@@ -2069,7 +2067,7 @@ class N3VLMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> \
op11_8, bit op4,  class N3VLMulOpSL<bit op24, bits<2> op21_20, bits<4> op11_8,
                   InstrItinClass itin, string OpcodeStr, string Dt,
                   ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode>
-  : N3V<op24, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd),
+  : N3VLane32<op24, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd),
         (ins QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin,
         OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "$src1 = $Vd",
@@ -2081,7 +2079,7 @@ class N3VLMulOpSL<bit op24, bits<2> op21_20, bits<4> op11_8,
 class N3VLMulOpSL16<bit op24, bits<2> op21_20, bits<4> op11_8,
                     InstrItinClass itin, string OpcodeStr, string Dt,
                     ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode>
-  : N3V<op24, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd),
+  : N3VLane16<op24, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd),
         (ins QPR:$src1, DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin,
         OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "$src1 = $Vd",
@@ -2116,7 +2114,7 @@ class N3VLInt3<bit op24, bit op23, bits<2> op21_20, bits<4> \
op11_8, bit op4,  class N3VLInt3SL<bit op24, bits<2> op21_20, bits<4> op11_8, \
InstrItinClass itin,  string OpcodeStr, string Dt,
                  ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
-  : N3V<op24, 1, op21_20, op11_8, 1, 0,
+  : N3VLane32<op24, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd),
         (ins QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin,
@@ -2129,7 +2127,7 @@ class N3VLInt3SL<bit op24, bits<2> op21_20, bits<4> op11_8, \
InstrItinClass itin,  class N3VLInt3SL16<bit op24, bits<2> op21_20, bits<4> op11_8,
                    InstrItinClass itin, string OpcodeStr, string Dt,
                    ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
-  : N3V<op24, 1, op21_20, op11_8, 1, 0,
+  : N3VLane16<op24, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd),
         (ins QPR:$src1, DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin,
@@ -2164,7 +2162,7 @@ class N3VL<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, \
bit op4,  class N3VLSL<bit op24, bits<2> op21_20, bits<4> op11_8,
              InstrItinClass itin, string OpcodeStr, string Dt,
              ValueType TyQ, ValueType TyD, SDNode OpNode>
-  : N3V<op24, 1, op21_20, op11_8, 1, 0,
+  : N3VLane32<op24, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set QPR:$Vd,
@@ -2173,7 +2171,7 @@ class N3VLSL<bit op24, bits<2> op21_20, bits<4> op11_8,
 class N3VLSL16<bit op24, bits<2> op21_20, bits<4> op11_8,
                InstrItinClass itin, string OpcodeStr, string Dt,
                ValueType TyQ, ValueType TyD, SDNode OpNode>
-  : N3V<op24, 1, op21_20, op11_8, 1, 0,
+  : N3VLane16<op24, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set QPR:$Vd,
@@ -2219,7 +2217,7 @@ class N3VLInt<bit op24, bit op23, bits<2> op21_20, bits<4> \
op11_8, bit op4,  class N3VLIntSL<bit op24, bits<2> op21_20, bits<4> op11_8, \
InstrItinClass itin,  string OpcodeStr, string Dt,
                 ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
-  : N3V<op24, 1, op21_20, op11_8, 1, 0,
+  : N3VLane32<op24, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set (ResTy QPR:$Vd),
@@ -2229,7 +2227,7 @@ class N3VLIntSL<bit op24, bits<2> op21_20, bits<4> op11_8, \
InstrItinClass itin,  class N3VLIntSL16<bit op24, bits<2> op21_20, bits<4> op11_8,
                   InstrItinClass itin, string OpcodeStr, string Dt,
                   ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
-  : N3V<op24, 1, op21_20, op11_8, 1, 0,
+  : N3VLane16<op24, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, nohash_imm:$lane),
         NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm[$lane]", "",
         [(set (ResTy QPR:$Vd),
@@ -3775,16 +3773,21 @@ def  VBSLd    : N3VX<1, 0, 0b01, 0b0001, 0, 1, (outs \
DPR:$Vd),  (ins DPR:$src1, DPR:$Vn, DPR:$Vm),
                      N3RegFrm, IIC_VCNTiD,
                      "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd",
-                     [(set DPR:$Vd,
-                       (v2i32 (or (and DPR:$Vn, DPR:$src1),
-                                  (and DPR:$Vm, (vnotd DPR:$src1)))))]>;
+                     [(set DPR:$Vd, (v2i32 (NEONvbsl DPR:$src1, DPR:$Vn, \
DPR:$Vm)))]>; +
+def : Pat<(v2i32 (or (and DPR:$Vn, DPR:$Vd),
+                     (and DPR:$Vm, (vnotd DPR:$Vd)))),
+          (VBSLd DPR:$Vd, DPR:$Vn, DPR:$Vm)>;
+
 def  VBSLq    : N3VX<1, 0, 0b01, 0b0001, 1, 1, (outs QPR:$Vd),
                      (ins QPR:$src1, QPR:$Vn, QPR:$Vm),
                      N3RegFrm, IIC_VCNTiQ,
                      "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd",
-                     [(set QPR:$Vd,
-                       (v4i32 (or (and QPR:$Vn, QPR:$src1),
-                                  (and QPR:$Vm, (vnotq QPR:$src1)))))]>;
+                     [(set QPR:$Vd, (v4i32 (NEONvbsl QPR:$src1, QPR:$Vn, \
QPR:$Vm)))]>; +
+def : Pat<(v4i32 (or (and QPR:$Vn, QPR:$Vd),
+                     (and QPR:$Vm, (vnotq QPR:$Vd)))),
+          (VBSLq QPR:$Vd, QPR:$Vn, QPR:$Vm)>;
 
 //   VBIF     : Vector Bitwise Insert if False
 //              like VBSL but with: "vbif $dst, $src3, $src1", "$src2 = $dst",
Modified: lib/Target/ARM/ARMInstrThumb2.td
===================================================================
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -145,6 +145,15 @@ def t2addrmode_so_reg : Operand<i32>,
   let ParserMatchClass = MemMode5AsmOperand;
 }
 
+// t2addrmode_reg := reg
+// Used by load/store exclusive instructions. Useful to enable right assembly
+// parsing and printing. Not used for any codegen matching.
+//
+def t2addrmode_reg : Operand<i32> {
+  let PrintMethod = "printAddrMode7Operand";
+  let MIOperandInfo = (ops tGPR);
+  let ParserMatchClass = MemMode7AsmOperand;
+}
 
 //===----------------------------------------------------------------------===//
 // Multiclass helpers...
@@ -2821,9 +2830,9 @@ class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, \
SizeFlagVal sz,  let Inst{5-4} = opcod;
   let Inst{3-0} = 0b1111;
 
-  bits<4> Rn;
+  bits<4> addr;
   bits<4> Rt;
-  let Inst{19-16} = Rn;
+  let Inst{19-16} = addr;
   let Inst{15-12} = Rt;
 }
 class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
@@ -2837,37 +2846,37 @@ class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode \
am, SizeFlagVal sz,  let Inst{5-4} = opcod;
 
   bits<4> Rd;
-  bits<4> Rn;
+  bits<4> addr;
   bits<4> Rt;
-  let Inst{11-8}  = Rd;
-  let Inst{19-16} = Rn;
+  let Inst{3-0}  = Rd;
+  let Inst{19-16} = addr;
   let Inst{15-12} = Rt;
 }
 
 let mayLoad = 1 in {
-def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
-                         Size4Bytes, NoItinerary, "ldrexb", "\t$Rt, [$Rn]",
+def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$Rt), (ins t2addrmode_reg:$addr), \
AddrModeNone, +                         Size4Bytes, NoItinerary, "ldrexb", "\t$Rt, \
$addr",  "", []>;
-def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
-                         Size4Bytes, NoItinerary, "ldrexh", "\t$Rt, [$Rn]",
+def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$Rt), (ins t2addrmode_reg:$addr), \
AddrModeNone, +                         Size4Bytes, NoItinerary, "ldrexh", "\t$Rt, \
$addr",  "", []>;
-def t2LDREX  : Thumb2I<(outs rGPR:$Rt), (ins rGPR:$Rn), AddrModeNone,
+def t2LDREX  : Thumb2I<(outs rGPR:$Rt), (ins t2addrmode_reg:$addr), AddrModeNone,
                        Size4Bytes, NoItinerary,
-                       "ldrex", "\t$Rt, [$Rn]", "",
+                       "ldrex", "\t$Rt, $addr", "",
                       []> {
   let Inst{31-27} = 0b11101;
   let Inst{26-20} = 0b0000101;
   let Inst{11-8} = 0b1111;
   let Inst{7-0} = 0b00000000; // imm8 = 0
 
-  bits<4> Rn;
   bits<4> Rt;
-  let Inst{19-16} = Rn;
+  bits<4> addr;
+  let Inst{19-16} = addr;
   let Inst{15-12} = Rt;
 }
-def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$Rt, rGPR:$Rt2), (ins rGPR:$Rn),
+def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$Rt, rGPR:$Rt2), (ins \
t2addrmode_reg:$addr),  AddrModeNone, Size4Bytes, NoItinerary,
-                         "ldrexd", "\t$Rt, $Rt2, [$Rn]", "",
+                         "ldrexd", "\t$Rt, $Rt2, $addr", "",
                          [], {?, ?, ?, ?}> {
   bits<4> Rt2;
   let Inst{11-8} = Rt2;
@@ -2875,31 +2884,31 @@ def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$Rt, rGPR:$Rt2), \
(ins rGPR:$Rn),  }
 
 let mayStore = 1, Constraints = "@earlyclobber $Rd" in {
-def t2STREXB : T2I_strex<0b00, (outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
-                         AddrModeNone, Size4Bytes, NoItinerary,
-                         "strexb", "\t$Rd, $Rt, [$Rn]", "", []>;
-def t2STREXH : T2I_strex<0b01, (outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
-                         AddrModeNone, Size4Bytes, NoItinerary,
-                         "strexh", "\t$Rd, $Rt, [$Rn]", "", []>;
-def t2STREX  : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rn),
-                       AddrModeNone, Size4Bytes, NoItinerary,
-                       "strex", "\t$Rd, $Rt, [$Rn]", "",
-                      []> {
+def t2STREXB : T2I_strex<0b00, (outs rGPR:$Rd), (ins rGPR:$Rt, \
t2addrmode_reg:$addr), +                  AddrModeNone, Size4Bytes, NoItinerary,
+                  "strexb", "\t$Rd, $Rt, $addr", "", []>;
+def t2STREXH : T2I_strex<0b01, (outs rGPR:$Rd), (ins rGPR:$Rt, \
t2addrmode_reg:$addr), +                  AddrModeNone, Size4Bytes, NoItinerary,
+                  "strexh", "\t$Rd, $Rt, $addr", "", []>;
+def t2STREX  : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt, t2addrmode_reg:$addr),
+                  AddrModeNone, Size4Bytes, NoItinerary,
+                  "strex", "\t$Rd, $Rt, $addr", "",
+                  []> {
   let Inst{31-27} = 0b11101;
   let Inst{26-20} = 0b0000100;
   let Inst{7-0} = 0b00000000; // imm8 = 0
 
   bits<4> Rd;
-  bits<4> Rn;
+  bits<4> addr;
   bits<4> Rt;
   let Inst{11-8}  = Rd;
-  let Inst{19-16} = Rn;
+  let Inst{19-16} = addr;
   let Inst{15-12} = Rt;
 }
 def t2STREXD : T2I_strex<0b11, (outs rGPR:$Rd),
-                         (ins rGPR:$Rt, rGPR:$Rt2, rGPR:$Rn),
+                         (ins rGPR:$Rt, rGPR:$Rt2, t2addrmode_reg:$addr),
                          AddrModeNone, Size4Bytes, NoItinerary,
-                         "strexd", "\t$Rd, $Rt, $Rt2, [$Rn]", "", [],
+                         "strexd", "\t$Rd, $Rt, $Rt2, $addr", "", [],
                          {?, ?, ?, ?}> {
   bits<4> Rt2;
   let Inst{11-8} = Rt2;
Modified: lib/Target/ARM/ARMInstrVFP.td
===================================================================
--- a/lib/Target/ARM/ARMInstrVFP.td
+++ b/lib/Target/ARM/ARMInstrVFP.td
@@ -101,14 +101,6 @@ multiclass vfp_ldst_mult<string asm, bit L_bit,
     let Inst{21}    = 1;          // Writeback
     let Inst{20}    = L_bit;
   }
-  def DDB :
-    AXDI4<(outs), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops),
-          IndexModeNone, itin,
-          !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
-    let Inst{24-23} = 0b10;       // Decrement Before
-    let Inst{21}    = 0;          // No writeback
-    let Inst{20}    = L_bit;
-  }
   def DDB_UPD :
     AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops),
           IndexModeUpd, itin_upd,
@@ -143,18 +135,6 @@ multiclass vfp_ldst_mult<string asm, bit L_bit,
     // VFP pipelines.
     let D = VFPNeonDomain;
   }
-  def SDB :
-    AXSI4<(outs), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, variable_ops),
-          IndexModeNone, itin,
-          !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
-    let Inst{24-23} = 0b10;       // Decrement Before
-    let Inst{21}    = 0;          // No writeback
-    let Inst{20}    = L_bit;
-
-    // Some single precision VFP instructions may be executed on both NEON and
-    // VFP pipelines.
-    let D = VFPNeonDomain;
-  }
   def SDB_UPD :
     AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, variable_ops),
           IndexModeUpd, itin_upd,
Modified: lib/Target/ARM/ARMLoadStoreOptimizer.cpp
===================================================================
--- a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
+++ b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -79,7 +79,7 @@ namespace {
       unsigned Position;
       MachineBasicBlock::iterator MBBI;
       bool Merged;
-      MemOpQueueEntry(int o, unsigned r, bool k, unsigned p, 
+      MemOpQueueEntry(int o, unsigned r, bool k, unsigned p,
                       MachineBasicBlock::iterator i)
         : Offset(o), Reg(r), isKill(k), Position(p), MBBI(i), Merged(false) {}
     };
@@ -174,7 +174,7 @@ static int getLoadStoreMultipleOpcode(int Opcode, \
ARM_AM::AMSubMode Mode) {  switch (Mode) {
     default: llvm_unreachable("Unhandled submode!");
     case ARM_AM::ia: return ARM::VLDMSIA;
-    case ARM_AM::db: return ARM::VLDMSDB;
+    case ARM_AM::db: return 0; // Only VLDMSDB_UPD exists.
     }
     break;
   case ARM::VSTRS:
@@ -182,7 +182,7 @@ static int getLoadStoreMultipleOpcode(int Opcode, \
ARM_AM::AMSubMode Mode) {  switch (Mode) {
     default: llvm_unreachable("Unhandled submode!");
     case ARM_AM::ia: return ARM::VSTMSIA;
-    case ARM_AM::db: return ARM::VSTMSDB;
+    case ARM_AM::db: return 0; // Only VSTMSDB_UPD exists.
     }
     break;
   case ARM::VLDRD:
@@ -190,7 +190,7 @@ static int getLoadStoreMultipleOpcode(int Opcode, \
ARM_AM::AMSubMode Mode) {  switch (Mode) {
     default: llvm_unreachable("Unhandled submode!");
     case ARM_AM::ia: return ARM::VLDMDIA;
-    case ARM_AM::db: return ARM::VLDMDDB;
+    case ARM_AM::db: return 0; // Only VLDMDDB_UPD exists.
     }
     break;
   case ARM::VSTRD:
@@ -198,7 +198,7 @@ static int getLoadStoreMultipleOpcode(int Opcode, \
ARM_AM::AMSubMode Mode) {  switch (Mode) {
     default: llvm_unreachable("Unhandled submode!");
     case ARM_AM::ia: return ARM::VSTMDIA;
-    case ARM_AM::db: return ARM::VSTMDDB;
+    case ARM_AM::db: return 0; // Only VSTMDDB_UPD exists.
     }
     break;
   }
@@ -246,13 +246,9 @@ AMSubMode getLoadStoreMultipleSubMode(int Opcode) {
   case ARM::t2LDMDB_UPD:
   case ARM::t2STMDB:
   case ARM::t2STMDB_UPD:
-  case ARM::VLDMSDB:
   case ARM::VLDMSDB_UPD:
-  case ARM::VSTMSDB:
   case ARM::VSTMSDB_UPD:
-  case ARM::VLDMDDB:
   case ARM::VLDMDDB_UPD:
-  case ARM::VSTMDDB:
   case ARM::VSTMDDB_UPD:
     return ARM_AM::db;
 
@@ -312,6 +308,10 @@ ARMLoadStoreOpt::MergeOps(MachineBasicBlock &MBB,
     // VLDM/VSTM do not support DB mode without also updating the base reg.
     Mode = ARM_AM::db;
   else if (Offset != 0) {
+    // Check if this is a supported opcode before we insert instructions to
+    // calculate a new base register.
+    if (!getLoadStoreMultipleOpcode(Opcode, Mode)) return false;
+
     // If starting offset isn't zero, insert a MI to materialize a new base.
     // But only do so if it is cost effective, i.e. merging more than two
     // loads / stores.
@@ -354,6 +354,7 @@ ARMLoadStoreOpt::MergeOps(MachineBasicBlock &MBB,
   bool isDef = (isi32Load(Opcode) || Opcode == ARM::VLDRS ||
                 Opcode == ARM::VLDRD);
   Opcode = getLoadStoreMultipleOpcode(Opcode, Mode);
+  if (!Opcode) return false;
   MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(Opcode))
     .addReg(Base, getKillRegState(BaseKill))
     .addImm(Pred).addReg(PredReg);
@@ -567,14 +568,10 @@ static inline unsigned getLSMultipleTransferSize(MachineInstr \
*MI) {  case ARM::t2STMIA:
   case ARM::t2STMDB:
   case ARM::VLDMSIA:
-  case ARM::VLDMSDB:
   case ARM::VSTMSIA:
-  case ARM::VSTMSDB:
     return (MI->getNumOperands() - MI->getDesc().getNumOperands() + 1) * 4;
   case ARM::VLDMDIA:
-  case ARM::VLDMDDB:
   case ARM::VSTMDIA:
-  case ARM::VSTMDDB:
     return (MI->getNumOperands() - MI->getDesc().getNumOperands() + 1) * 8;
   }
 }
@@ -624,7 +621,6 @@ static unsigned getUpdatingLSMultipleOpcode(unsigned Opc,
     }
     break;
   case ARM::VLDMSIA:
-  case ARM::VLDMSDB:
     switch (Mode) {
     default: llvm_unreachable("Unhandled submode!");
     case ARM_AM::ia: return ARM::VLDMSIA_UPD;
@@ -632,7 +628,6 @@ static unsigned getUpdatingLSMultipleOpcode(unsigned Opc,
     }
     break;
   case ARM::VLDMDIA:
-  case ARM::VLDMDDB:
     switch (Mode) {
     default: llvm_unreachable("Unhandled submode!");
     case ARM_AM::ia: return ARM::VLDMDIA_UPD;
@@ -640,7 +635,6 @@ static unsigned getUpdatingLSMultipleOpcode(unsigned Opc,
     }
     break;
   case ARM::VSTMSIA:
-  case ARM::VSTMSDB:
     switch (Mode) {
     default: llvm_unreachable("Unhandled submode!");
     case ARM_AM::ia: return ARM::VSTMSIA_UPD;
@@ -648,7 +642,6 @@ static unsigned getUpdatingLSMultipleOpcode(unsigned Opc,
     }
     break;
   case ARM::VSTMDIA:
-  case ARM::VSTMDDB:
     switch (Mode) {
     default: llvm_unreachable("Unhandled submode!");
     case ARM_AM::ia: return ARM::VSTMDIA_UPD;
Modified: lib/Target/ARM/AsmParser/ARMAsmParser.cpp
===================================================================
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -48,7 +48,8 @@ class ARMAsmParser : public TargetAsmParser {
   bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
   bool TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
   bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
-  bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
+  bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &,
+                   ARMII::AddrMode AddrMode);
   bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
   bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
   const MCExpr *ApplyPrefixToExpr(const MCExpr *E,
@@ -95,6 +96,14 @@ class ARMAsmParser : public TargetAsmParser {
     SmallVectorImpl<MCParsedAsmOperand*>&);
   OperandMatchResultTy tryParseMSRMaskOperand(
     SmallVectorImpl<MCParsedAsmOperand*>&);
+  OperandMatchResultTy tryParseMemMode2Operand(
+    SmallVectorImpl<MCParsedAsmOperand*>&);
+
+  // Asm Match Converter Methods
+  bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
+                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
+  bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
+                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
 
 public:
   ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM)
@@ -172,6 +181,7 @@ class ARMOperand : public MCParsedAsmOperand {
 
     /// Combined record for all forms of ARM address expressions.
     struct {
+      ARMII::AddrMode AddrMode;
       unsigned BaseRegNum;
       union {
         unsigned RegNum;     ///< Offset register num, when OffsetIsReg.
@@ -293,7 +303,9 @@ public:
 
   /// @name Memory Operand Accessors
   /// @{
-
+  ARMII::AddrMode getMemAddrMode() const {
+    return Mem.AddrMode;
+  }
   unsigned getMemBaseRegNum() const {
     return Mem.BaseRegNum;
   }
@@ -338,6 +350,27 @@ public:
   bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
   bool isMemory() const { return Kind == Memory; }
   bool isShifter() const { return Kind == Shifter; }
+  bool isMemMode2() const {
+    if (getMemAddrMode() != ARMII::AddrMode2)
+      return false;
+
+    if (getMemOffsetIsReg())
+      return true;
+
+    if (getMemNegative() &&
+        !(getMemPostindexed() || getMemPreindexed()))
+      return false;
+
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
+    if (!CE) return false;
+    int64_t Value = CE->getValue();
+
+    // The offset must be in the range 0-4095 (imm12).
+    if (Value > 4095 || Value < -4095)
+      return false;
+
+    return true;
+  }
   bool isMemMode5() const {
     if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() ||
         getMemNegative())
@@ -350,6 +383,23 @@ public:
     int64_t Value = CE->getValue();
     return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
   }
+  bool isMemMode7() const {
+    if (!isMemory() ||
+        getMemPreindexed() ||
+        getMemPostindexed() ||
+        getMemOffsetIsReg() ||
+        getMemNegative() ||
+        getMemWriteback())
+      return false;
+
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
+    if (!CE) return false;
+
+    if (CE->getValue())
+      return false;
+
+    return true;
+  }
   bool isMemModeRegThumb() const {
     if (!isMemory() || !getMemOffsetIsReg() || getMemWriteback())
       return false;
@@ -438,6 +488,57 @@ public:
     Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
   }
 
+  void addMemMode7Operands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && isMemMode7() && "Invalid number of operands!");
+    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
+
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
+    (void)CE;
+    assert((CE || CE->getValue() == 0) &&
+           "No offset operand support in mode 7");
+  }
+
+  void addMemMode2Operands(MCInst &Inst, unsigned N) const {
+    assert(isMemMode2() && "Invalid mode or number of operands!");
+    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
+    unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
+
+    if (getMemOffsetIsReg()) {
+      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
+
+      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
+      ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift;
+      int64_t ShiftAmount = 0;
+
+      if (getMemOffsetRegShifted()) {
+        ShOpc = getMemShiftType();
+        const MCConstantExpr *CE =
+                   dyn_cast<MCConstantExpr>(getMemShiftAmount());
+        ShiftAmount = CE->getValue();
+      }
+
+      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount,
+                                           ShOpc, IdxMode)));
+      return;
+    }
+
+    // Create a operand placeholder to always yield the same number of operands.
+    Inst.addOperand(MCOperand::CreateReg(0));
+
+    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
+    // the difference?
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
+    assert(CE && "Non-constant mode 2 offset operand!");
+    int64_t Offset = CE->getValue();
+
+    if (Offset >= 0)
+      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add,
+                                           Offset, ARM_AM::no_shift, IdxMode)));
+    else
+      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub,
+                                          -Offset, ARM_AM::no_shift, IdxMode)));
+  }
+
   void addMemMode5Operands(MCInst &Inst, unsigned N) const {
     assert(N == 2 && isMemMode5() && "Invalid number of operands!");
 
@@ -572,9 +673,9 @@ public:
     return Op;
   }
 
-  static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg,
-                               const MCExpr *Offset, int OffsetRegNum,
-                               bool OffsetRegShifted,
+  static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum,
+                               bool OffsetIsReg, const MCExpr *Offset,
+                               int OffsetRegNum, bool OffsetRegShifted,
                                enum ARM_AM::ShiftOpc ShiftType,
                                const MCExpr *ShiftAmount, bool Preindexed,
                                bool Postindexed, bool Negative, bool Writeback,
@@ -591,6 +692,7 @@ public:
            "Cannot have expression offset and register offset!");
 
     ARMOperand *Op = new ARMOperand(Memory);
+    Op->Mem.AddrMode = AddrMode;
     Op->Mem.BaseRegNum = BaseRegNum;
     Op->Mem.OffsetIsReg = OffsetIsReg;
     if (OffsetIsReg)
@@ -662,7 +764,8 @@ void ARMOperand::dump(raw_ostream &OS) const {
     break;
   case Memory:
     OS << "<memory "
-       << "base:" << getMemBaseRegNum();
+       << "am:" << ARMII::AddrModeToString(getMemAddrMode())
+       << " base:" << getMemBaseRegNum();
     if (getMemOffsetIsReg()) {
       OS << " offset:<register " << getMemOffsetRegNum();
       if (getMemOffsetRegShifted()) {
@@ -1105,13 +1208,57 @@ tryParseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> \
&Operands) {  return MatchOperand_Success;
 }
 
+/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand.
+ARMAsmParser::OperandMatchResultTy ARMAsmParser::
+tryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+  SMLoc S = Parser.getTok().getLoc();
+  const AsmToken &Tok = Parser.getTok();
+  assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\"");
+
+  if (ParseMemory(Operands, ARMII::AddrMode2))
+    return MatchOperand_NoMatch;
+
+  return MatchOperand_Success;
+}
+
+/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
+/// Needed here because the Asm Gen Matcher can't handle properly tied operands
+/// when they refer multiple MIOperands inside a single one.
+bool ARMAsmParser::
+CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
+                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
+
+  // Create a writeback register dummy placeholder.
+  Inst.addOperand(MCOperand::CreateImm(0));
+
+  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
+  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
+  return true;
+}
+
+/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
+/// Needed here because the Asm Gen Matcher can't handle properly tied operands
+/// when they refer multiple MIOperands inside a single one.
+bool ARMAsmParser::
+CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
+                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+  // Create a writeback register dummy placeholder.
+  Inst.addOperand(MCOperand::CreateImm(0));
+  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
+  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
+  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
+  return true;
+}
+
 /// Parse an ARM memory expression, return false if successful else return true
 /// or an error.  The first token must be a '[' when called.
 ///
 /// TODO Only preindexing and postindexing addressing are started, unindexed
 /// with option, etc are still to do.
 bool ARMAsmParser::
-ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+            ARMII::AddrMode AddrMode = ARMII::AddrModeNone) {
   SMLoc S, E;
   assert(Parser.getTok().is(AsmToken::LBrac) &&
          "Token is not a Left Bracket");
@@ -1169,6 +1316,9 @@ ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
                                      ExclaimTok.getLoc());
       Writeback = true;
       Parser.Lex(); // Eat exclaim token
+    } else { // In addressing mode 2, pre-indexed mode always end with "!"
+      if (AddrMode == ARMII::AddrMode2)
+        Preindexed = false;
     }
   } else {
     // The "[Rn" we have so far was not followed by a comma.
@@ -1204,11 +1354,10 @@ ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
       Offset = MCConstantExpr::Create(0, getContext());
   }
 
-  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset,
-                                           OffsetRegNum, OffsetRegShifted,
-                                           ShiftType, ShiftAmount, Preindexed,
-                                           Postindexed, Negative, Writeback,
-                                           S, E));
+  Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg,
+                                     Offset, OffsetRegNum, OffsetRegShifted,
+                                     ShiftType, ShiftAmount, Preindexed,
+                                     Postindexed, Negative, Writeback, S, E));
   if (WBOp)
     Operands.push_back(WBOp);
 
Modified: lib/Target/ARM/Disassembler/ARMDisassembler.cpp
===================================================================
--- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -18,6 +18,7 @@
 #include "ARMDisassembler.h"
 #include "ARMDisassemblerCore.h"
 
+#include "llvm/ADT/OwningPtr.h"
 #include "llvm/MC/EDInstInfo.h"
 #include "llvm/MC/MCInst.h"
 #include "llvm/Target/TargetRegistry.h"
@@ -283,6 +284,24 @@ static unsigned T2Morph2LoadLiteral(unsigned Opcode) {
   }
 }
 
+// Helper function for special case handling of PLD (literal) and friends.
+// See A8.6.117 T1 & T2 and friends for why we morphed the opcode
+// before returning it.
+static unsigned T2Morph2PLDLiteral(unsigned Opcode) {
+  switch (Opcode) {
+  default:
+    return Opcode; // Return unmorphed opcode.
+
+  case ARM::t2PLDi8:   case ARM::t2PLDs:
+  case ARM::t2PLDWi12: case ARM::t2PLDWi8:
+  case ARM::t2PLDWs:
+    return ARM::t2PLDi12;
+
+  case ARM::t2PLIi8:   case ARM::t2PLIs:
+    return ARM::t2PLIi12;
+  }
+}
+
 /// decodeThumbSideEffect is a decorator function which can potentially twiddle
 /// the instruction or morph the returned opcode under Thumb2.
 ///
@@ -333,12 +352,27 @@ static unsigned decodeThumbSideEffect(bool IsThumb2, unsigned \
&insn) {  }
     // --------- Transform End Marker ---------
 
+    unsigned unmorphed = decodeThumbInstruction(insn);
+
     // See, for example, A6.3.7 Load word: Table A6-18 Load word.
     // See A8.6.57 T3, T4 & A8.6.60 T2 and friends for why we morphed the opcode
     // before returning it to our caller.
     if (op1 == 3 && slice(op2, 6, 5) == 0 && slice(op2, 0, 0) == 1
-        && slice(insn, 19, 16) == 15)
-      return T2Morph2LoadLiteral(decodeThumbInstruction(insn));
+        && slice(insn, 19, 16) == 15) {
+      unsigned morphed = T2Morph2LoadLiteral(unmorphed);
+      if (morphed != unmorphed)
+        return morphed;
+    }
+
+    // See, for example, A8.6.117 PLD,PLDW (immediate) T1 & T2, and friends for
+    // why we morphed the opcode before returning it to our caller.
+    if (slice(insn, 31, 25) == 0x7C && slice(insn, 15, 12) == 0xF
+        && slice(insn, 22, 22) == 0 && slice(insn, 20, 20) == 1
+        && slice(insn, 19, 16) == 15) {
+      unsigned morphed = T2Morph2PLDLiteral(unmorphed);
+      if (morphed != unmorphed)
+        return morphed;
+    }
 
     // One last check for NEON/VFP instructions.
     if ((op1 == 1 || op1 == 3) && slice(op2, 6, 6) == 1)
@@ -384,15 +418,13 @@ bool ARMDisassembler::getInstruction(MCInst &MI,
       showBitVector(errs(), insn);
     });
 
-  ARMBasicMCBuilder *Builder = CreateMCBuilder(Opcode, Format);
+  OwningPtr<ARMBasicMCBuilder> Builder(CreateMCBuilder(Opcode, Format));
   if (!Builder)
     return false;
 
   if (!Builder->Build(MI, insn))
     return false;
 
-  delete Builder;
-
   return true;
 }
 
@@ -466,7 +498,7 @@ bool ThumbDisassembler::getInstruction(MCInst &MI,
       showBitVector(errs(), insn);
     });
 
-  ARMBasicMCBuilder *Builder = CreateMCBuilder(Opcode, Format);
+  OwningPtr<ARMBasicMCBuilder> Builder(CreateMCBuilder(Opcode, Format));
   if (!Builder)
     return false;
 
@@ -475,8 +507,6 @@ bool ThumbDisassembler::getInstruction(MCInst &MI,
   if (!Builder->Build(MI, insn))
     return false;
 
-  delete Builder;
-
   return true;
 }
 
Modified: lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
===================================================================
--- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
@@ -643,8 +643,11 @@ static bool DisassembleCoprocessor(MCInst &MI, unsigned Opcode, \
uint32_t insn,  if (PW) {
       MI.addOperand(MCOperand::CreateReg(0));
       ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub;
+      const TargetInstrDesc &TID = ARMInsts[Opcode];
+      unsigned IndexMode =
+                  (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
       unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, slice(insn, 7, 0) << 2,
-                                          ARM_AM::no_shift);
+                                          ARM_AM::no_shift, IndexMode);
       MI.addOperand(MCOperand::CreateImm(Offset));
       OpIdx = 5;
     } else {
@@ -1073,6 +1076,8 @@ static bool DisassembleLdStFrm(MCInst &MI, unsigned Opcode, \
uint32_t insn,  return false;
 
   ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub;
+  unsigned IndexMode =
+               (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
   if (getIBit(insn) == 0) {
     // For pre- and post-indexed case, add a reg0 operand (Addressing Mode #2).
     // Otherwise, skip the reg operand since for addrmode_imm12, Rn has already
@@ -1084,7 +1089,8 @@ static bool DisassembleLdStFrm(MCInst &MI, unsigned Opcode, \
uint32_t insn,  
     // Disassemble the 12-bit immediate offset.
     unsigned Imm12 = slice(insn, 11, 0);
-    unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift);
+    unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift,
+                                        IndexMode);
     MI.addOperand(MCOperand::CreateImm(Offset));
     OpIdx += 1;
   } else {
@@ -1099,7 +1105,7 @@ static bool DisassembleLdStFrm(MCInst &MI, unsigned Opcode, \
uint32_t insn,  // A8.4.1.  Possible rrx or shift amount of 32...
     getImmShiftSE(ShOp, ShImm);
     MI.addOperand(MCOperand::CreateImm(
-                    ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp)));
+                    ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp, IndexMode)));
     OpIdx += 2;
   }
 
@@ -1123,7 +1129,7 @@ static bool HasDualReg(unsigned Opcode) {
   case ARM::LDRD: case ARM::LDRD_PRE: case ARM::LDRD_POST:
   case ARM::STRD: case ARM::STRD_PRE: case ARM::STRD_POST:
     return true;
-  }  
+  }
 }
 
 static bool DisassembleLdStMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
@@ -1610,7 +1616,7 @@ static bool DisassembleVFPBinaryFrm(MCInst &MI, unsigned \
Opcode, uint32_t insn,  // A8.6.295 vcvt (floating-point <-> integer)
 // Int to FP: VSITOD, VSITOS, VUITOD, VUITOS
 // FP to Int: VTOSI[Z|R]D, VTOSI[Z|R]S, VTOUI[Z|R]D, VTOUI[Z|R]S
-// 
+//
 // A8.6.297 vcvt (floating-point and fixed-point)
 // Dd|Sd Dd|Sd(TIED_TO) #fbits(= 16|32 - UInt(imm4:i))
 static bool DisassembleVFPConv1Frm(MCInst &MI, unsigned Opcode, uint32_t insn,
@@ -1832,9 +1838,9 @@ static bool DisassembleVFPLdStMulFrm(MCInst &MI, unsigned \
Opcode, uint32_t insn,  
   OpIdx += 3;
 
-  bool isSPVFP = (Opcode == ARM::VLDMSIA     || Opcode == ARM::VLDMSDB     ||
+  bool isSPVFP = (Opcode == ARM::VLDMSIA     ||
                   Opcode == ARM::VLDMSIA_UPD || Opcode == ARM::VLDMSDB_UPD ||
-                  Opcode == ARM::VSTMSIA     || Opcode == ARM::VSTMSDB     ||
+                  Opcode == ARM::VSTMSIA     ||
                   Opcode == ARM::VSTMSIA_UPD || Opcode == ARM::VSTMSDB_UPD);
   unsigned RegClassID = isSPVFP ? ARM::SPRRegClassID : ARM::DPRRegClassID;
 
@@ -1848,7 +1854,7 @@ static bool DisassembleVFPLdStMulFrm(MCInst &MI, unsigned \
Opcode, uint32_t insn,  // Apply some sanity checks before proceeding.
   if (Regs == 0 || (RegD + Regs) > 32 || (!isSPVFP && Regs > 16))
     return false;
-  
+
   for (unsigned i = 0; i < Regs; ++i) {
     MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassID,
                                                        RegD + i)));
@@ -2286,15 +2292,15 @@ static bool DisassembleNLdSt(MCInst &MI, unsigned Opcode, \
uint32_t insn,  // n == 2 && type == 0b1001 -> DblSpaced = true
     if (Name.startswith("VST2") || Name.startswith("VLD2"))
       DblSpaced = slice(insn, 11, 8) == 9;
-    
+
     // n == 3 && type == 0b0101 -> DblSpaced = true
     if (Name.startswith("VST3") || Name.startswith("VLD3"))
       DblSpaced = slice(insn, 11, 8) == 5;
-    
+
     // n == 4 && type == 0b0001 -> DblSpaced = true
     if (Name.startswith("VST4") || Name.startswith("VLD4"))
       DblSpaced = slice(insn, 11, 8) == 1;
-    
+
   }
   return DisassembleNLdSt0(MI, Opcode, insn, NumOps, NumOpsAdded,
                            slice(insn, 21, 21) == 0, DblSpaced, B);
@@ -2302,6 +2308,9 @@ static bool DisassembleNLdSt(MCInst &MI, unsigned Opcode, \
uint32_t insn,  
 // VMOV (immediate)
 //   Qd/Dd imm
+// VBIC (immediate)
+// VORR (immediate)
+//   Qd/Dd imm src(=Qd/Dd)
 static bool DisassembleN1RegModImmFrm(MCInst &MI, unsigned Opcode,
     uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
 
@@ -2328,12 +2337,20 @@ static bool DisassembleN1RegModImmFrm(MCInst &MI, unsigned \
Opcode,  case ARM::VMOVv8i16:
   case ARM::VMVNv4i16:
   case ARM::VMVNv8i16:
+  case ARM::VBICiv4i16:
+  case ARM::VBICiv8i16:
+  case ARM::VORRiv4i16:
+  case ARM::VORRiv8i16:
     esize = ESize16;
     break;
   case ARM::VMOVv2i32:
   case ARM::VMOVv4i32:
   case ARM::VMVNv2i32:
   case ARM::VMVNv4i32:
+  case ARM::VBICiv2i32:
+  case ARM::VBICiv4i32:
+  case ARM::VORRiv2i32:
+  case ARM::VORRiv4i32:
     esize = ESize32;
     break;
   case ARM::VMOVv1i64:
@@ -2341,7 +2358,7 @@ static bool DisassembleN1RegModImmFrm(MCInst &MI, unsigned \
Opcode,  esize = ESize64;
     break;
   default:
-    assert(0 && "Unreachable code!");
+    assert(0 && "Unexpected opcode!");
     return false;
   }
 
@@ -2350,6 +2367,16 @@ static bool DisassembleN1RegModImmFrm(MCInst &MI, unsigned \
Opcode,  MI.addOperand(MCOperand::CreateImm(decodeN1VImm(insn, esize)));
 
   NumOpsAdded = 2;
+
+  // VBIC/VORRiv*i* variants have an extra $src = $Vd to be filled in.
+  if (NumOps >= 3 &&
+      (OpInfo[2].RegClass == ARM::DPRRegClassID ||
+       OpInfo[2].RegClass == ARM::QPRRegClassID)) {
+    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[0].RegClass,
+                                                     decodeNEONRd(insn))));
+    NumOpsAdded += 1;
+  }
+
   return true;
 }
 
@@ -2370,7 +2397,7 @@ enum N2VFlag {
 //
 // Vector Move Long:
 //   Qd Dm
-// 
+//
 // Vector Move Narrow:
 //   Dd Qm
 //
@@ -2512,7 +2539,7 @@ static bool DisassembleNVectorShift(MCInst &MI, unsigned \
Opcode, uint32_t insn,  assert(OpInfo[OpIdx].RegClass < 0 && "Imm operand expected");
 
   // Add the imm operand.
-  
+
   // VSHLL has maximum shift count as the imm, inferred from its size.
   unsigned Imm;
   switch (Opcode) {
@@ -2625,7 +2652,7 @@ static bool DisassembleNVdVnVmOptImm(MCInst &MI, unsigned \
Opcode, uint32_t insn,  // N3RegFrm.
   if (Opcode == ARM::VMOVDneon || Opcode == ARM::VMOVQ)
     return true;
-  
+
   // Dm = Inst{5:3-0} => NEON Rm
   // or
   // Dm is restricted to D0-D7 if size is 16, D0-D15 otherwise
@@ -2872,8 +2899,8 @@ static bool DisassemblePreLoadFrm(MCInst &MI, unsigned Opcode, \
uint32_t insn,  unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
 
   // Preload Data/Instruction requires either 2 or 3 operands.
-  // PLDi, PLDWi, PLIi:                addrmode_imm12
-  // PLDr[a|m], PLDWr[a|m], PLIr[a|m]: ldst_so_reg
+  // PLDi12, PLDWi12, PLIi12: addrmode_imm12
+  // PLDrs, PLDWrs, PLIrs:    ldst_so_reg
 
   MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
                                                      decodeRn(insn))));
@@ -2882,10 +2909,19 @@ static bool DisassemblePreLoadFrm(MCInst &MI, unsigned \
Opcode, uint32_t insn,  || Opcode == ARM::PLIi12) {
     unsigned Imm12 = slice(insn, 11, 0);
     bool Negative = getUBit(insn) == 0;
+
+    // A8.6.118 PLD (literal) PLDWi12 with Rn=PC is transformed to PLDi12.
+    if (Opcode == ARM::PLDWi12 && slice(insn, 19, 16) == 0xF) {
+      DEBUG(errs() << "Rn == '1111': PLDWi12 morphed to PLDi12\n");
+      MI.setOpcode(ARM::PLDi12);
+    }
+    
     // -0 is represented specially. All other values are as normal.
+    int Offset = Negative ? -1 * Imm12 : Imm12;
     if (Imm12 == 0 && Negative)
-      Imm12 = INT32_MIN;
-    MI.addOperand(MCOperand::CreateImm(Imm12));
+      Offset = INT32_MIN;
+
+    MI.addOperand(MCOperand::CreateImm(Offset));
     NumOpsAdded = 2;
   } else {
     MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
@@ -2930,6 +2966,11 @@ static bool DisassembleMiscFrm(MCInst &MI, unsigned Opcode, \
uint32_t insn,  case ARM::WFI:
   case ARM::SEV:
     return true;
+  case ARM::SWP:
+  case ARM::SWPB:
+    // SWP, SWPB: Rd Rm Rn
+    // Delegate to DisassembleLdStExFrm()....
+    return DisassembleLdStExFrm(MI, Opcode, insn, NumOps, NumOpsAdded, B);
   default:
     break;
   }
@@ -2944,8 +2985,10 @@ static bool DisassembleMiscFrm(MCInst &MI, unsigned Opcode, \
uint32_t insn,  // opcodes which match the same real instruction. This is needed \
since there's  // no current handling of optional arguments. Fix here when a better \
handling  // of optional arguments is implemented.
-  if (Opcode == ARM::CPS3p) {
-    // Let's reject impossible imod values by returning false.
+  if (Opcode == ARM::CPS3p) {   // M = 1
+    // Let's reject these impossible imod values by returning false:
+    // 1. (imod=0b01)
+    //
     // AsmPrinter cannot handle imod=0b00, plus (imod=0b00,M=1,iflags!=0) is an
     // invalid combination, so we just check for imod=0b00 here.
     if (slice(insn, 19, 18) == 0 || slice(insn, 19, 18) == 1)
@@ -2956,13 +2999,18 @@ static bool DisassembleMiscFrm(MCInst &MI, unsigned Opcode, \
uint32_t insn,  NumOpsAdded = 3;
     return true;
   }
-  if (Opcode == ARM::CPS2p) {
+  if (Opcode == ARM::CPS2p) { // mode = 0, M = 0
+    // Let's reject these impossible imod values by returning false:
+    // 1. (imod=0b00,M=0)
+    // 2. (imod=0b01)
+    if (slice(insn, 19, 18) == 0 || slice(insn, 19, 18) == 1)
+      return false;
     MI.addOperand(MCOperand::CreateImm(slice(insn, 19, 18))); // imod
     MI.addOperand(MCOperand::CreateImm(slice(insn, 8, 6)));   // iflags
     NumOpsAdded = 2;
     return true;
   }
-  if (Opcode == ARM::CPS1p) {
+  if (Opcode == ARM::CPS1p) { // imod = 0, iflags = 0, M = 1
     MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0))); // mode
     NumOpsAdded = 1;
     return true;
@@ -3141,7 +3189,7 @@ bool ARMBasicMCBuilder::DoPredicateOperands(MCInst& MI, \
unsigned Opcode,  
   return false;
 }
-  
+
 /// TryPredicateAndSBitModifier - TryPredicateAndSBitModifier tries to process
 /// the possible Predicate and SBitModifier, to build the remaining MCOperand
 /// constituents.
Modified: lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
===================================================================
--- a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
+++ b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
@@ -1140,7 +1140,7 @@ static bool DisassembleThumb2LdStMul(MCInst &MI, unsigned \
Opcode, uint32_t insn,  Opcode == ARM::t2STMIA || Opcode == ARM::t2STMIA_UPD ||
           Opcode == ARM::t2STMDB || Opcode == ARM::t2STMDB_UPD)
          && "Unexpected opcode");
-  assert(NumOps >= 5 && "Thumb2 LdStMul expects NumOps >= 5");
+  assert(NumOps >= 4 && "Thumb2 LdStMul expects NumOps >= 4");
 
   NumOpsAdded = 0;
 
@@ -1194,8 +1194,8 @@ static bool DisassembleThumb2LdStEx(MCInst &MI, unsigned \
Opcode, uint32_t insn,  OpIdx = 0;
 
   assert(NumOps >= 2
-         && OpInfo[0].RegClass == ARM::GPRRegClassID
-         && OpInfo[1].RegClass == ARM::GPRRegClassID
+         && OpInfo[0].RegClass > 0
+         && OpInfo[1].RegClass > 0
          && "Expect >=2 operands and first two as reg operands");
 
   bool isStore = (ARM::t2STREX <= Opcode && Opcode <= ARM::t2STREXH);
@@ -1205,34 +1205,31 @@ static bool DisassembleThumb2LdStEx(MCInst &MI, unsigned \
Opcode, uint32_t insn,  // Add the destination operand for store.
   if (isStore) {
     MI.addOperand(MCOperand::CreateReg(
-                    getRegisterEnum(B, ARM::GPRRegClassID,
+                    getRegisterEnum(B, OpInfo[OpIdx].RegClass,
                                     isSW ? decodeRs(insn) : decodeRm(insn))));
     ++OpIdx;
   }
 
   // Source operand for store and destination operand for load.
-  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
                                                      decodeRd(insn))));
   ++OpIdx;
 
   // Thumb2 doubleword complication: with an extra source/destination operand.
   if (isDW) {
-    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
                                                        decodeRs(insn))));
     ++OpIdx;
   }
 
   // Finally add the pointer operand.
-  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
                                                      decodeRn(insn))));
   ++OpIdx;
 
   return true;
 }
 
-// LLVM, as of Jan-05-2010, does not output <Rt2>, i.e., Rs, in the asm.
-// Whereas the ARM Arch. Manual does not require that t2 = t+1 like in ARM ISA.
-//
 // t2LDRDi8: Rd Rs Rn imm8s4 (offset mode)
 // t2LDRDpci: Rd Rs imm8s4 (Not decoded, prefer the generic t2LDRDi8 version)
 // t2STRDi8: Rd Rs Rn imm8s4 (offset mode)
@@ -1246,18 +1243,21 @@ static bool DisassembleThumb2LdStDual(MCInst &MI, unsigned \
Opcode,  if (!OpInfo) return false;
 
   assert(NumOps >= 4
-         && OpInfo[0].RegClass == ARM::GPRRegClassID
-         && OpInfo[1].RegClass == ARM::GPRRegClassID
-         && OpInfo[2].RegClass == ARM::GPRRegClassID
+         && OpInfo[0].RegClass > 0
+         && OpInfo[0].RegClass == OpInfo[1].RegClass
+         && OpInfo[2].RegClass > 0
          && OpInfo[3].RegClass < 0
          && "Expect >= 4 operands and first 3 as reg operands");
 
   // Add the <Rt> <Rt2> operands.
-  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+  unsigned RegClassPair = OpInfo[0].RegClass;
+  unsigned RegClassBase = OpInfo[2].RegClass;
+  
+  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassPair,
                                                      decodeRd(insn))));
-  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassPair,
                                                      decodeRs(insn))));
-  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassBase,
                                                      decodeRn(insn))));
 
   // Finally add (+/-)imm8*4, depending on the U bit.
@@ -1786,7 +1786,7 @@ static bool DisassembleThumb2PreLoad(MCInst &MI, unsigned \
Opcode, uint32_t insn,  decodeRn(insn))));
   ++OpIdx;
 
-  if (OpInfo[OpIdx].RegClass == ARM::GPRRegClassID) {
+  if (OpInfo[OpIdx].RegClass == ARM::rGPRRegClassID) {
     MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
                                                        decodeRm(insn))));
   } else {
@@ -1794,17 +1794,17 @@ static bool DisassembleThumb2PreLoad(MCInst &MI, unsigned \
Opcode, uint32_t insn,  && !OpInfo[OpIdx].isOptionalDef()
            && "Pure imm operand expected");
     int Offset = 0;
-    if (slice(insn, 19, 16) == 0xFF) {
-      bool Negative = slice(insn, 23, 23) == 0;
-      unsigned Imm12 = getImm12(insn);
-      Offset = Negative ? -1 - Imm12 : 1 * Imm12;
-    } else if (Opcode == ARM::t2PLDi8 || Opcode == ARM::t2PLDWi8 ||
-               Opcode == ARM::t2PLIi8) {
+    if (Opcode == ARM::t2PLDi8 || Opcode == ARM::t2PLDWi8 ||
+        Opcode == ARM::t2PLIi8) {
       // A8.6.117 Encoding T2: add = FALSE
       unsigned Imm8 = getImm8(insn);
-      Offset = -1 - Imm8;
-    } else // The i12 forms.  See, for example, A8.6.117 Encoding T1.
+      Offset = -1 * Imm8;
+    } else {
+      // The i12 forms.  See, for example, A8.6.117 Encoding T1.
+      // Note that currently t2PLDi12 also handles the previously named t2PLDpci
+      // opcode, that's why we use decodeImm12(insn) which returns +/- imm12.
       Offset = decodeImm12(insn);
+    }
     MI.addOperand(MCOperand::CreateImm(Offset));
   }
   ++OpIdx;
@@ -1868,7 +1868,7 @@ static bool DisassembleThumb2LdSt(bool Load, MCInst &MI, \
unsigned Opcode,  OpInfo[1].RegClass == ARM::GPRRegClassID &&
          "Expect >= 3 operands and first two as reg operands");
 
-  bool ThreeReg = (OpInfo[2].RegClass == ARM::GPRRegClassID);
+  bool ThreeReg = (OpInfo[2].RegClass > 0);
   bool TIED_TO = ThreeReg && TID.getOperandConstraint(2, TOI::TIED_TO) != -1;
   bool Imm12 = !ThreeReg && slice(insn, 23, 23) == 1; // ARMInstrThumb2.td
 
@@ -1912,7 +1912,8 @@ static bool DisassembleThumb2LdSt(bool Load, MCInst &MI, \
unsigned Opcode,  ++OpIdx;
 
   if (ThreeReg) {
-    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+    // This could be an offset register or a TIED_TO register.
+    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
                                                        R2)));
     ++OpIdx;
   }
@@ -1946,25 +1947,25 @@ static bool DisassembleThumb2DPReg(MCInst &MI, unsigned \
Opcode, uint32_t insn,  OpIdx = 0;
 
   assert(NumOps >= 2 &&
-         OpInfo[0].RegClass == ARM::rGPRRegClassID &&
-         OpInfo[1].RegClass == ARM::rGPRRegClassID &&
+         OpInfo[0].RegClass > 0 &&
+         OpInfo[1].RegClass > 0 &&
          "Expect >= 2 operands and first two as reg operands");
 
   // Build the register operands, followed by the optional rotation amount.
 
-  bool ThreeReg = NumOps > 2 && OpInfo[2].RegClass == ARM::rGPRRegClassID;
+  bool ThreeReg = NumOps > 2 && OpInfo[2].RegClass > 0;
 
-  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
+  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
                                                      decodeRs(insn))));
   ++OpIdx;
 
   if (ThreeReg) {
-    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
+    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
                                                        decodeRn(insn))));
     ++OpIdx;
   }
 
-  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
+  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
                                                      decodeRm(insn))));
   ++OpIdx;
 
Modified: lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
===================================================================
--- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
+++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
@@ -181,18 +181,12 @@ void ARMInstPrinter::printSORegOperand(const MCInst *MI, \
unsigned OpNum,  }
 }
 
-
-void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
-                                           raw_ostream &O) {
+void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
+                                                raw_ostream &O) {
   const MCOperand &MO1 = MI->getOperand(Op);
   const MCOperand &MO2 = MI->getOperand(Op+1);
   const MCOperand &MO3 = MI->getOperand(Op+2);
 
-  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
-    printOperand(MI, Op, O);
-    return;
-  }
-
   O << "[" << getRegisterName(MO1.getReg());
 
   if (!MO2.getReg()) {
@@ -215,6 +209,50 @@ void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, \
unsigned Op,  O << "]";
 }
 
+void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op,
+                                         raw_ostream &O) {
+  const MCOperand &MO1 = MI->getOperand(Op);
+  const MCOperand &MO2 = MI->getOperand(Op+1);
+  const MCOperand &MO3 = MI->getOperand(Op+2);
+
+  O << "[" << getRegisterName(MO1.getReg()) << "], ";
+
+  if (!MO2.getReg()) {
+    unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm());
+    O << '#'
+      << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
+      << ImmOffs;
+    return;
+  }
+
+  O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
+    << getRegisterName(MO2.getReg());
+
+  if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
+    O << ", "
+    << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
+    << " #" << ShImm;
+}
+
+void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
+                                           raw_ostream &O) {
+  const MCOperand &MO1 = MI->getOperand(Op);
+
+  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
+    printOperand(MI, Op, O);
+    return;
+  }
+
+  const MCOperand &MO3 = MI->getOperand(Op+2);
+  unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm());
+
+  if (IdxMode == ARMII::IndexModePost) {
+    printAM2PostIndexOp(MI, Op, O);
+    return;
+  }
+  printAM2PreOrOffsetIndexOp(MI, Op, O);
+}
+
 void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
                                                  unsigned OpNum,
                                                  raw_ostream &O) {
@@ -317,6 +355,12 @@ void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, \
unsigned OpNum,  O << "]";
 }
 
+void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum,
+                                           raw_ostream &O) {
+  const MCOperand &MO1 = MI->getOperand(OpNum);
+  O << "[" << getRegisterName(MO1.getReg()) << "]";
+}
+
 void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI,
                                                  unsigned OpNum,
                                                  raw_ostream &O) {
Modified: lib/Target/ARM/InstPrinter/ARMInstPrinter.h
===================================================================
--- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
+++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
@@ -42,7 +42,11 @@ public:
   void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
 
   void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+
   void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+  void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+  void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum,
+                                  raw_ostream &O);
   void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum,
                                    raw_ostream &O);
   void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
@@ -51,6 +55,7 @@ public:
   void printLdStmModeOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
   void printAddrMode5Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
   void printAddrMode6Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+  void printAddrMode7Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
   void printAddrMode6OffsetOperand(const MCInst *MI, unsigned OpNum,
                                    raw_ostream &O);
 
Modified: lib/Target/CppBackend/CPPBackend.cpp
===================================================================
--- a/lib/Target/CppBackend/CPPBackend.cpp
+++ b/lib/Target/CppBackend/CPPBackend.cpp
@@ -1348,12 +1348,10 @@ void CppWriter::printInstruction(const Instruction *I,
     const PHINode* phi = cast<PHINode>(I);
 
     Out << "PHINode* " << iName << " = PHINode::Create("
-        << getCppName(phi->getType()) << ", \"";
+        << getCppName(phi->getType()) << ", \""
+        << phi->getNumIncomingValues() << ", \"";
     printEscapedString(phi->getName());
     Out << "\", " << bbname << ");";
-    nl(Out) << iName << "->reserveOperandSpace("
-      << phi->getNumIncomingValues()
-        << ");";
     nl(Out);
     for (unsigned i = 0; i < phi->getNumOperands(); i+=2) {
       Out << iName << "->addIncoming("
Modified: lib/Target/Mips/MipsISelLowering.cpp
===================================================================
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -197,7 +197,7 @@ unsigned MipsTargetLowering::getFunctionAlignment(const Function \
*) const {  //  multHi/Lo: product of multiplication
 //  Lo0: initial value of Lo register
 //  Hi0: initial value of Hi register
-// Return true if mattern matching was successful.
+// Return true if pattern matching was successful.
 static bool SelectMadd(SDNode* ADDENode, SelectionDAG* CurDAG) {
   // ADDENode's second operand must be a flag output of an ADDC node in order
   // for the matching to be successful.
@@ -271,7 +271,7 @@ static bool SelectMadd(SDNode* ADDENode, SelectionDAG* CurDAG) {
 //  multHi/Lo: product of multiplication
 //  Lo0: initial value of Lo register
 //  Hi0: initial value of Hi register
-// Return true if mattern matching was successful.
+// Return true if pattern matching was successful.
 static bool SelectMsub(SDNode* SUBENode, SelectionDAG* CurDAG) {
   // SUBENode's second operand must be a flag output of an SUBC node in order
   // for the matching to be successful.
Modified: lib/Target/PTX/PTXISelLowering.cpp
===================================================================
--- a/lib/Target/PTX/PTXISelLowering.cpp
+++ b/lib/Target/PTX/PTXISelLowering.cpp
@@ -56,8 +56,6 @@ SDValue PTXTargetLowering::LowerOperation(SDValue Op, SelectionDAG \
&DAG) const {  llvm_unreachable("Unimplemented operand");
     case ISD::GlobalAddress:
       return LowerGlobalAddress(Op, DAG);
-    case ISD::BRCOND:
-      return LowerGlobalAddress(Op, DAG);
   }
 }
 
Modified: lib/Target/PTX/PTXInstrInfo.cpp
===================================================================
--- a/lib/Target/PTX/PTXInstrInfo.cpp
+++ b/lib/Target/PTX/PTXInstrInfo.cpp
@@ -247,11 +247,15 @@ AnalyzeBranch(MachineBasicBlock &MBB,
 }
 
 unsigned PTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
-  unsigned count;
-  for (count = 0; IsAnyKindOfBranch(MBB.back()); ++count)
-    MBB.pop_back();
+  unsigned count = 0;
+  while (!MBB.empty())
+    if (IsAnyKindOfBranch(MBB.back())) {
+      MBB.pop_back();
+      ++count;
+    } else
+      break;
   DEBUG(dbgs() << "RemoveBranch: MBB:   " << MBB.getName().str() << "\n");
-  DEBUG(dbgs() << "RemoveBranch: count: " << count << "\n");
+  DEBUG(dbgs() << "RemoveBranch: remove " << count << " branch inst\n");
   return count;
 }
 
@@ -262,12 +266,12 @@ InsertBranch(MachineBasicBlock &MBB,
              const SmallVectorImpl<MachineOperand> &Cond,
              DebugLoc DL) const {
   DEBUG(dbgs() << "InsertBranch: MBB: " << MBB.getName().str() << "\n");
-  DEBUG(if (TBB) dbgs() << "InsertBranch: TBB: "
-                        << TBB->getName().str() << "\n";
-      else dbgs() << "InsertBranch: TBB: (NULL)\n");
-  DEBUG(if (FBB) dbgs() << "InsertBranch: FBB: "
-                        << FBB->getName().str() << "\n";
-      else dbgs() << "InsertBranch: FBB: (NULL)\n");
+  DEBUG(if (TBB) dbgs() << "InsertBranch: TBB: " << TBB->getName().str()
+                        << "\n";
+        else     dbgs() << "InsertBranch: TBB: (NULL)\n");
+  DEBUG(if (FBB) dbgs() << "InsertBranch: FBB: " << FBB->getName().str()
+                        << "\n";
+        else     dbgs() << "InsertBranch: FBB: (NULL)\n");
   DEBUG(dbgs() << "InsertBranch: Cond size: " << Cond.size() << "\n");
 
   assert(TBB && "TBB is NULL");
Modified: lib/Target/PTX/PTXInstrInfo.td
===================================================================
--- a/lib/Target/PTX/PTXInstrInfo.td
+++ b/lib/Target/PTX/PTXInstrInfo.td
@@ -618,12 +618,11 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
 }
 
 let isBranch = 1, isTerminator = 1 in {
-  // FIXME: should be able to write a pattern for brcond, but can't use
-  //        a two-value operand where a dag node expects two operands. :(
-  // NOTE: ARM & PowerPC backend also report the same problem
+  // FIXME: The pattern part is blank because I cannot (or do not yet know
+  // how to) use the first operand of PredicateOperand (a Preds register) here
   def BRAdp
     : InstPTX<(outs), (ins brtarget:$d), "bra\t$d",
-              [/*(brcond bb:$d, Preds:$p, i32imm:$c)*/]>;
+              [/*(brcond pred:$_p, bb:$d)*/]>;
 }
 
 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
Modified: lib/Target/README.txt
===================================================================
--- a/lib/Target/README.txt
+++ b/lib/Target/README.txt
@@ -2238,4 +2238,23 @@ missed cases:
 
 //===---------------------------------------------------------------------===//
 
+define i1 @test1(i32 %x) nounwind {
+  %and = and i32 %x, 3
+  %cmp = icmp ult i32 %and, 2
+  ret i1 %cmp
+}
+
+Can be folded to (x & 2) == 0.
+
+define i1 @test2(i32 %x) nounwind {
+  %and = and i32 %x, 3
+  %cmp = icmp ugt i32 %and, 1
+  ret i1 %cmp
+}
 
+Can be folded to (x & 2) != 0.
+
+SimplifyDemandedBits shrinks the "and" constant to 2 but instcombine misses the
+icmp transform.
+
+//===---------------------------------------------------------------------===//
Modified: lib/Target/TargetInstrInfo.cpp
===================================================================
--- a/lib/Target/TargetInstrInfo.cpp
+++ b/lib/Target/TargetInstrInfo.cpp
@@ -149,10 +149,10 @@ bool TargetInstrInfo::isUnpredicatedTerminator(const \
MachineInstr *MI) const {  
 /// Measure the specified inline asm to determine an approximation of its
 /// length.
-/// Comments (which run till the next SeparatorChar or newline) do not
+/// Comments (which run till the next SeparatorString or newline) do not
 /// count as an instruction.
 /// Any other non-whitespace text is considered an instruction, with
-/// multiple instructions separated by SeparatorChar or newlines.
+/// multiple instructions separated by SeparatorString or newlines.
 /// Variable-length instructions are not handled here; this function
 /// may be overloaded in the target code to do that.
 unsigned TargetInstrInfo::getInlineAsmLength(const char *Str,
@@ -163,7 +163,8 @@ unsigned TargetInstrInfo::getInlineAsmLength(const char *Str,
   bool atInsnStart = true;
   unsigned Length = 0;
   for (; *Str; ++Str) {
-    if (*Str == '\n' || *Str == MAI.getSeparatorChar())
+    if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),
+                                strlen(MAI.getSeparatorString())) == 0)
       atInsnStart = true;
     if (atInsnStart && !std::isspace(*Str)) {
       Length += MAI.getMaxInstLength();
Modified: lib/Target/TargetMachine.cpp
===================================================================
--- a/lib/Target/TargetMachine.cpp
+++ b/lib/Target/TargetMachine.cpp
@@ -221,6 +221,7 @@ TargetMachine::TargetMachine(const Target &T)
   : TheTarget(T), AsmInfo(0),
     MCRelaxAll(false),
     MCNoExecStack(false),
+    MCSaveTempLabels(false),
     MCUseLoc(true) {
   // Typically it will be subtargets that will adjust FloatABIType from Default
   // to Soft or Hard.
Modified: lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -1639,8 +1639,9 @@ X86TargetLowering::LowerMemArgument(SDValue Chain,
   // In case of tail call optimization mark all arguments mutable. Since they
   // could be overwritten by lowering of arguments in case of a tail call.
   if (Flags.isByVal()) {
-    int FI = MFI->CreateFixedObject(Flags.getByValSize(),
-                                    VA.getLocMemOffset(), isImmutable);
+    unsigned Bytes = Flags.getByValSize();
+    if (Bytes == 0) Bytes = 1; // Don't create zero-sized stack objects.
+    int FI = MFI->CreateFixedObject(Bytes, VA.getLocMemOffset(), isImmutable);
     return DAG.getFrameIndex(FI, getPointerTy());
   } else {
     int FI = MFI->CreateFixedObject(ValVT.getSizeInBits()/8,
@@ -3902,8 +3903,8 @@ static SDValue getShuffleVectorZeroOrUndef(SDValue V2, unsigned \
Idx,  
 /// getShuffleScalarElt - Returns the scalar element that will make up the ith
 /// element of the result of the vector shuffle.
-SDValue getShuffleScalarElt(SDNode *N, int Index, SelectionDAG &DAG,
-                            unsigned Depth) {
+static SDValue getShuffleScalarElt(SDNode *N, int Index, SelectionDAG &DAG,
+                                   unsigned Depth) {
   if (Depth == 6)
     return SDValue();  // Limit search depth.
 
Modified: lib/Target/XCore/XCoreInstrInfo.td
===================================================================
--- a/lib/Target/XCore/XCoreInstrInfo.td
+++ b/lib/Target/XCore/XCoreInstrInfo.td
@@ -739,7 +739,7 @@ def BL_lu10 : _FLU10<
 }
 
 // Two operand short
-// TODO getr, getst
+// TODO eet, eef, testwct, tsetmr, sext (reg), zext (reg)
 def NOT : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b),
                  "not $dst, $b",
                  [(set GRRegs:$dst, (not GRRegs:$b))]>;
@@ -748,8 +748,6 @@ def NEG : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b),
                  "neg $dst, $b",
                  [(set GRRegs:$dst, (ineg GRRegs:$b))]>;
 
-// TODO setd, eet, eef, testwct, tinitpc, tinitdp,
-// tinitsp, tinitcp, tsetmr, sext (reg), zext (reg)
 let Constraints = "$src1 = $dst" in {
 let neverHasSideEffects = 1 in
 def SEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2),
@@ -837,9 +835,29 @@ def SETD_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val),
                  "setd res[$r], $val",
                  [(int_xcore_setd GRRegs:$r, GRRegs:$val)]>;
 
+def GETST_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r),
+                    "getst $dst, res[$r]",
+                    [(set GRRegs:$dst, (int_xcore_getst GRRegs:$r))]>;
+
+def INITSP_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src),
+                     "init t[$t]:sp, $src",
+                     [(int_xcore_initsp GRRegs:$t, GRRegs:$src)]>;
+
+def INITPC_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src),
+                     "init t[$t]:pc, $src",
+                     [(int_xcore_initpc GRRegs:$t, GRRegs:$src)]>;
+
+def INITCP_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src),
+                     "init t[$t]:cp, $src",
+                     [(int_xcore_initcp GRRegs:$t, GRRegs:$src)]>;
+
+def INITDP_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src),
+                     "init t[$t]:dp, $src",
+                     [(int_xcore_initdp GRRegs:$t, GRRegs:$src)]>;
+
 // Two operand long
 // TODO endin, peek,
-// getd, testlcl, tinitlr
+// getd, testlcl
 def BITREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src),
                  "bitrev $dst, $src",
                  [(set GRRegs:$dst, (int_xcore_bitrev GRRegs:$src))]>;
@@ -868,6 +886,10 @@ def SETPS_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2),
                  "set ps[$src1], $src2",
                  [(int_xcore_setps GRRegs:$src1, GRRegs:$src2)]>;
 
+def INITLR_l2r : _FL2R<(outs), (ins GRRegs:$t, GRRegs:$src),
+                       "init t[$t]:lr, $src",
+                       [(int_xcore_initlr GRRegs:$t, GRRegs:$src)]>;
+
 def SETCLK_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2),
                        "setclk res[$src1], $src2",
                        [(int_xcore_setclk GRRegs:$src1, GRRegs:$src2)]>;
@@ -881,9 +903,16 @@ def SETPSC_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2),
                        [(int_xcore_setpsc GRRegs:$src1, GRRegs:$src2)]>;
 
 // One operand short
-// TODO edu, eeu, waitet, waitef, tstart, msync, mjoin, clrtp
+// TODO edu, eeu, waitet, waitef, tstart, clrtp
 // setdp, setcp, setev, kcall
 // dgetreg
+def MSYNC_1r : _F1R<(outs), (ins GRRegs:$i),
+                    "msync res[$i]",
+		    [(int_xcore_msync GRRegs:$i)]>;
+def MJOIN_1r : _F1R<(outs), (ins GRRegs:$i),
+                    "mjoin res[$i]",
+		    [(int_xcore_mjoin GRRegs:$i)]>;
+
 let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in
 def BAU_1r : _F1R<(outs), (ins GRRegs:$addr),
                  "bau $addr",
@@ -940,7 +969,7 @@ def EEU_1r : _F1R<(outs), (ins GRRegs:$r),
                [(int_xcore_eeu GRRegs:$r)]>;
 
 // Zero operand short
-// TODO ssync, freet, ldspc, stspc, ldssr, stssr, ldsed, stsed,
+// TODO freet, ldspc, stspc, ldssr, stssr, ldsed, stsed,
 // stet, geted, getet, getkep, getksp, setkep, getid, kret, dcall, dret,
 // dentsp, drestsp
 
@@ -951,6 +980,10 @@ def GETID_0R : _F0R<(outs), (ins),
                  "get r11, id",
                  [(set R11, (int_xcore_getid))]>;
 
+def SSYNC_0r : _F0R<(outs), (ins),
+                    "ssync",
+		    [(int_xcore_ssync)]>;
+
 let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1,
     hasSideEffects = 1 in
 def WAITEU_0R : _F0R<(outs), (ins),
Modified: lib/Transforms/IPO/GlobalOpt.cpp
===================================================================
--- a/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/lib/Transforms/IPO/GlobalOpt.cpp
@@ -1193,9 +1193,11 @@ static Value *GetHeapSROAValue(Value *V, unsigned FieldNo,
     const StructType *ST =
       cast<StructType>(cast<PointerType>(PN->getType())->getElementType());
 
-    Result =
+    PHINode *NewPN =
      PHINode::Create(PointerType::getUnqual(ST->getElementType(FieldNo)),
+                     PN->getNumIncomingValues(),
                      PN->getName()+".f"+Twine(FieldNo), PN);
+    Result = NewPN;
     PHIsToRewrite.push_back(std::make_pair(PN, FieldNo));
   } else {
     llvm_unreachable("Unknown usable value");
Modified: lib/Transforms/IPO/LowerSetJmp.cpp
===================================================================
--- a/lib/Transforms/IPO/LowerSetJmp.cpp
+++ b/lib/Transforms/IPO/LowerSetJmp.cpp
@@ -430,7 +430,7 @@ void LowerSetJmp::TransformSetJmpCall(CallInst* Inst)
 
   // This PHI node will be in the new block created from the
   // splitBasicBlock call.
-  PHINode* PHI = PHINode::Create(Type::getInt32Ty(Inst->getContext()),
+  PHINode* PHI = PHINode::Create(Type::getInt32Ty(Inst->getContext()), 2,
                                  "SetJmpReturn", Inst);
 
   // Coming from a call to setjmp, the return is 0.
Modified: lib/Transforms/IPO/MergeFunctions.cpp
===================================================================
--- a/lib/Transforms/IPO/MergeFunctions.cpp
+++ b/lib/Transforms/IPO/MergeFunctions.cpp
@@ -125,7 +125,7 @@ private:
 const ComparableFunction ComparableFunction::EmptyKey = ComparableFunction(0);
 const ComparableFunction ComparableFunction::TombstoneKey =
     ComparableFunction(1);
-TargetData * const ComparableFunction::LookupOnly = (TargetData*)(-1);
+TargetData *const ComparableFunction::LookupOnly = (TargetData*)(-1);
 
 }
 
@@ -212,7 +212,7 @@ bool FunctionComparator::isEquivalentType(const Type *Ty1,
     return false;
   }
 
-  switch(Ty1->getTypeID()) {
+  switch (Ty1->getTypeID()) {
   default:
     llvm_unreachable("Unknown type!");
     // Fall through in Release mode.
Modified: lib/Transforms/IPO/PartialInlining.cpp
===================================================================
--- a/lib/Transforms/IPO/PartialInlining.cpp
+++ b/lib/Transforms/IPO/PartialInlining.cpp
@@ -95,7 +95,7 @@ Function* PartialInliner::unswitchFunction(Function* F) {
     PHINode* OldPhi = dyn_cast<PHINode>(I);
     if (!OldPhi) break;
     
-    PHINode* retPhi = PHINode::Create(OldPhi->getType(), "", Ins);
+    PHINode* retPhi = PHINode::Create(OldPhi->getType(), 2, "", Ins);
     OldPhi->replaceAllUsesWith(retPhi);
     Ins = newReturnBlock->getFirstNonPHI();
     
Modified: lib/Transforms/InstCombine/InstCombine.h
===================================================================
--- a/lib/Transforms/InstCombine/InstCombine.h
+++ b/lib/Transforms/InstCombine/InstCombine.h
@@ -246,7 +246,10 @@ public:
     // segment of unreachable code, so just clobber the instruction.
     if (&I == V) 
       V = UndefValue::get(I.getType());
-      
+
+    DEBUG(errs() << "IC: Replacing " << I << "\n"
+                    "    with " << *V << '\n');
+
     I.replaceAllUsesWith(V);
     return &I;
   }
Modified: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -756,6 +756,18 @@ Value *InstCombiner::FoldAndOfICmps(ICmpInst *LHS, ICmpInst \
*RHS) {  Value *NewOr = Builder->CreateOr(Val, Val2);
       return Builder->CreateICmp(LHSCC, NewOr, LHSCst);
     }
+
+    // (icmp slt A, 0) & (icmp slt B, 0) --> (icmp slt (A&B), 0)
+    if (LHSCC == ICmpInst::ICMP_SLT && LHSCst->isZero()) {
+      Value *NewAnd = Builder->CreateAnd(Val, Val2);
+      return Builder->CreateICmp(LHSCC, NewAnd, LHSCst);
+    }
+
+    // (icmp sgt A, -1) & (icmp sgt B, -1) --> (icmp sgt (A|B), -1)
+    if (LHSCC == ICmpInst::ICMP_SGT && LHSCst->isAllOnesValue()) {
+      Value *NewOr = Builder->CreateOr(Val, Val2);
+      return Builder->CreateICmp(LHSCC, NewOr, LHSCst);
+    }
   }
   
   // From here on, we only handle:
@@ -1442,6 +1454,18 @@ Value *InstCombiner::FoldOrOfICmps(ICmpInst *LHS, ICmpInst \
*RHS) {  Value *NewOr = Builder->CreateOr(Val, Val2);
       return Builder->CreateICmp(LHSCC, NewOr, LHSCst);
     }
+
+    // (icmp slt A, 0) | (icmp slt B, 0) --> (icmp slt (A|B), 0)
+    if (LHSCC == ICmpInst::ICMP_SLT && LHSCst->isZero()) {
+      Value *NewOr = Builder->CreateOr(Val, Val2);
+      return Builder->CreateICmp(LHSCC, NewOr, LHSCst);
+    }
+
+    // (icmp sgt A, -1) | (icmp sgt B, -1) --> (icmp sgt (A&B), -1)
+    if (LHSCC == ICmpInst::ICMP_SGT && LHSCst->isAllOnesValue()) {
+      Value *NewAnd = Builder->CreateAnd(Val, Val2);
+      return Builder->CreateICmp(LHSCC, NewAnd, LHSCst);
+    }
   }
 
   // (icmp ult (X + CA), C1) | (icmp eq X, C2) -> (icmp ule (X + CA), C1)
Modified: lib/Transforms/InstCombine/InstCombineCalls.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -487,14 +487,15 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
     APInt RHSKnownOne(BitWidth, 0);
     ComputeMaskedBits(RHS, Mask, RHSKnownZero, RHSKnownOne);
 
-    // Get the largest possible values for each operand, extended to be large
-    // enough so that every possible product of two BitWidth-sized ints fits.
-    APInt LHSMax = (~LHSKnownZero).zext(BitWidth*2);
-    APInt RHSMax = (~RHSKnownZero).zext(BitWidth*2);
+    // Get the largest possible values for each operand.
+    APInt LHSMax = ~LHSKnownZero;
+    APInt RHSMax = ~RHSKnownZero;
 
     // If multiplying the maximum values does not overflow then we can turn
     // this into a plain NUW mul.
-    if ((LHSMax * RHSMax).getActiveBits() <= BitWidth) {
+    bool Overflow;
+    LHSMax.umul_ov(RHSMax, Overflow);
+    if (!Overflow) {
       Value *Mul = Builder->CreateNUWMul(LHS, RHS, "umul_with_overflow");
       Constant *V[] = {
         UndefValue::get(LHS->getType()),
Modified: lib/Transforms/InstCombine/InstCombineCasts.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -196,7 +196,7 @@ Value *InstCombiner::EvaluateInDifferentType(Value *V, const Type \
*Ty,  }
   case Instruction::PHI: {
     PHINode *OPN = cast<PHINode>(I);
-    PHINode *NPN = PHINode::Create(Ty);
+    PHINode *NPN = PHINode::Create(Ty, OPN->getNumIncomingValues());
     for (unsigned i = 0, e = OPN->getNumIncomingValues(); i != e; ++i) {
       Value *V =EvaluateInDifferentType(OPN->getIncomingValue(i), Ty, isSigned);
       NPN->addIncoming(V, OPN->getIncomingBlock(i));
Modified: lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2762,6 +2762,40 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
   if (Constant *RHSC = dyn_cast<Constant>(Op1)) {
     if (Instruction *LHSI = dyn_cast<Instruction>(Op0))
       switch (LHSI->getOpcode()) {
+      case Instruction::FPExt: {
+        // fcmp (fpext x), C -> fcmp x, (fptrunc C) if fptrunc is lossless
+        FPExtInst *LHSExt = cast<FPExtInst>(LHSI);
+        ConstantFP *RHSF = dyn_cast<ConstantFP>(RHSC);
+        if (!RHSF)
+          break;
+
+        const fltSemantics *Sem;
+        // FIXME: This shouldn't be here.
+        if (LHSExt->getSrcTy()->isFloatTy())
+          Sem = &APFloat::IEEEsingle;
+        else if (LHSExt->getSrcTy()->isDoubleTy())
+          Sem = &APFloat::IEEEdouble;
+        else if (LHSExt->getSrcTy()->isFP128Ty())
+          Sem = &APFloat::IEEEquad;
+        else if (LHSExt->getSrcTy()->isX86_FP80Ty())
+          Sem = &APFloat::x87DoubleExtended;
+        else if (LHSExt->getSrcTy()->isPPC_FP128Ty())
+          Sem = &APFloat::PPCDoubleDouble;
+        else
+          break;
+
+        bool Lossy;
+        APFloat F = RHSF->getValueAPF();
+        F.convert(*Sem, APFloat::rmNearestTiesToEven, &Lossy);
+
+        // Avoid lossy conversions and denormals.
+        if (!Lossy &&
+            F.compare(APFloat::getSmallestNormalized(*Sem)) !=
+                                                           APFloat::cmpLessThan)
+          return new FCmpInst(I.getPredicate(), LHSExt->getOperand(0),
+                              ConstantFP::get(RHSC->getContext(), F));
+        break;
+      }
       case Instruction::PHI:
         // Only fold fcmp into the PHI if the phi and fcmp are in the same
         // block.  If in the same block, we're encouraging jump threading.  If
@@ -2800,6 +2834,14 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
           return SelectInst::Create(LHSI->getOperand(0), Op1, Op2);
         break;
       }
+      case Instruction::FSub: {
+        // fcmp pred (fneg x), C -> fcmp swap(pred) x, -C
+        Value *Op;
+        if (match(LHSI, m_FNeg(m_Value(Op))))
+          return new FCmpInst(I.getSwappedPredicate(), Op,
+                              ConstantExpr::getFNeg(RHSC));
+        break;
+      }
       case Instruction::Load:
         if (GetElementPtrInst *GEP =
             dyn_cast<GetElementPtrInst>(LHSI->getOperand(0))) {
@@ -2813,5 +2855,17 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
       }
   }
 
+  // fcmp pred (fneg x), (fneg y) -> fcmp swap(pred) x, y
+  Value *X, *Y;
+  if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_FNeg(m_Value(Y))))
+    return new FCmpInst(I.getSwappedPredicate(), X, Y);
+
+  // fcmp (fpext x), (fpext y) -> fcmp x, y
+  if (FPExtInst *LHSExt = dyn_cast<FPExtInst>(Op0))
+    if (FPExtInst *RHSExt = dyn_cast<FPExtInst>(Op1))
+      if (LHSExt->getSrcTy() == RHSExt->getSrcTy())
+        return new FCmpInst(I.getPredicate(), LHSExt->getOperand(0),
+                            RHSExt->getOperand(0));
+
   return Changed ? &I : 0;
 }
Modified: lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -591,8 +591,7 @@ bool InstCombiner::SimplifyStoreAtEndOfBlock(StoreInst &SI) {
   // Insert a PHI node now if we need it.
   Value *MergedVal = OtherStore->getOperand(0);
   if (MergedVal != SI.getOperand(0)) {
-    PHINode *PN = PHINode::Create(MergedVal->getType(), "storemerge");
-    PN->reserveOperandSpace(2);
+    PHINode *PN = PHINode::Create(MergedVal->getType(), 2, "storemerge");
     PN->addIncoming(SI.getOperand(0), SI.getParent());
     PN->addIncoming(OtherStore->getOperand(0), OtherBB);
     MergedVal = InsertNewInstBefore(PN, DestBB->front());
Modified: lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -452,6 +452,18 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) {
   if (Value *V = SimplifyFDivInst(Op0, Op1, TD))
     return ReplaceInstUsesWith(I, V);
 
+  if (ConstantFP *Op1C = dyn_cast<ConstantFP>(Op1)) {
+    const APFloat &Op1F = Op1C->getValueAPF();
+
+    // If the divisor has an exact multiplicative inverse we can turn the fdiv
+    // into a cheaper fmul.
+    APFloat Reciprocal(Op1F.getSemantics());
+    if (Op1F.getExactInverse(&Reciprocal)) {
+      ConstantFP *RFP = ConstantFP::get(Builder->getContext(), Reciprocal);
+      return BinaryOperator::CreateFMul(Op0, RFP);
+    }
+  }
+
   return 0;
 }
 
Modified: lib/Transforms/InstCombine/InstCombinePHI.cpp
===================================================================
--- a/lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ b/lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -80,18 +80,16 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
   Value *InRHS = FirstInst->getOperand(1);
   PHINode *NewLHS = 0, *NewRHS = 0;
   if (LHSVal == 0) {
-    NewLHS = PHINode::Create(LHSType,
+    NewLHS = PHINode::Create(LHSType, PN.getNumIncomingValues(),
                              FirstInst->getOperand(0)->getName() + ".pn");
-    NewLHS->reserveOperandSpace(PN.getNumOperands()/2);
     NewLHS->addIncoming(InLHS, PN.getIncomingBlock(0));
    


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic