diff options
author | Nico Weber <nicolasweber@gmx.de> | 2016-09-12 21:40:50 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2016-09-12 21:40:50 +0000 |
commit | 7c31d0ebc0de04b8f94e5c142ed3354ba7825d33 (patch) | |
tree | 5e16f5f609958781ee825ba37a2f4d20cd782cd1 /llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp | |
parent | 8ad01c303e4980e81ff00c7ec693924613c9cc32 (diff) | |
download | bcm5719-llvm-7c31d0ebc0de04b8f94e5c142ed3354ba7825d33.tar.gz bcm5719-llvm-7c31d0ebc0de04b8f94e5c142ed3354ba7825d33.zip |
Revert r281215, it caused PR30358.
llvm-svn: 281263
Diffstat (limited to 'llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp | 138 |
1 files changed, 4 insertions, 134 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp index e4ce927afb5..30586aa2539 100644 --- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -244,8 +244,7 @@ private: bool tryInlineAsm(SDNode *N); void SelectConcatVector(SDNode *N); - void SelectCMPZ(SDNode *N, bool &SwitchEQNEToPLMI); - + bool trySMLAWSMULW(SDNode *N); void SelectCMP_SWAP(SDNode *N); @@ -2694,83 +2693,6 @@ void ARMDAGToDAGISel::SelectConcatVector(SDNode *N) { ReplaceNode(N, createDRegPairNode(VT, N->getOperand(0), N->getOperand(1))); } -static Optional<std::pair<unsigned, unsigned>> -getContiguousRangeOfSetBits(const APInt &A) { - unsigned FirstOne = A.getBitWidth() - A.countLeadingZeros() - 1; - unsigned LastOne = A.countTrailingZeros(); - if (A.countPopulation() != (FirstOne - LastOne + 1)) - return Optional<std::pair<unsigned,unsigned>>(); - return std::make_pair(FirstOne, LastOne); -} - -void ARMDAGToDAGISel::SelectCMPZ(SDNode *N, bool &SwitchEQNEToPLMI) { - assert(N->getOpcode() == ARMISD::CMPZ); - SwitchEQNEToPLMI = false; - - if (!Subtarget->isThumb()) - // FIXME: Work out whether it is profitable to do this in A32 mode - LSL and - // LSR don't exist as standalone instructions - they need the barrel shifter. - return; - // select (cmpz (and X, C), #0) -> (LSLS X) or (LSRS X) or (LSRS (LSLS X)) - SDValue And = N->getOperand(0); - SDValue Zero = N->getOperand(1); - if (!isa<ConstantSDNode>(Zero) || !cast<ConstantSDNode>(Zero)->isNullValue() || - And->getOpcode() != ISD::AND) - return; - SDValue X = And.getOperand(0); - auto C = dyn_cast<ConstantSDNode>(And.getOperand(1)); - - if (!C || !X->hasOneUse()) - return; - auto Range = getContiguousRangeOfSetBits(C->getAPIntValue()); - if (!Range) - return; - - // There are several ways to lower this: - SDNode *NewN; - SDLoc dl(N); - - auto EmitShift = [&](unsigned Opc, SDValue Src, unsigned Imm) -> SDNode* { - if (Subtarget->isThumb2()) { - Opc = (Opc == ARM::tLSLri) ? ARM::t2LSLri : ARM::t2LSRri; - SDValue Ops[] = { Src, CurDAG->getTargetConstant(Imm, dl, MVT::i32), - getAL(CurDAG, dl), CurDAG->getRegister(0, MVT::i32), - CurDAG->getRegister(0, MVT::i32) }; - return CurDAG->getMachineNode(Opc, dl, MVT::i32, Ops); - } else { - SDValue Ops[] = {CurDAG->getRegister(ARM::CPSR, MVT::i32), Src, - CurDAG->getTargetConstant(Imm, dl, MVT::i32), - getAL(CurDAG, dl), CurDAG->getRegister(0, MVT::i32)}; - return CurDAG->getMachineNode(Opc, dl, MVT::i32, Ops); - } - }; - - if (Range->second == 0) { - // 1. Mask includes the LSB -> Simply shift the top N bits off - NewN = EmitShift(ARM::tLSLri, X, 31 - Range->first); - ReplaceNode(And.getNode(), NewN); - } else if (Range->first == 31) { - // 2. Mask includes the MSB -> Simply shift the bottom N bits off - NewN = EmitShift(ARM::tLSRri, X, Range->second); - ReplaceNode(And.getNode(), NewN); - } else if (Range->first == Range->second) { - // 3. Only one bit is set. We can shift this into the sign bit and use a - // PL/MI comparison. - NewN = EmitShift(ARM::tLSLri, X, 31 - Range->first); - ReplaceNode(And.getNode(), NewN); - - SwitchEQNEToPLMI = true; - } else if (!Subtarget->hasV6T2Ops()) { - // 4. Do a double shift to clear bottom and top bits, but only in - // thumb-1 mode as in thumb-2 we can use UBFX. - NewN = EmitShift(ARM::tLSLri, X, 31 - Range->first); - NewN = EmitShift(ARM::tLSRri, SDValue(NewN, 0), - Range->second + (31 - Range->first)); - ReplaceNode(And.getNode(), NewN); - } - -} - void ARMDAGToDAGISel::Select(SDNode *N) { SDLoc dl(N); @@ -2998,7 +2920,6 @@ void ARMDAGToDAGISel::Select(SDNode *N) { return; } } - break; } case ARMISD::VMOVRRD: @@ -3189,27 +3110,9 @@ void ARMDAGToDAGISel::Select(SDNode *N) { assert(N2.getOpcode() == ISD::Constant); assert(N3.getOpcode() == ISD::Register); - unsigned CC = (unsigned) cast<ConstantSDNode>(N2)->getZExtValue(); - - if (InFlag.getOpcode() == ARMISD::CMPZ) { - bool SwitchEQNEToPLMI; - SelectCMPZ(InFlag.getNode(), SwitchEQNEToPLMI); - InFlag = N->getOperand(4); - - if (SwitchEQNEToPLMI) { - switch ((ARMCC::CondCodes)CC) { - default: llvm_unreachable("CMPZ must be either NE or EQ!"); - case ARMCC::NE: - CC = (unsigned)ARMCC::MI; - break; - case ARMCC::EQ: - CC = (unsigned)ARMCC::PL; - break; - } - } - } - - SDValue Tmp2 = CurDAG->getTargetConstant(CC, dl, MVT::i32); + SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) + cast<ConstantSDNode>(N2)->getZExtValue()), dl, + MVT::i32); SDValue Ops[] = { N1, Tmp2, N3, Chain, InFlag }; SDNode *ResNode = CurDAG->getMachineNode(Opc, dl, MVT::Other, MVT::Glue, Ops); @@ -3264,39 +3167,6 @@ void ARMDAGToDAGISel::Select(SDNode *N) { // Other cases are autogenerated. break; } - - case ARMISD::CMOV: { - SDValue InFlag = N->getOperand(4); - - if (InFlag.getOpcode() == ARMISD::CMPZ) { - bool SwitchEQNEToPLMI; - SelectCMPZ(InFlag.getNode(), SwitchEQNEToPLMI); - - if (SwitchEQNEToPLMI) { - SDValue ARMcc = N->getOperand(2); - ARMCC::CondCodes CC = - (ARMCC::CondCodes)cast<ConstantSDNode>(ARMcc)->getZExtValue(); - - switch (CC) { - default: llvm_unreachable("CMPZ must be either NE or EQ!"); - case ARMCC::NE: - CC = ARMCC::MI; - break; - case ARMCC::EQ: - CC = ARMCC::PL; - break; - } - SDValue NewARMcc = CurDAG->getConstant((unsigned)CC, dl, MVT::i32); - SDValue Ops[] = {N->getOperand(0), N->getOperand(1), NewARMcc, - N->getOperand(3), N->getOperand(4)}; - CurDAG->MorphNodeTo(N, ARMISD::CMOV, CurDAG->getVTList(MVT::i32), - Ops); - } - - } - // Other cases are autogenerated. - break; - } case ARMISD::VZIP: { unsigned Opc = 0; |