[llvm] 8d37ed1 - [ARM] Extract code for forming CSINV etc (NFC)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 12 09:51:53 PDT 2026
Author: Nikita Popov
Date: 2026-03-12T17:51:43+01:00
New Revision: 8d37ed127e74569217505e3fe99480f278e1a95c
URL: https://github.com/llvm/llvm-project/commit/8d37ed127e74569217505e3fe99480f278e1a95c
DIFF: https://github.com/llvm/llvm-project/commit/8d37ed127e74569217505e3fe99480f278e1a95c.diff
LOG: [ARM] Extract code for forming CSINV etc (NFC)
Added:
Modified:
llvm/lib/Target/ARM/ARMISelLowering.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 87b55f53b7dd1..228ed68e386b4 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -5096,6 +5096,54 @@ bool ARMTargetLowering::isUnsupportedFloatingType(EVT VT) const {
return false;
}
+static SDValue matchCSET(unsigned &Opcode, bool &InvertCond, SDValue TrueVal,
+ SDValue FalseVal, const ARMSubtarget *Subtarget) {
+ ConstantSDNode *CFVal = dyn_cast<ConstantSDNode>(FalseVal);
+ ConstantSDNode *CTVal = dyn_cast<ConstantSDNode>(TrueVal);
+ if (!CFVal || !CTVal || !Subtarget->hasV8_1MMainlineOps())
+ return SDValue();
+
+ unsigned TVal = CTVal->getZExtValue();
+ unsigned FVal = CFVal->getZExtValue();
+
+ Opcode = 0;
+ InvertCond = false;
+ if (TVal == ~FVal) {
+ Opcode = ARMISD::CSINV;
+ } else if (TVal == ~FVal + 1) {
+ Opcode = ARMISD::CSNEG;
+ } else if (TVal + 1 == FVal) {
+ Opcode = ARMISD::CSINC;
+ } else if (TVal == FVal + 1) {
+ Opcode = ARMISD::CSINC;
+ std::swap(TrueVal, FalseVal);
+ std::swap(TVal, FVal);
+ InvertCond = !InvertCond;
+ } else {
+ return SDValue();
+ }
+
+ // If one of the constants is cheaper than another, materialise the
+ // cheaper one and let the csel generate the other.
+ if (Opcode != ARMISD::CSINC &&
+ HasLowerConstantMaterializationCost(FVal, TVal, Subtarget)) {
+ std::swap(TrueVal, FalseVal);
+ std::swap(TVal, FVal);
+ InvertCond = !InvertCond;
+ }
+
+ // Attempt to use ZR checking TVal is 0, possibly inverting the condition
+ // to get there. CSINC not is invertable like the other two (~(~a) == a,
+ // -(-a) == a, but (a+1)+1 != a).
+ if (FVal == 0 && Opcode != ARMISD::CSINC) {
+ std::swap(TrueVal, FalseVal);
+ std::swap(TVal, FVal);
+ InvertCond = !InvertCond;
+ }
+
+ return TrueVal;
+}
+
SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
EVT VT = Op.getValueType();
SDLoc dl(Op);
@@ -5131,7 +5179,6 @@ SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
SDValue TrueVal = Op.getOperand(2);
SDValue FalseVal = Op.getOperand(3);
ConstantSDNode *CFVal = dyn_cast<ConstantSDNode>(FalseVal);
- ConstantSDNode *CTVal = dyn_cast<ConstantSDNode>(TrueVal);
ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS);
if (Op.getValueType().isInteger()) {
@@ -5154,51 +5201,18 @@ SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
}
}
- if (Subtarget->hasV8_1MMainlineOps() && CFVal && CTVal &&
- LHS.getValueType() == MVT::i32 && RHS.getValueType() == MVT::i32) {
- unsigned TVal = CTVal->getZExtValue();
- unsigned FVal = CFVal->getZExtValue();
- unsigned Opcode = 0;
-
- if (TVal == ~FVal) {
- Opcode = ARMISD::CSINV;
- } else if (TVal == ~FVal + 1) {
- Opcode = ARMISD::CSNEG;
- } else if (TVal + 1 == FVal) {
- Opcode = ARMISD::CSINC;
- } else if (TVal == FVal + 1) {
- Opcode = ARMISD::CSINC;
- std::swap(TrueVal, FalseVal);
- std::swap(TVal, FVal);
- CC = ISD::getSetCCInverse(CC, LHS.getValueType());
- }
-
- if (Opcode) {
- // If one of the constants is cheaper than another, materialise the
- // cheaper one and let the csel generate the other.
- if (Opcode != ARMISD::CSINC &&
- HasLowerConstantMaterializationCost(FVal, TVal, Subtarget)) {
- std::swap(TrueVal, FalseVal);
- std::swap(TVal, FVal);
- CC = ISD::getSetCCInverse(CC, LHS.getValueType());
- }
-
- // Attempt to use ZR checking TVal is 0, possibly inverting the condition
- // to get there. CSINC not is invertable like the other two (~(~a) == a,
- // -(-a) == a, but (a+1)+1 != a).
- if (FVal == 0 && Opcode != ARMISD::CSINC) {
- std::swap(TrueVal, FalseVal);
- std::swap(TVal, FVal);
+ if (LHS.getValueType() == MVT::i32) {
+ unsigned Opcode;
+ bool InvertCond;
+ if (SDValue Op =
+ matchCSET(Opcode, InvertCond, TrueVal, FalseVal, Subtarget)) {
+ if (InvertCond)
CC = ISD::getSetCCInverse(CC, LHS.getValueType());
- }
-
- // Drops F's value because we can get it by inverting/negating TVal.
- FalseVal = TrueVal;
SDValue ARMcc;
SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
- EVT VT = TrueVal.getValueType();
- return DAG.getNode(Opcode, dl, VT, TrueVal, FalseVal, ARMcc, Cmp);
+ EVT VT = Op.getValueType();
+ return DAG.getNode(Opcode, dl, VT, Op, Op, ARMcc, Cmp);
}
}
More information about the llvm-commits
mailing list