diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp index 50cb31158c59..8ffa3691d59b 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp @@ -116,69 +116,6 @@ public: void SelectBitcast(SDNode *N); void SelectBitOp(SDNode *N); - // XformMskToBitPosU5Imm - Returns the bit position which - // the single bit 32 bit mask represents. - // Used in Clr and Set bit immediate memops. - SDValue XformMskToBitPosU5Imm(uint32_t Imm, const SDLoc &DL) { - unsigned BitPos = Log2_32(Imm); - assert(BitPos < 32 && "Constant out of range for 32 BitPos Memops"); - return CurDAG->getTargetConstant(BitPos, DL, MVT::i32); - } - - // XformMskToBitPosU4Imm - Returns the bit position which the single-bit - // 16 bit mask represents. Used in Clr and Set bit immediate memops. - SDValue XformMskToBitPosU4Imm(uint16_t Imm, const SDLoc &DL) { - return XformMskToBitPosU5Imm(Imm, DL); - } - - // XformMskToBitPosU3Imm - Returns the bit position which the single-bit - // 8 bit mask represents. Used in Clr and Set bit immediate memops. - SDValue XformMskToBitPosU3Imm(uint8_t Imm, const SDLoc &DL) { - return XformMskToBitPosU5Imm(Imm, DL); - } - - // Return true if there is exactly one bit set in V, i.e., if V is one of the - // following integers: 2^0, 2^1, ..., 2^31. - bool ImmIsSingleBit(uint32_t v) const { - return isPowerOf2_32(v); - } - - // XformM5ToU5Imm - Return a target constant with the specified value, of - // type i32 where the negative literal is transformed into a positive literal - // for use in -= memops. - inline SDValue XformM5ToU5Imm(signed Imm, const SDLoc &DL) { - assert((Imm >= -31 && Imm <= -1) && "Constant out of range for Memops"); - return CurDAG->getTargetConstant(-Imm, DL, MVT::i32); - } - - // XformU7ToU7M1Imm - Return a target constant decremented by 1, in range - // [1..128], used in cmpb.gtu instructions. - inline SDValue XformU7ToU7M1Imm(signed Imm, const SDLoc &DL) { - assert((Imm >= 1 && Imm <= 128) && "Constant out of range for cmpb op"); - return CurDAG->getTargetConstant(Imm - 1, DL, MVT::i8); - } - - // XformS8ToS8M1Imm - Return a target constant decremented by 1. - inline SDValue XformSToSM1Imm(signed Imm, const SDLoc &DL) { - return CurDAG->getTargetConstant(Imm - 1, DL, MVT::i32); - } - - // XformU8ToU8M1Imm - Return a target constant decremented by 1. - inline SDValue XformUToUM1Imm(unsigned Imm, const SDLoc &DL) { - assert((Imm >= 1) && "Cannot decrement unsigned int less than 1"); - return CurDAG->getTargetConstant(Imm - 1, DL, MVT::i32); - } - - // XformSToSM2Imm - Return a target constant decremented by 2. - inline SDValue XformSToSM2Imm(unsigned Imm, const SDLoc &DL) { - return CurDAG->getTargetConstant(Imm - 2, DL, MVT::i32); - } - - // XformSToSM3Imm - Return a target constant decremented by 3. - inline SDValue XformSToSM3Imm(unsigned Imm, const SDLoc &DL) { - return CurDAG->getTargetConstant(Imm - 3, DL, MVT::i32); - } - // Include the pieces autogenerated from the target description. #include "HexagonGenDAGISel.inc" diff --git a/llvm/lib/Target/Hexagon/HexagonIntrinsics.td b/llvm/lib/Target/Hexagon/HexagonIntrinsics.td index b6a863ab3a13..31f1545cb6d8 100644 --- a/llvm/lib/Target/Hexagon/HexagonIntrinsics.td +++ b/llvm/lib/Target/Hexagon/HexagonIntrinsics.td @@ -1243,6 +1243,15 @@ class S2op_tableidx_pat ; +def DEC2_CONST_SIGNED : SDNodeXFormgetSExtValue(); + return CurDAG->getTargetConstant(V-2, SDLoc(N), MVT::i32); +}]>; + +def DEC3_CONST_SIGNED : SDNodeXFormgetSExtValue(); + return CurDAG->getTargetConstant(V-3, SDLoc(N), MVT::i32); +}]>; // Table Index : Extract and insert bits. // Map to the real hardware instructions after subtracting appropriate diff --git a/llvm/lib/Target/Hexagon/HexagonOperands.td b/llvm/lib/Target/Hexagon/HexagonOperands.td index 559a488e110d..80af52c603ba 100644 --- a/llvm/lib/Target/Hexagon/HexagonOperands.td +++ b/llvm/lib/Target/Hexagon/HexagonOperands.td @@ -196,12 +196,6 @@ def u8_0ImmPred : PatLeaf<(i32 imm), [{ return isUInt<8>(v); }]>; -def u7_0StrictPosImmPred : ImmLeaf(Imm) && Imm > 0; -}]>; - def u6_0ImmPred : PatLeaf<(i32 imm), [{ int64_t v = (int64_t)N->getSExtValue(); return isUInt<6>(v); @@ -237,28 +231,6 @@ def u2_0ImmPred : PatLeaf<(i32 imm), [{ return isUInt<2>(v); }]>; -def m5_0ImmPred : PatLeaf<(i32 imm), [{ - // m5_0ImmPred predicate - True if the number is in range -1 .. -31 - // and will fit in a 5 bit field when made positive, for use in memops. - int64_t v = (int64_t)N->getSExtValue(); - return (-31 <= v && v <= -1); -}]>; - -//InN means negative integers in [-(2^N - 1), 0] -def n8_0ImmPred : PatLeaf<(i32 imm), [{ - // n8_0ImmPred predicate - True if the immediate fits in a 8-bit signed - // field. - int64_t v = (int64_t)N->getSExtValue(); - return (-255 <= v && v <= 0); -}]>; - -def nOneImmPred : PatLeaf<(i32 imm), [{ - // nOneImmPred predicate - True if the immediate is -1. - int64_t v = (int64_t)N->getSExtValue(); - return (-1 == v); -}]>; - - // Extendable immediate operands. def f32ExtOperand : AsmOperandClass { let Name = "f32Ext"; } def s16_0ExtOperand : AsmOperandClass { let Name = "s16_0Ext"; } @@ -320,25 +292,6 @@ let OperandType = "OPERAND_IMMEDIATE", PrintMethod = "printExtOperand", } -def s4_7ImmPred : PatLeaf<(i32 imm), [{ - int64_t v = (int64_t)N->getSExtValue(); - if (HST->hasV60TOps()) - // Return true if the immediate can fit in a 10-bit sign extended field and - // is 128-byte aligned. - return isShiftedInt<4,7>(v); - return false; -}]>; - -def s4_6ImmPred : PatLeaf<(i32 imm), [{ - int64_t v = (int64_t)N->getSExtValue(); - if (HST->hasV60TOps()) - // Return true if the immediate can fit in a 10-bit sign extended field and - // is 64-byte aligned. - return isShiftedInt<4,6>(v); - return false; -}]>; - - // This complex pattern exists only to create a machine instruction operand // of type "frame index". There doesn't seem to be a way to do that directly // in the patterns. diff --git a/llvm/lib/Target/Hexagon/HexagonPatterns.td b/llvm/lib/Target/Hexagon/HexagonPatterns.td index 232bb2bf15bd..b4d00d4a8e3e 100644 --- a/llvm/lib/Target/Hexagon/HexagonPatterns.td +++ b/llvm/lib/Target/Hexagon/HexagonPatterns.td @@ -39,34 +39,23 @@ def Clr5ImmPred : PatLeaf<(i32 imm), [{ return isPowerOf2_32(v); }]>; -// SDNode for converting immediate C to C-1. def DEC_CONST_SIGNED : SDNodeXFormgetSExtValue(); - return XformSToSM1Imm(imm, SDLoc(N)); + int32_t V = N->getSExtValue(); + return CurDAG->getTargetConstant(V-1, SDLoc(N), MVT::i32); }]>; -// SDNode for converting immediate C to C-2. -def DEC2_CONST_SIGNED : SDNodeXFormgetSExtValue(); - return XformSToSM2Imm(imm, SDLoc(N)); -}]>; - -// SDNode for converting immediate C to C-3. -def DEC3_CONST_SIGNED : SDNodeXFormgetSExtValue(); - return XformSToSM3Imm(imm, SDLoc(N)); -}]>; - -// SDNode for converting immediate C to C-1. def DEC_CONST_UNSIGNED : SDNodeXFormgetZExtValue(); - return XformUToUM1Imm(imm, SDLoc(N)); + uint32_t V = N->getZExtValue(); + assert(V > 0); + return CurDAG->getTargetConstant(V-1, SDLoc(N), MVT::i32); }]>; +def BITPOS32 : SDNodeXFormgetZExtValue(); + return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32); +}]>; + + class T_CMP_pat : Pat<(i1 (OpNode I32:$src1, ImmPred:$src2)), (MI IntRegs:$src1, ImmPred:$src2)>; @@ -1094,6 +1083,11 @@ def: Pat<(HexagonEXTRACTURP I32:$src1, I64:$src2), def: Pat<(HexagonEXTRACTURP I64:$src1, I64:$src2), (S2_extractup_rp I64:$src1, I64:$src2)>; +def n8_0ImmPred: PatLeaf<(i32 imm), [{ + int64_t V = N->getSExtValue(); + return -255 <= V && V <= 0; +}]>; + // Change the sign of the immediate for Rd=-mpyi(Rs,#u8) def: Pat<(mul I32:$src1, (ineg n8_0ImmPred:$src2)), (M2_mpysin IntRegs:$src1, u8_0ImmPred:$src2)>; @@ -1144,13 +1138,6 @@ def : Pat<(callv3nr texternalsym:$dst), def addrga: PatLeaf<(i32 AddrGA:$Addr)>; def addrgp: PatLeaf<(i32 AddrGP:$Addr)>; -def BITPOS32 : SDNodeXFormgetSExtValue(); - return XformMskToBitPosU5Imm(imm, SDLoc(N)); -}]>; - // Pats for instruction selection. @@ -1368,8 +1355,8 @@ def s30_2ProperPred : PatLeaf<(i32 imm), [{ return isShiftedInt<30,2>(v) && !isShiftedInt<29,3>(v); }]>; def RoundTo8 : SDNodeXFormgetSExtValue(); - return CurDAG->getTargetConstant(Imm & -8, SDLoc(N), MVT::i32); + int32_t Imm = N->getSExtValue(); + return CurDAG->getTargetConstant(Imm & -8, SDLoc(N), MVT::i32); }]>; let AddedComplexity = 40 in @@ -1649,53 +1636,60 @@ def: Pat<(shl s6_0ImmPred:$s6, I32:$Rt), //===----------------------------------------------------------------------===// def m5_0Imm8Pred : PatLeaf<(i32 imm), [{ - int8_t v = (int8_t)N->getSExtValue(); - return v > -32 && v <= -1; + int8_t V = N->getSExtValue(); + return V > -32 && V <= -1; }]>; def m5_0Imm16Pred : PatLeaf<(i32 imm), [{ - int16_t v = (int16_t)N->getSExtValue(); - return v > -32 && v <= -1; + int16_t V = N->getSExtValue(); + return V > -32 && V <= -1; +}]>; + +def m5_0ImmPred : PatLeaf<(i32 imm), [{ + // m5_0ImmPred predicate - True if the number is in range -1 .. -31 + // and will fit in a 5 bit field when made positive, for use in memops. + int64_t v = (int64_t)N->getSExtValue(); + return (-31 <= v && v <= -1); }]>; def Clr5Imm8Pred : PatLeaf<(i32 imm), [{ - uint32_t v = (uint8_t)~N->getZExtValue(); - return ImmIsSingleBit(v); + uint8_t V = ~N->getZExtValue(); + return isPowerOf2_32(V); }]>; def Clr5Imm16Pred : PatLeaf<(i32 imm), [{ - uint32_t v = (uint16_t)~N->getZExtValue(); - return ImmIsSingleBit(v); + uint16_t V = ~N->getZExtValue(); + return isPowerOf2_32(V); }]>; def Set5Imm8 : SDNodeXFormgetZExtValue(); - return XformMskToBitPosU5Imm(imm, SDLoc(N)); + uint8_t V = N->getZExtValue(); + return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32); }]>; def Set5Imm16 : SDNodeXFormgetZExtValue(); - return XformMskToBitPosU5Imm(imm, SDLoc(N)); + uint16_t V = N->getZExtValue(); + return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32); }]>; def Set5Imm32 : SDNodeXFormgetZExtValue(); - return XformMskToBitPosU5Imm(imm, SDLoc(N)); + uint32_t V = N->getZExtValue(); + return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32); }]>; def Clr5Imm8 : SDNodeXFormgetZExtValue(); - return XformMskToBitPosU5Imm(imm, SDLoc(N)); + uint8_t V = ~N->getZExtValue(); + return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32); }]>; def Clr5Imm16 : SDNodeXFormgetZExtValue(); - return XformMskToBitPosU5Imm(imm, SDLoc(N)); + uint16_t V = ~N->getZExtValue(); + return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32); }]>; def Clr5Imm32 : SDNodeXFormgetZExtValue(); - return XformMskToBitPosU5Imm(imm, SDLoc(N)); + uint32_t V = ~N->getZExtValue(); + return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32); }]>; def NegImm8 : SDNodeXForm; def NegImm32 : SDNodeXFormgetTargetConstant(-N->getSExtValue(), SDLoc(N), MVT::i32); + int32_t V = N->getSExtValue(); + return CurDAG->getTargetConstant(-V, SDLoc(N), MVT::i32); }]>; def IdImm : SDNodeXForm; @@ -1955,17 +1950,18 @@ def: Pat<(i1 (setlt I32:$src1, s32_0ImmPred:$src2)), def: Pat<(i1 (setne I32:$src1, s32_0ImmPred:$src2)), (C4_cmpneqi IntRegs:$src1, s32_0ImmPred:$src2)>; -// SDNode for converting immediate C to C-1. -def DEC_CONST_BYTE : SDNodeXFormgetSExtValue(); - return XformU7ToU7M1Imm(imm, SDLoc(N)); -}]>; - // For the sequence // zext( setult ( and(Rs, 255), u8)) // Use the isdigit transformation below + +def u7_0PosImmPred : ImmLeaf 0 && isUInt<7>(Imm); +}]>; + + // Generate code of the form 'C2_muxii(cmpbgtui(Rdd, C-1),0,1)' // for C code of the form r = ((c>='0') & (c<='9')) ? 1 : 0;. // The isdigit transformation relies on two 'clever' aspects: @@ -1978,12 +1974,11 @@ def DEC_CONST_BYTE : SDNodeXForm='0') & (c<='9')) ? 1 : 0; // The code is transformed upstream of llvm into // retval = (c-48) < 10 ? 1 : 0; + let AddedComplexity = 139 in def: Pat<(i32 (zext (i1 (setult (i32 (and I32:$src1, 255)), - u7_0StrictPosImmPred:$src2)))), - (C2_muxii (A4_cmpbgtui IntRegs:$src1, - (DEC_CONST_BYTE u7_0StrictPosImmPred:$src2)), - 0, 1)>; + u7_0PosImmPred:$src2)))), + (C2_muxii (A4_cmpbgtui IntRegs:$src1, (DEC_CONST_UNSIGNED imm:$src2)), 0, 1)>; class Loada_pat : Pat<(VT (Load Addr:$addr)), (MI Addr:$addr)>; @@ -2688,6 +2683,17 @@ def unalignedstore : PatFrag<(ops node:$val, node:$addr), (store $val, $addr), [ }]>; +def s4_6ImmPred: PatLeaf<(i32 imm), [{ + int64_t V = N->getSExtValue(); + return isShiftedInt<4,6>(V); +}]>; + +def s4_7ImmPred: PatLeaf<(i32 imm), [{ + int64_t V = N->getSExtValue(); + return isShiftedInt<4,7>(V); +}]>; + + multiclass vS32b_ai_pats { // Aligned stores def : Pat<(alignedstore (VTSgl VectorRegs:$src1), IntRegs:$addr),