[llvm-commits] [llvm] r118968 - in /llvm/trunk: lib/Target/ARM/ARMExpandPseudoInsts.cpp lib/Target/ARM/ARMISelDAGToDAG.cpp lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/ARMInstrThumb2.td test/CodeGen/ARM/select-imm.ll

Evan Cheng evan.cheng at apple.com
Fri Nov 12 18:25:14 PST 2010


Author: evancheng
Date: Fri Nov 12 20:25:14 2010
New Revision: 118968

URL: http://llvm.org/viewvc/llvm-project?rev=118968&view=rev
Log:
Add conditional move of large immediate.

Modified:
    llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp
    llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
    llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
    llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
    llvm/trunk/test/CodeGen/ARM/select-imm.ll

Modified: llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp?rev=118968&r1=118967&r2=118968&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp Fri Nov 12 20:25:14 2010
@@ -691,15 +691,19 @@
     }
 
     case ARM::MOVi32imm:
-    case ARM::t2MOVi32imm: {
+    case ARM::MOVCCi32imm:
+    case ARM::t2MOVi32imm:
+    case ARM::t2MOVCCi32imm: {
       unsigned PredReg = 0;
       ARMCC::CondCodes Pred = llvm::getInstrPredicate(&MI, PredReg);
       unsigned DstReg = MI.getOperand(0).getReg();
       bool DstIsDead = MI.getOperand(0).isDead();
-      const MachineOperand &MO = MI.getOperand(1);
+      bool isCC = Opcode == ARM::MOVCCi32imm || Opcode == ARM::t2MOVCCi32imm;
+      const MachineOperand &MO = MI.getOperand(isCC ? 2 : 1);
       MachineInstrBuilder LO16, HI16;
 
-      if (Opcode == ARM::MOVi32imm && !STI->hasV6T2Ops()) {
+      if (!STI->hasV6T2Ops() &&
+          (Opcode == ARM::MOVi32imm || Opcode == ARM::MOVCCi32imm)) {
         // Expand into a movi + orr.
         LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVi), DstReg);
         HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::ORRri))

Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=118968&r1=118967&r2=118968&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Fri Nov 12 20:25:14 2010
@@ -1782,20 +1782,26 @@
   if (!T)
     return 0;
 
+  unsigned Opc = 0;
   unsigned TrueImm = T->getZExtValue();
   bool isSoImm = is_t2_so_imm(TrueImm);
   if (isSoImm || TrueImm <= 0xffff) {
-    SDValue True = CurDAG->getTargetConstant(TrueImm, MVT::i32);
-    SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
-    SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag };
-    return CurDAG->SelectNodeTo(N, (isSoImm ? ARM::t2MOVCCi : ARM::t2MOVCCi16),
-                                MVT::i32, Ops, 5);
+    Opc = isSoImm ? ARM::t2MOVCCi : ARM::t2MOVCCi16;
   } else if (is_t2_so_imm_not(TrueImm)) {
-    SDValue True = CurDAG->getTargetConstant(~TrueImm, MVT::i32);
+    TrueImm = ~TrueImm;
+    Opc = ARM::t2MVNCCi;
+  } else if (Subtarget->hasV6T2Ops()) {
+    // Large immediate.
+    Opc = ARM::t2MOVCCi32imm;
+  }
+
+  if (Opc) {
+    SDValue True = CurDAG->getTargetConstant(TrueImm, MVT::i32);
     SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
     SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag };
-    return CurDAG->SelectNodeTo(N, ARM::t2MVNCCi, MVT::i32, Ops, 5);
+    return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 5);
   }
+
   return 0;
 }
 
@@ -1806,20 +1812,26 @@
   if (!T)
     return 0;
 
+  unsigned Opc = 0;
   unsigned TrueImm = T->getZExtValue();
   bool isSoImm = is_so_imm(TrueImm);
   if (isSoImm || (Subtarget->hasV6T2Ops() && TrueImm <= 0xffff)) {
-    SDValue True = CurDAG->getTargetConstant(TrueImm, MVT::i32);
-    SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
-    SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag };
-    return CurDAG->SelectNodeTo(N, (isSoImm ? ARM::MOVCCi : ARM::MOVCCi16),
-                                MVT::i32, Ops, 5);
+    Opc = isSoImm ? ARM::MOVCCi : ARM::MOVCCi16;
   } else if (is_so_imm_not(TrueImm)) {
-    SDValue True = CurDAG->getTargetConstant(~TrueImm, MVT::i32);
+    TrueImm = ~TrueImm;
+    Opc = ARM::MVNCCi;
+  } else if (Subtarget->hasV6T2Ops() || ARM_AM::isSOImmTwoPartVal(TrueImm)) {
+    // Large immediate.
+    Opc = ARM::MOVCCi32imm;
+  }
+
+  if (Opc) {
+    SDValue True = CurDAG->getTargetConstant(TrueImm, MVT::i32);
     SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
     SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag };
-    return CurDAG->SelectNodeTo(N, ARM::MVNCCi, MVT::i32, Ops, 5);
+    return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 5);
   }
+  
   return 0;
 }
 

Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=118968&r1=118967&r2=118968&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Fri Nov 12 20:25:14 2010
@@ -2942,6 +2942,11 @@
   let Inst{11-0} = imm;
 }
 
+// Two instruction predicate mov immediate.
+def MOVCCi32imm : PseudoInst<(outs GPR:$Rd),
+                             (ins GPR:$false, i32imm:$src, pred:$p),
+                  IIC_iMOVix2, "", []>, RegConstraint<"$false = $Rd">;
+
 let isAsCheapAsAMove = 1 in
 def MVNCCi : AI1<0b1111, (outs GPR:$Rd),
                          (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,

Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=118968&r1=118967&r2=118968&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Fri Nov 12 20:25:14 2010
@@ -2243,7 +2243,8 @@
 // Conditional moves
 // FIXME: should be able to write a pattern for ARMcmov, but can't use
 // a two-value operand where a dag node expects two operands. :(
-let neverHasSideEffects = 1, isAsCheapAsAMove = 1 in {
+let neverHasSideEffects = 1 in {
+let isAsCheapAsAMove = 1 in
 def t2MOVCCr : T2I<(outs rGPR:$dst), (ins rGPR:$false, rGPR:$true), IIC_iCMOVr,
                    "mov", ".w\t$dst, $true",
    [/*(set rGPR:$dst, (ARMcmov rGPR:$false, rGPR:$true, imm:$cc, CCR:$ccr))*/]>,
@@ -2257,6 +2258,7 @@
   let Inst{7-4} = 0b0000;
 }
 
+let isAsCheapAsAMove = 1 in
 def t2MOVCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
                    IIC_iCMOVi, "mov", ".w\t$dst, $true",
 [/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
@@ -2269,6 +2271,7 @@
   let Inst{15} = 0;
 }
 
+let isAsCheapAsAMove = 1 in
 def t2MOVCCi16 : T2I<(outs rGPR:$dst), (ins rGPR:$false, i32imm:$src),
                       IIC_iCMOVi,
                       "movw", "\t$dst, $src", []>,
@@ -2280,6 +2283,11 @@
   let Inst{15} = 0;
 }
 
+def t2MOVCCi32imm : PseudoInst<(outs rGPR:$dst),
+                               (ins rGPR:$false, i32imm:$src, pred:$p),
+                    IIC_iMOVix2, "", []>, RegConstraint<"$false = $dst">;
+
+let isAsCheapAsAMove = 1 in
 def t2MVNCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
                    IIC_iCMOVi, "mvn", ".w\t$dst, $true",
 [/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm_not:$true,

Modified: llvm/trunk/test/CodeGen/ARM/select-imm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/select-imm.ll?rev=118968&r1=118967&r2=118968&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/select-imm.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/select-imm.ll Fri Nov 12 20:25:14 2010
@@ -1,5 +1,6 @@
 ; RUN: llc < %s -march=arm                  | FileCheck %s --check-prefix=ARM
-; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s --check-prefix=T2
+; RUN: llc < %s -march=arm -mattr=+thumb2   | FileCheck %s --check-prefix=ARMT2
+; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s --check-prefix=THUMB2
 
 define i32 @t1(i32 %c) nounwind readnone {
 entry:
@@ -8,9 +9,13 @@
 ; ARM: orr r1, r1, #1, 24
 ; ARM: movgt r0, #123
 
-; T2: t1:
-; T2: movw r0, #357
-; T2: movgt r0, #123
+; ARMT2: t1:
+; ARMT2: movw r0, #357
+; ARMT2: movgt r0, #123
+
+; THUMB2: t1:
+; THUMB2: movw r0, #357
+; THUMB2: movgt r0, #123
 
   %0 = icmp sgt i32 %c, 1
   %1 = select i1 %0, i32 123, i32 357
@@ -20,13 +25,17 @@
 define i32 @t2(i32 %c) nounwind readnone {
 entry:
 ; ARM: t2:
-; ARM: mov r1, #101
-; ARM: orr r1, r1, #1, 24
-; ARM: movle r0, #123
-
-; T2: t2:
-; T2: mov.w r0, #123
-; T2: movwgt r0, #357
+; ARM: mov r0, #123
+; ARM: movgt r0, #101
+; ARM: orrgt r0, r0, #1, 24
+
+; ARMT2: t2:
+; ARMT2: mov r0, #123
+; ARMT2: movwgt r0, #357
+
+; THUMB2: t2:
+; THUMB2: mov.w r0, #123
+; THUMB2: movwgt r0, #357
 
   %0 = icmp sgt i32 %c, 1
   %1 = select i1 %0, i32 357, i32 123
@@ -39,9 +48,13 @@
 ; ARM: mov r0, #0
 ; ARM: moveq r0, #1
 
-; T2: t3:
-; T2: mov.w r0, #0
-; T2: moveq r0, #1
+; ARMT2: t3:
+; ARMT2: mov r0, #0
+; ARMT2: moveq r0, #1
+
+; THUMB2: t3:
+; THUMB2: mov.w r0, #0
+; THUMB2: moveq r0, #1
   %0 = icmp eq i32 %a, 160
   %1 = zext i1 %0 to i32
   ret i32 %1
@@ -53,8 +66,12 @@
 ; ARM: ldr
 ; ARM: movlt
 
-; T2: t4:
-; T2: mvnlt.w r0, #11141290
+; ARMT2: t4:
+; ARMT2: movwlt r0, #65365
+; ARMT2: movtlt r0, #65365
+
+; THUMB2: t4:
+; THUMB2: mvnlt.w r0, #11141290
   %0 = icmp slt i32 %a, %b
   %1 = select i1 %0, i32 4283826005, i32 %x
   ret i32 %1





More information about the llvm-commits mailing list