llvm.org GIT mirror llvm / 5bcb8a6
temporarily revert r112664, it is causing a decoding conflict, and the testcases should be merged. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112711 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 10 years ago
5 changed file(s) with 0 addition(s) and 142 deletion(s). Raw diff Collapse all Expand all
179179 SDNode *SelectARMCMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
180180 ARMCC::CondCodes CCVal, SDValue CCR,
181181 SDValue InFlag);
182 SDNode *OptimizeCMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
183 ARMCC::CondCodes CCVal, SDValue CCR,
184 SDValue InFlag, bool IsThumb2);
185182
186183 SDNode *SelectConcatVector(SDNode *N);
187184
16431640 return 0;
16441641 }
16451642
1646 /// OptimizeCMOVSoImmOp - It's possible to save an instruction or two be
1647 /// recognizing that the TST and AND instructions perform the same function
1648 /// (they "and" the two values). See inside for more details.
1649 SDNode *ARMDAGToDAGISel::
1650 OptimizeCMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
1651 ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag,
1652 bool IsThumb2) {
1653 // Convert:
1654 //
1655 // tst.w r0, #256
1656 // mvn r0, #25
1657 // it eq
1658 // moveq r0, #0
1659 //
1660 // into:
1661 //
1662 // ands.w r0, r0, #256
1663 // it ne
1664 // mvnne.w r0, #25
1665 //
1666 if (InFlag.getOpcode() != ARMISD::CMPZ ||
1667 InFlag.getOperand(0).getOpcode() != ISD::AND)
1668 return 0;
1669
1670 // The true value needs to be zero, as that's the result of the AND
1671 // instruction.
1672 ConstantSDNode *True = dyn_cast(TrueVal);
1673 if (!True || True->getZExtValue() != 0)
1674 return 0;
1675
1676 // Bail if the false value isn't an immediate.
1677 ConstantSDNode *False = dyn_cast(FalseVal);
1678 if (!False)
1679 return 0;
1680
1681 bool UseMVN = false;
1682 if ((IsThumb2 && !Pred_t2_so_imm(FalseVal.getNode())) ||
1683 (!IsThumb2 && !Pred_so_imm(FalseVal.getNode()))) {
1684 // The false value isn't a proper immediate. Check to see if we can use the
1685 // bitwise NOT version.
1686 if ((IsThumb2 && ARM_AM::getT2SOImmVal(~False->getZExtValue()) != -1) ||
1687 (!IsThumb2 && ARM_AM::getSOImmVal(~False->getZExtValue()) != -1)) {
1688 UseMVN = true;
1689 FalseVal = CurDAG->getTargetConstant(~False->getZExtValue(), MVT::i32);
1690 } else {
1691 return 0;
1692 }
1693 } else {
1694 FalseVal = CurDAG->getTargetConstant(False->getZExtValue(), MVT::i32);
1695 }
1696
1697 // A comparison against zero corresponds with the flag AND sets if the result
1698 // is zero.
1699 ConstantSDNode *CmpVal = dyn_cast(InFlag.getOperand(1));
1700 if (!CmpVal || CmpVal->getZExtValue() != 0)
1701 return 0;
1702
1703 ARMCC::CondCodes NegCC = ARMCC::getOppositeCondition(CCVal);
1704 SDValue OrigAnd = InFlag.getOperand(0);
1705 SDValue NewAnd =
1706 CurDAG->getNode(ARMISD::AND, N->getDebugLoc(),
1707 CurDAG->getVTList(OrigAnd.getValueType(), MVT::Flag),
1708 OrigAnd->getOperand(0), OrigAnd->getOperand(1));
1709
1710 unsigned Opcode = !UseMVN ?
1711 (IsThumb2 ? ARM::t2MOVCCi : ARM::MOVCCi) :
1712 (IsThumb2 ? ARM::t2MVNCCi : ARM::MVNCCi);
1713
1714 SDValue Ops[] = {
1715 NewAnd.getValue(0),
1716 FalseVal,
1717 CurDAG->getTargetConstant(NegCC, MVT::i32),
1718 CCR, NewAnd.getValue(1)
1719 };
1720 SDNode *ResNode = CurDAG->SelectNodeTo(N, Opcode, MVT::i32, Ops, 5);
1721
1722 // Manually run "Select" on the newly created "ARMISD::AND" node to make
1723 // sure that it's converted properly.
1724 SDNode *AndNode = Select(NewAnd.getNode());
1725 if (AndNode && NewAnd.getNode() != AndNode &&
1726 NewAnd.getNode()->getOpcode() != ISD::DELETED_NODE)
1727 ReplaceUses(NewAnd.getNode(), AndNode);
1728
1729 return ResNode;
1730 }
1731
17321643 SDNode *ARMDAGToDAGISel::
17331644 SelectT2CMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
17341645 ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) {
17371648 return 0;
17381649
17391650 if (Pred_t2_so_imm(TrueVal.getNode())) {
1740 SDNode *ResNode = OptimizeCMOVSoImmOp(N, FalseVal, TrueVal, CCVal, CCR,
1741 InFlag, true);
1742 if (ResNode) return ResNode;
1743
17441651 SDValue True = CurDAG->getTargetConstant(T->getZExtValue(), MVT::i32);
17451652 SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
17461653 SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag };
17581665 return 0;
17591666
17601667 if (Pred_so_imm(TrueVal.getNode())) {
1761 SDNode *ResNode = OptimizeCMOVSoImmOp(N, FalseVal, TrueVal, CCVal, CCR,
1762 InFlag, false);
1763 if (ResNode) return ResNode;
1764
17651668 SDValue True = CurDAG->getTargetConstant(T->getZExtValue(), MVT::i32);
17661669 SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
17671670 SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag };
24172417 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
24182418 RegConstraint<"$false = $dst">, UnaryDP {
24192419 let Inst{25} = 1;
2420 }
2421
2422 def MVNCCi : AI1<0b1111, (outs GPR:$dst),
2423 (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
2424 "mvn", "\t$dst, $true",
2425 [/*(set GPR:$dst, (ARMcmov GPR:$false,so_imm_not:$true,imm:$cc,CCR:$ccr))*/]>,
2426 RegConstraint<"$false = $dst">, UnaryDP {
2427 let Inst{25} = 0;
24282420 }
24292421 } // neverHasSideEffects
24302422
21892189 let Inst{31-27} = 0b11110;
21902190 let Inst{25} = 0;
21912191 let Inst{24-21} = 0b0010;
2192 let Inst{20} = 0; // The S bit.
2193 let Inst{19-16} = 0b1111; // Rn
2194 let Inst{15} = 0;
2195 }
2196
2197 def t2MVNCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
2198 IIC_iCMOVi, "mvn", ".w\t$dst, $true",
2199 [/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm_not:$true,imm:$cc,CCR:$ccr))*/]>,
2200 RegConstraint<"$false = $dst"> {
2201 let Inst{31-27} = 0b11110;
2202 let Inst{25} = 0;
2203 let Inst{24-21} = 0b0011;
22042192 let Inst{20} = 0; // The S bit.
22052193 let Inst{19-16} = 0b1111; // Rn
22062194 let Inst{15} = 0;
+0
-12
test/CodeGen/ARM/mvncc.ll less more
None ; RUN: llc < %s -mtriple=arm-apple-darwin | FileCheck %s
1
2 define i32 @f1(i32 %t) nounwind {
3 ; CHECK: f1
4 ; CHECK-NOT: tst
5 ; CHECK: and
6 ; CHECK: mvnne
7 %and = and i32 %t, 256
8 %tobool = icmp eq i32 %and, 0
9 %retval.0 = select i1 %tobool, i32 0, i32 -26
10 ret i32 %retval.0
11 }
+0
-13
test/CodeGen/Thumb2/thumb2-mvncc.ll less more
None ; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s
1
2 define i32 @f1(i32 %t) nounwind {
3 ; CHECK: f1
4 ; CHECK-NOT: tst
5 ; CHECK: ands
6 ; CHECK: it ne
7 ; CHECK: mvnne
8 %and = and i32 %t, 256
9 %tobool = icmp eq i32 %and, 0
10 %retval.0 = select i1 %tobool, i32 0, i32 -26
11 ret i32 %retval.0
12 }