[llvm] r286081 - Revert r286080: it breaks build bots
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Sun Nov 6 11:36:09 PST 2016
Author: kparzysz
Date: Sun Nov 6 13:36:09 2016
New Revision: 286081
URL: http://llvm.org/viewvc/llvm-project?rev=286081&view=rev
Log:
Revert r286080: it breaks build bots
Modified:
llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
llvm/trunk/lib/Target/Hexagon/HexagonPatterns.td
Modified: llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp?rev=286081&r1=286080&r2=286081&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp Sun Nov 6 13:36:09 2016
@@ -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
}
+//
+// 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<ConstantSDNode>((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
SelectFrameIndex(N);
return;
+ case ISD::ADD:
+ SelectAdd(N);
+ return;
+
case ISD::BITCAST:
SelectBitcast(N);
return;
@@ -971,6 +1151,14 @@ void HexagonDAGToDAGISel::Select(SDNode
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;
Modified: llvm/trunk/lib/Target/Hexagon/HexagonPatterns.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonPatterns.td?rev=286081&r1=286080&r2=286081&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonPatterns.td (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonPatterns.td Sun Nov 6 13:36:09 2016
@@ -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 : SDNodeXForm<imm, [{
@@ -61,36 +36,15 @@ def SDEC1 : SDNodeXForm<imm, [{
def UDEC1 : SDNodeXForm<imm, [{
uint32_t V = N->getZExtValue();
- assert(V >= 1);
+ assert(V > 0);
return CurDAG->getTargetConstant(V-1, SDLoc(N), MVT::i32);
}]>;
-def UDEC32 : SDNodeXForm<imm, [{
- uint32_t V = N->getZExtValue();
- assert(V >= 32);
- return CurDAG->getTargetConstant(V-32, SDLoc(N), MVT::i32);
-}]>;
-
def Log2_32 : SDNodeXForm<imm, [{
uint32_t V = N->getZExtValue();
return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32);
}]>;
-def Log2_64 : SDNodeXForm<imm, [{
- uint64_t V = N->getZExtValue();
- return CurDAG->getTargetConstant(Log2_64(V), SDLoc(N), MVT::i32);
-}]>;
-
-def LogN2_32 : SDNodeXForm<imm, [{
- uint32_t NV = ~N->getZExtValue();
- return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32);
-}]>;
-
-def LogN2_64 : SDNodeXForm<imm, [{
- uint64_t NV = ~N->getZExtValue();
- return CurDAG->getTargetConstant(Log2_64(NV), SDLoc(N), MVT::i32);
-}]>;
-
class T_CMP_pat <InstHexagon MI, PatFrag OpNode, PatLeaf ImmPred>
: Pat<(i1 (OpNode I32:$src1, ImmPred:$src2)),
@@ -574,54 +528,18 @@ def: Pat<(i32 (trunc (ctlz (not 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 : SDNodeXForm<imm, [{
return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32);
}]>;
+def LogN2_32 : SDNodeXForm<imm, [{
+ uint32_t NV = ~N->getZExtValue();
+ return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32);
+}]>;
+
def NegImm8 : SDNodeXForm<imm, [{
int8_t NV = -N->getSExtValue();
return CurDAG->getTargetConstant(NV, SDLoc(N), MVT::i32);
More information about the llvm-commits
mailing list