@@ -4054,8 +4054,9 @@ SDValue AArch64TargetLowering::LowerSELECT_CC(ISD::CondCode CC, SDValue LHS,
4054
4054
4055
4055
// Avoid materializing a constant when possible by reusing a known value in
4056
4056
// a register. However, don't perform this optimization if the known value
4057
- // is one, zero or negative one. We can always materialize these values
4058
- // using CSINC, CSEL and CSINV with wzr/xzr as the FVal, respectively.
4057
+ // is one, zero or negative one in the case of a CSEL. We can always
4058
+ // materialize these values using CSINC, CSEL and CSINV with wzr/xzr as the
4059
+ // FVal, respectively.
4059
4060
ConstantSDNode *RHSVal = dyn_cast<ConstantSDNode>(RHS);
4060
4061
if (Opcode == AArch64ISD::CSEL && RHSVal && !RHSVal->isOne () &&
4061
4062
!RHSVal->isNullValue () && !RHSVal->isAllOnesValue ()) {
@@ -4066,6 +4067,16 @@ SDValue AArch64TargetLowering::LowerSELECT_CC(ISD::CondCode CC, SDValue LHS,
4066
4067
TVal = LHS;
4067
4068
else if (CFVal && CFVal == RHSVal && AArch64CC == AArch64CC::NE)
4068
4069
FVal = LHS;
4070
+ } else if (Opcode == AArch64ISD::CSNEG && RHSVal && RHSVal->isOne ()) {
4071
+ assert (CTVal && CFVal && " Expected constant operands for CSNEG." );
4072
+ // Use a CSINV to transform "a == C ? 1 : -1" to "a == C ? a : -1" to
4073
+ // avoid materializing C.
4074
+ AArch64CC::CondCode AArch64CC = changeIntCCToAArch64CC (CC);
4075
+ if (CTVal == RHSVal && AArch64CC == AArch64CC::EQ) {
4076
+ Opcode = AArch64ISD::CSINV;
4077
+ TVal = LHS;
4078
+ FVal = DAG.getConstant (0 , dl, FVal.getValueType ());
4079
+ }
4069
4080
}
4070
4081
4071
4082
SDValue CCVal;
0 commit comments