From: Krzysztof Parzyszek Date: Sun, 6 Nov 2016 19:36:09 +0000 (+0000) Subject: Revert r286080: it breaks build bots X-Git-Tag: llvmorg-4.0.0-rc1~5385 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f8d38d11b9323d875b85623193940b117c1ec4fa;p=platform%2Fupstream%2Fllvm.git Revert r286080: it breaks build bots llvm-svn: 286081 --- diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp index e5e2c8b..8ffa369 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp @@ -112,7 +112,9 @@ public: void SelectIntrinsicWOChain(SDNode *N); void SelectConstant(SDNode *N); void SelectConstantFP(SDNode *N); + void SelectAdd(SDNode *N); void SelectBitcast(SDNode *N); + void SelectBitOp(SDNode *N); // Include the pieces autogenerated from the target description. #include "HexagonGenDAGISel.inc" @@ -886,6 +888,180 @@ void HexagonDAGToDAGISel::SelectConstant(SDNode *N) { } +// +// Map add followed by a asr -> asr +=. +// +void HexagonDAGToDAGISel::SelectAdd(SDNode *N) { + SDLoc dl(N); + if (N->getValueType(0) != MVT::i32) { + SelectCode(N); + return; + } + // Identify nodes of the form: add(asr(...)). + SDNode* Src1 = N->getOperand(0).getNode(); + if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse() || + Src1->getValueType(0) != MVT::i32) { + SelectCode(N); + return; + } + + // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that + // Rd and Rd' are assigned to the same register + SDNode* Result = CurDAG->getMachineNode(Hexagon::S2_asr_r_r_acc, dl, MVT::i32, + N->getOperand(1), + Src1->getOperand(0), + Src1->getOperand(1)); + ReplaceNode(N, Result); +} + +// +// Map the following, where possible. +// AND/FABS -> clrbit +// OR -> setbit +// XOR/FNEG ->toggle_bit. +// +void HexagonDAGToDAGISel::SelectBitOp(SDNode *N) { + SDLoc dl(N); + EVT ValueVT = N->getValueType(0); + + // We handle only 32 and 64-bit bit ops. + if (!(ValueVT == MVT::i32 || ValueVT == MVT::i64 || + ValueVT == MVT::f32 || ValueVT == MVT::f64)) { + SelectCode(N); + return; + } + + // We handly only fabs and fneg for V5. + unsigned Opc = N->getOpcode(); + if ((Opc == ISD::FABS || Opc == ISD::FNEG) && !HST->hasV5TOps()) { + SelectCode(N); + return; + } + + int64_t Val = 0; + if (Opc != ISD::FABS && Opc != ISD::FNEG) { + if (N->getOperand(1).getOpcode() == ISD::Constant) + Val = cast((N)->getOperand(1))->getSExtValue(); + else { + SelectCode(N); + return; + } + } + + if (Opc == ISD::AND) { + // Check if this is a bit-clearing AND, if not select code the usual way. + if ((ValueVT == MVT::i32 && isPowerOf2_32(~Val)) || + (ValueVT == MVT::i64 && isPowerOf2_64(~Val))) + Val = ~Val; + else { + SelectCode(N); + return; + } + } + + // If OR or AND is being fed by shl, srl and, sra don't do this change, + // because Hexagon provide |= &= on shl, srl, and sra. + // Traverse the DAG to see if there is shl, srl and sra. + if (Opc == ISD::OR || Opc == ISD::AND) { + switch (N->getOperand(0)->getOpcode()) { + default: + break; + case ISD::SRA: + case ISD::SRL: + case ISD::SHL: + SelectCode(N); + return; + } + } + + // Make sure it's power of 2. + unsigned BitPos = 0; + if (Opc != ISD::FABS && Opc != ISD::FNEG) { + if ((ValueVT == MVT::i32 && !isPowerOf2_32(Val)) || + (ValueVT == MVT::i64 && !isPowerOf2_64(Val))) { + SelectCode(N); + return; + } + + // Get the bit position. + BitPos = countTrailingZeros(uint64_t(Val)); + } else { + // For fabs and fneg, it's always the 31st bit. + BitPos = 31; + } + + unsigned BitOpc = 0; + // Set the right opcode for bitwise operations. + switch (Opc) { + default: + llvm_unreachable("Only bit-wise/abs/neg operations are allowed."); + case ISD::AND: + case ISD::FABS: + BitOpc = Hexagon::S2_clrbit_i; + break; + case ISD::OR: + BitOpc = Hexagon::S2_setbit_i; + break; + case ISD::XOR: + case ISD::FNEG: + BitOpc = Hexagon::S2_togglebit_i; + break; + } + + SDNode *Result; + // Get the right SDVal for the opcode. + SDValue SDVal = CurDAG->getTargetConstant(BitPos, dl, MVT::i32); + + if (ValueVT == MVT::i32 || ValueVT == MVT::f32) { + Result = CurDAG->getMachineNode(BitOpc, dl, ValueVT, + N->getOperand(0), SDVal); + } else { + // 64-bit gymnastic to use REG_SEQUENCE. But it's worth it. + EVT SubValueVT; + if (ValueVT == MVT::i64) + SubValueVT = MVT::i32; + else + SubValueVT = MVT::f32; + + SDNode *Reg = N->getOperand(0).getNode(); + SDValue RegClass = CurDAG->getTargetConstant(Hexagon::DoubleRegsRegClassID, + dl, MVT::i64); + + SDValue SubregHiIdx = CurDAG->getTargetConstant(Hexagon::subreg_hireg, dl, + MVT::i32); + SDValue SubregLoIdx = CurDAG->getTargetConstant(Hexagon::subreg_loreg, dl, + MVT::i32); + + SDValue SubregHI = CurDAG->getTargetExtractSubreg(Hexagon::subreg_hireg, dl, + MVT::i32, SDValue(Reg, 0)); + + SDValue SubregLO = CurDAG->getTargetExtractSubreg(Hexagon::subreg_loreg, dl, + MVT::i32, SDValue(Reg, 0)); + + // Clear/set/toggle hi or lo registers depending on the bit position. + if (SubValueVT != MVT::f32 && BitPos < 32) { + SDNode *Result0 = CurDAG->getMachineNode(BitOpc, dl, SubValueVT, + SubregLO, SDVal); + const SDValue Ops[] = { RegClass, SubregHI, SubregHiIdx, + SDValue(Result0, 0), SubregLoIdx }; + Result = CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, + dl, ValueVT, Ops); + } else { + if (Opc != ISD::FABS && Opc != ISD::FNEG) + SDVal = CurDAG->getTargetConstant(BitPos-32, dl, MVT::i32); + SDNode *Result0 = CurDAG->getMachineNode(BitOpc, dl, SubValueVT, + SubregHI, SDVal); + const SDValue Ops[] = { RegClass, SDValue(Result0, 0), SubregHiIdx, + SubregLO, SubregLoIdx }; + Result = CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, + dl, ValueVT, Ops); + } + } + + ReplaceNode(N, Result); +} + + void HexagonDAGToDAGISel::SelectFrameIndex(SDNode *N) { MachineFrameInfo &MFI = MF->getFrameInfo(); const HexagonFrameLowering *HFI = HST->getFrameLowering(); @@ -951,6 +1127,10 @@ void HexagonDAGToDAGISel::Select(SDNode *N) { SelectFrameIndex(N); return; + case ISD::ADD: + SelectAdd(N); + return; + case ISD::BITCAST: SelectBitcast(N); return; @@ -971,6 +1151,14 @@ void HexagonDAGToDAGISel::Select(SDNode *N) { SelectMul(N); return; + case ISD::AND: + case ISD::OR: + case ISD::XOR: + case ISD::FABS: + case ISD::FNEG: + SelectBitOp(N); + return; + case ISD::ZERO_EXTEND: SelectZeroExtend(N); return; diff --git a/llvm/lib/Target/Hexagon/HexagonPatterns.td b/llvm/lib/Target/Hexagon/HexagonPatterns.td index f46a558..bce46ef 100644 --- a/llvm/lib/Target/Hexagon/HexagonPatterns.td +++ b/llvm/lib/Target/Hexagon/HexagonPatterns.td @@ -24,34 +24,9 @@ def IsPow2_32 : PatLeaf<(i32 imm), [{ return isPowerOf2_32(V); }]>; -def IsPow2_64 : PatLeaf<(i64 imm), [{ - uint64_t V = N->getZExtValue(); - return isPowerOf2_64(V); -}]>; - def IsNPow2_32 : PatLeaf<(i32 imm), [{ - uint32_t NV = ~N->getZExtValue(); - return isPowerOf2_32(NV); -}]>; - -def IsPow2_64L : PatLeaf<(i64 imm), [{ - uint64_t V = N->getZExtValue(); - return isPowerOf2_64(V) && Log2_64(V) < 32; -}]>; - -def IsPow2_64H : PatLeaf<(i64 imm), [{ - uint64_t V = N->getZExtValue(); - return isPowerOf2_64(V) && Log2_64(V) >= 32; -}]>; - -def IsNPow2_64L : PatLeaf<(i64 imm), [{ - uint64_t NV = ~N->getZExtValue(); - return isPowerOf2_64(NV) && Log2_64(NV) < 32; -}]>; - -def IsNPow2_64H : PatLeaf<(i64 imm), [{ - uint64_t NV = ~N->getZExtValue(); - return isPowerOf2_64(NV) && Log2_64(NV) >= 32; + uint32_t V = N->getZExtValue(); + return isPowerOf2_32(~V); }]>; def SDEC1 : SDNodeXFormgetZExtValue(); - assert(V >= 1); + assert(V > 0); return CurDAG->getTargetConstant(V-1, SDLoc(N), MVT::i32); }]>; -def UDEC32 : SDNodeXFormgetZExtValue(); - assert(V >= 32); - return CurDAG->getTargetConstant(V-32, SDLoc(N), MVT::i32); -}]>; - def Log2_32 : SDNodeXFormgetZExtValue(); return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32); }]>; -def Log2_64 : SDNodeXFormgetZExtValue(); - return CurDAG->getTargetConstant(Log2_64(V), SDLoc(N), MVT::i32); -}]>; - -def LogN2_32 : SDNodeXFormgetZExtValue(); - return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32); -}]>; - -def LogN2_64 : SDNodeXFormgetZExtValue(); - return CurDAG->getTargetConstant(Log2_64(NV), SDLoc(N), MVT::i32); -}]>; - class T_CMP_pat : Pat<(i1 (OpNode I32:$src1, ImmPred:$src2)), @@ -574,54 +528,18 @@ def: Pat<(i32 (trunc (ctlz (not I64:$Rss)))), (S2_cl1p I64:$Rss)>; // Count trailing ones: 32-bit. def: Pat<(cttz (not I32:$Rs)), (S2_ct1 I32:$Rs)>; -let AddedComplexity = 20 in { // Complexity greater than and/or/xor - def: Pat<(and I32:$Rs, IsNPow2_32:$V), - (S2_clrbit_i IntRegs:$Rs, (LogN2_32 $V))>; - def: Pat<(or I32:$Rs, IsPow2_32:$V), - (S2_setbit_i IntRegs:$Rs, (Log2_32 $V))>; - def: Pat<(xor I32:$Rs, IsPow2_32:$V), - (S2_togglebit_i IntRegs:$Rs, (Log2_32 $V))>; - - def: Pat<(and I32:$Rs, (not (shl 1, I32:$Rt))), - (S2_clrbit_r IntRegs:$Rs, IntRegs:$Rt)>; - def: Pat<(or I32:$Rs, (shl 1, I32:$Rt)), - (S2_setbit_r IntRegs:$Rs, IntRegs:$Rt)>; - def: Pat<(xor I32:$Rs, (shl 1, I32:$Rt)), - (S2_togglebit_r IntRegs:$Rs, IntRegs:$Rt)>; -} - -// Clr/set/toggle bit for 64-bit values with immediate bit index. -let AddedComplexity = 20 in { // Complexity greater than and/or/xor - def: Pat<(and I64:$Rss, IsNPow2_64L:$V), - (REG_SEQUENCE DoubleRegs, - (i32 (HiReg $Rss)), subreg_hireg, - (S2_clrbit_i (LoReg $Rss), (LogN2_64 $V)), subreg_loreg)>; - def: Pat<(and I64:$Rss, IsNPow2_64H:$V), - (REG_SEQUENCE DoubleRegs, - (S2_clrbit_i (HiReg $Rss), (UDEC32 (i32 (LogN2_64 $V)))), - subreg_hireg, - (i32 (LoReg $Rss)), subreg_loreg)>; - - def: Pat<(or I64:$Rss, IsPow2_64L:$V), - (REG_SEQUENCE DoubleRegs, - (i32 (HiReg $Rss)), subreg_hireg, - (S2_setbit_i (LoReg $Rss), (Log2_64 $V)), subreg_loreg)>; - def: Pat<(or I64:$Rss, IsPow2_64H:$V), - (REG_SEQUENCE DoubleRegs, - (S2_setbit_i (HiReg $Rss), (UDEC32 (i32 (Log2_64 $V)))), - subreg_hireg, - (i32 (LoReg $Rss)), subreg_loreg)>; - - def: Pat<(xor I64:$Rss, IsPow2_64L:$V), - (REG_SEQUENCE DoubleRegs, - (i32 (HiReg $Rss)), subreg_hireg, - (S2_togglebit_i (LoReg $Rss), (Log2_64 $V)), subreg_loreg)>; - def: Pat<(xor I64:$Rss, IsPow2_64H:$V), - (REG_SEQUENCE DoubleRegs, - (S2_togglebit_i (HiReg $Rss), (UDEC32 (i32 (Log2_64 $V)))), - subreg_hireg, - (i32 (LoReg $Rss)), subreg_loreg)>; -} +def: Pat<(i32 (and I32:$Rs, (not (shl 1, u5_0ImmPred:$u5)))), + (S2_clrbit_i IntRegs:$Rs, u5_0ImmPred:$u5)>; +def: Pat<(i32 (or I32:$Rs, (shl 1, u5_0ImmPred:$u5))), + (S2_setbit_i IntRegs:$Rs, u5_0ImmPred:$u5)>; +def: Pat<(i32 (xor I32:$Rs, (shl 1, u5_0ImmPred:$u5))), + (S2_togglebit_i IntRegs:$Rs, u5_0ImmPred:$u5)>; +def: Pat<(i32 (and I32:$Rs, (not (shl 1, I32:$Rt)))), + (S2_clrbit_r IntRegs:$Rs, IntRegs:$Rt)>; +def: Pat<(i32 (or I32:$Rs, (shl 1, I32:$Rt))), + (S2_setbit_r IntRegs:$Rs, IntRegs:$Rt)>; +def: Pat<(i32 (xor I32:$Rs, (shl 1, I32:$Rt))), + (S2_togglebit_r IntRegs:$Rs, IntRegs:$Rt)>; let AddedComplexity = 20 in { // Complexity greater than cmp reg-imm. def: Pat<(i1 (setne (and (shl 1, u5_0ImmPred:$u5), I32:$Rs), 0)), @@ -1724,6 +1642,11 @@ def LogN2_16 : SDNodeXFormgetTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32); }]>; +def LogN2_32 : SDNodeXFormgetZExtValue(); + return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32); +}]>; + def NegImm8 : SDNodeXFormgetSExtValue(); return CurDAG->getTargetConstant(NV, SDLoc(N), MVT::i32);