blob: bde5e03cf90388c41d783aaeda4233d60eed8015 [file] [log] [blame]
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,