| commit 9ae73cdbc1e59fd3149e60efd2b96e68e8d1669b |
| Author: David Green <david.green@arm.com> |
| Date: Fri Jan 22 11:11:36 2021 +0000 |
| |
| [ARM] Adjust isSaturatingConditional to return a new SDValue. NFC |
| |
| This replaces the isSaturatingConditional function with |
| LowerSaturatingConditional that directly returns a new SSAT or |
| USAT SDValue, instead of returning true and the components of it. |
| |
| diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp |
| index aabfad045d9f..949d2ffc1714 100644 |
| --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp |
| +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp |
| @@ -5036,17 +5036,13 @@ static bool isLowerSaturate(const SDValue LHS, const SDValue RHS, |
| // etc. |
| // |
| // LLVM canonicalizes these to either a min(max()) or a max(min()) |
| -// pattern. This function tries to match one of these and will return true |
| -// if successful. |
| +// pattern. This function tries to match one of these and will return a SSAT |
| +// node if successful. |
| // |
| -// USAT works similarily to SSAT but bounds on the interval [0, k] where k + 1 is |
| -// a power of 2. |
| -// |
| -// It returns true if the conversion can be done, false otherwise. |
| -// Additionally, the variable is returned in parameter V, the constant in K and |
| -// usat is set to true if the conditional represents an unsigned saturation |
| -static bool isSaturatingConditional(const SDValue &Op, SDValue &V, |
| - uint64_t &K, bool &Usat) { |
| +// USAT works similarily to SSAT but bounds on the interval [0, k] where k + 1 |
| +// is a power of 2. |
| +static SDValue LowerSaturatingConditional(SDValue Op, SelectionDAG &DAG) { |
| + EVT VT = Op.getValueType(); |
| SDValue V1 = Op.getOperand(0); |
| SDValue K1 = Op.getOperand(1); |
| SDValue TrueVal1 = Op.getOperand(2); |
| @@ -5055,7 +5051,7 @@ static bool isSaturatingConditional(const SDValue &Op, SDValue &V, |
| |
| const SDValue Op2 = isa<ConstantSDNode>(TrueVal1) ? FalseVal1 : TrueVal1; |
| if (Op2.getOpcode() != ISD::SELECT_CC) |
| - return false; |
| + return SDValue(); |
| |
| SDValue V2 = Op2.getOperand(0); |
| SDValue K2 = Op2.getOperand(1); |
| @@ -5074,41 +5070,39 @@ static bool isSaturatingConditional(const SDValue &Op, SDValue &V, |
| |
| // Check that the registers and the constants match a max(min()) or min(max()) |
| // pattern |
| - if (V1Tmp == TrueVal1 && V2Tmp == TrueVal2 && K1 == FalseVal1 && |
| - K2 == FalseVal2 && |
| - ((isGTorGE(CC1) && isLTorLE(CC2)) || (isLTorLE(CC1) && isGTorGE(CC2)))) { |
| - |
| - // Check that the constant in the lower-bound check is |
| - // the opposite of the constant in the upper-bound check |
| - // in 1's complement. |
| - if (!isa<ConstantSDNode>(K1) || !isa<ConstantSDNode>(K2)) |
| - return false; |
| + if (V1Tmp != TrueVal1 || V2Tmp != TrueVal2 || K1 != FalseVal1 || |
| + K2 != FalseVal2 || |
| + !((isGTorGE(CC1) && isLTorLE(CC2)) || (isLTorLE(CC1) && isGTorGE(CC2)))) |
| + return SDValue(); |
| |
| - int64_t Val1 = cast<ConstantSDNode>(K1)->getSExtValue(); |
| - int64_t Val2 = cast<ConstantSDNode>(K2)->getSExtValue(); |
| - int64_t PosVal = std::max(Val1, Val2); |
| - int64_t NegVal = std::min(Val1, Val2); |
| + // Check that the constant in the lower-bound check is |
| + // the opposite of the constant in the upper-bound check |
| + // in 1's complement. |
| + if (!isa<ConstantSDNode>(K1) || !isa<ConstantSDNode>(K2)) |
| + return SDValue(); |
| |
| - if (!((Val1 > Val2 && isLTorLE(CC1)) || (Val1 < Val2 && isLTorLE(CC2))) || |
| - !isPowerOf2_64(PosVal + 1)) |
| - return false; |
| + int64_t Val1 = cast<ConstantSDNode>(K1)->getSExtValue(); |
| + int64_t Val2 = cast<ConstantSDNode>(K2)->getSExtValue(); |
| + int64_t PosVal = std::max(Val1, Val2); |
| + int64_t NegVal = std::min(Val1, Val2); |
| |
| - // Handle the difference between USAT (unsigned) and SSAT (signed) |
| - // saturation |
| - if (Val1 == ~Val2) |
| - Usat = false; |
| - else if (NegVal == 0) |
| - Usat = true; |
| - else |
| - return false; |
| + if (!((Val1 > Val2 && isLTorLE(CC1)) || (Val1 < Val2 && isLTorLE(CC2))) || |
| + !isPowerOf2_64(PosVal + 1)) |
| + return SDValue(); |
| |
| - V = V2Tmp; |
| - // At this point, PosVal is guaranteed to be positive |
| - K = (uint64_t) PosVal; |
| + // Handle the difference between USAT (unsigned) and SSAT (signed) |
| + // saturation |
| + // At this point, PosVal is guaranteed to be positive |
| + uint64_t K = PosVal; |
| + SDLoc dl(Op); |
| + if (Val1 == ~Val2) |
| + return DAG.getNode(ARMISD::SSAT, dl, VT, V2Tmp, |
| + DAG.getConstant(countTrailingOnes(K), dl, VT)); |
| + if (NegVal == 0) |
| + return DAG.getNode(ARMISD::USAT, dl, VT, V2Tmp, |
| + DAG.getConstant(countTrailingOnes(K), dl, VT)); |
| |
| - return true; |
| - } |
| - return false; |
| + return SDValue(); |
| } |
| |
| // Check if a condition of the type x < k ? k : x can be converted into a |
| @@ -5168,18 +5162,9 @@ SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { |
| SDLoc dl(Op); |
| |
| // Try to convert two saturating conditional selects into a single SSAT |
| - SDValue SatValue; |
| - uint64_t SatConstant; |
| - bool SatUSat; |
| - if (((!Subtarget->isThumb() && Subtarget->hasV6Ops()) || Subtarget->isThumb2()) && |
| - isSaturatingConditional(Op, SatValue, SatConstant, SatUSat)) { |
| - if (SatUSat) |
| - return DAG.getNode(ARMISD::USAT, dl, VT, SatValue, |
| - DAG.getConstant(countTrailingOnes(SatConstant), dl, VT)); |
| - else |
| - return DAG.getNode(ARMISD::SSAT, dl, VT, SatValue, |
| - DAG.getConstant(countTrailingOnes(SatConstant), dl, VT)); |
| - } |
| + if ((!Subtarget->isThumb() && Subtarget->hasV6Ops()) || Subtarget->isThumb2()) |
| + if (SDValue SatValue = LowerSaturatingConditional(Op, DAG)) |
| + return SatValue; |
| |
| // Try to convert expressions of the form x < k ? k : x (and similar forms) |
| // into more efficient bit operations, which is possible when k is 0 or -1 |
| @@ -5188,6 +5173,7 @@ SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { |
| // instructions. |
| // Only allow this transformation on full-width (32-bit) operations |
| SDValue LowerSatConstant; |
| + SDValue SatValue; |
| if (VT == MVT::i32 && |
| isLowerSaturatingConditional(Op, SatValue, LowerSatConstant)) { |
| SDValue ShiftV = DAG.getNode(ISD::SRA, dl, VT, SatValue, |