Fix a crash compiling 254.gap for Thumb2.  The Thumb2 add/sub with 12-bit
immediate instructions cannot set the condition codes, so they do not have
the extra cc_out operand.  We hit an assertion during tail duplication
because the instruction being duplicated had more operands that expected.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98001 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index 6241766..77714bb 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -331,9 +331,9 @@
      let Inst{15} = 0;
    }
    // 12-bit imm
-   def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), IIC_iALUi,
-                   !strconcat(opc, "w"), "\t$dst, $lhs, $rhs",
-                   [(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]> {
+   def ri12 : T2I<(outs GPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), IIC_iALUi,
+                  !strconcat(opc, "w"), "\t$dst, $lhs, $rhs",
+                  [(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]> {
      let Inst{31-27} = 0b11110;
      let Inst{25} = 1;
      let Inst{24} = 0;
diff --git a/lib/Target/ARM/Thumb2InstrInfo.cpp b/lib/Target/ARM/Thumb2InstrInfo.cpp
index 20f13f1..e4abcdb 100644
--- a/lib/Target/ARM/Thumb2InstrInfo.cpp
+++ b/lib/Target/ARM/Thumb2InstrInfo.cpp
@@ -164,6 +164,7 @@
       continue;
     }
 
+    bool HasCCOut = true;
     if (BaseReg == ARM::SP) {
       // sub sp, sp, #imm7
       if (DestReg == ARM::SP && (ThisVal < ((1 << 7)-1) * 4)) {
@@ -195,6 +196,7 @@
         NumBytes = 0;
       } else if (ThisVal < 4096) {
         Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
+        HasCCOut = false;
         NumBytes = 0;
       } else {
         // FIXME: Move this to ARMAddressingModes.h?
@@ -207,9 +209,12 @@
     }
 
     // Build the new ADD / SUB.
-    AddDefaultCC(AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
-                                .addReg(BaseReg, RegState::Kill)
-                                .addImm(ThisVal)));
+    MachineInstrBuilder MIB =
+      AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
+                     .addReg(BaseReg, RegState::Kill)
+                     .addImm(ThisVal));
+    if (HasCCOut)
+      AddDefaultCC(MIB);
 
     BaseReg = DestReg;
   }
@@ -328,7 +333,6 @@
   if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) {
     Offset += MI.getOperand(FrameRegIdx+1).getImm();
 
-    bool isSP = FrameReg == ARM::SP;
     unsigned PredReg;
     if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) {
       // Turn it into a move.
@@ -342,6 +346,9 @@
       return true;
     }
 
+    bool isSP = FrameReg == ARM::SP;
+    bool HasCCOut = Opcode != ARM::t2ADDri12;
+
     if (Offset < 0) {
       Offset = -Offset;
       isSub = true;
@@ -354,17 +361,24 @@
     if (ARM_AM::getT2SOImmVal(Offset) != -1) {
       MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
       MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
+      // Add cc_out operand if the original instruction did not have one.
+      if (!HasCCOut)
+        MI.addOperand(MachineOperand::CreateReg(0, false));
       Offset = 0;
       return true;
     }
     // Another common case: imm12.
-    if (Offset < 4096) {
+    if (Offset < 4096 &&
+        (!HasCCOut || MI.getOperand(MI.getNumOperands()-1).getReg() == 0)) {
       unsigned NewOpc = isSP
         ? (isSub ? ARM::t2SUBrSPi12 : ARM::t2ADDrSPi12)
         : (isSub ? ARM::t2SUBri12   : ARM::t2ADDri12);
       MI.setDesc(TII.get(NewOpc));
       MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
       MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
+      // Remove the cc_out operand.
+      if (HasCCOut)
+        MI.RemoveOperand(MI.getNumOperands()-1);
       Offset = 0;
       return true;
     }
@@ -380,6 +394,10 @@
     assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 &&
            "Bit extraction didn't work?");
     MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
+    // Add cc_out operand if the original instruction did not have one.
+    if (!HasCCOut)
+      MI.addOperand(MachineOperand::CreateReg(0, false));
+
   } else {
 
     // AddrMode4 and AddrMode6 cannot handle any offset.