@@ -5907,8 +5907,8 @@ static SDValue foldAndOrOfSETCC(SDNode *LogicOp, SelectionDAG &DAG) {
5907
5907
SDValue LHS1 = LHS->getOperand(1);
5908
5908
SDValue RHS1 = RHS->getOperand(1);
5909
5909
5910
- // TODO: We don't actually need a splat here, for vectors we just need
5911
- // LaneLHS[N] == -LaneRHS[N];
5910
+ // TODO: We don't actually need a splat here, for vectors we just need the
5911
+ // invariants to hold for each element.
5912
5912
auto *LHS1C = isConstOrConstSplat(LHS1);
5913
5913
auto *RHS1C = isConstOrConstSplat(RHS1);
5914
5914
@@ -5919,15 +5919,16 @@ static SDValue foldAndOrOfSETCC(SDNode *LogicOp, SelectionDAG &DAG) {
5919
5919
if (CCL == CCR &&
5920
5920
CCL == (LogicOp->getOpcode() == ISD::AND ? ISD::SETNE : ISD::SETEQ) &&
5921
5921
LHS0 == RHS0 && LHS1C && RHS1C && OpVT.isInteger() && LHS.hasOneUse() &&
5922
- RHS.hasOneUse() && LHS1C->getAPIntValue() == (-RHS1C->getAPIntValue())) {
5922
+ RHS.hasOneUse()) {
5923
+ const APInt &APLhs = LHS1C->getAPIntValue();
5924
+ const APInt &APRhs = RHS1C->getAPIntValue();
5923
5925
5924
5926
// Preference is to use ISD::ABS or we already have an ISD::ABS (in which
5925
5927
// case this is just a compare).
5926
- if (TargetPreference == AndOrSETCCFoldKind::ABS ||
5927
- DAG.doesNodeExist(ISD::ABS, DAG.getVTList(OpVT), {LHS0})) {
5928
- APInt C = LHS1C->getAPIntValue();
5929
- if (C.isNegative())
5930
- C = RHS1C->getAPIntValue();
5928
+ if (APLhs == (-APRhs) &&
5929
+ (TargetPreference == AndOrSETCCFoldKind::ABS ||
5930
+ DAG.doesNodeExist(ISD::ABS, DAG.getVTList(OpVT), {LHS0}))) {
5931
+ const APInt &C = APLhs.isNegative() ? APRhs : APLhs;
5931
5932
// (icmp eq A, C) | (icmp eq A, -C)
5932
5933
// -> (icmp eq Abs(A), C)
5933
5934
// (icmp ne A, C) & (icmp ne A, -C)
@@ -5936,23 +5937,20 @@ static SDValue foldAndOrOfSETCC(SDNode *LogicOp, SelectionDAG &DAG) {
5936
5937
return DAG.getNode(ISD::SETCC, DL, VT, AbsOp,
5937
5938
DAG.getConstant(C, DL, OpVT), LHS.getOperand(2));
5938
5939
} else if (TargetPreference == AndOrSETCCFoldKind::AddAnd) {
5939
- // With C as a power of 2 and C != 0 and C != INT_MIN:
5940
- // (icmp eq A, C) | (icmp eq A, -C)
5941
- // -> (icmp eq and(add(A, C), ~(C + C)), 0)
5942
- // (icmp ne A, C) & (icmp ne A, -C)w
5943
- // -> (icmp ne and(add(A, C), ~(C + C)), 0)
5944
- const ConstantSDNode *Pow2 = nullptr;
5945
- if (LHS1C->getAPIntValue().isPowerOf2())
5946
- Pow2 = LHS1C;
5947
- else if (RHS1C->getAPIntValue().isPowerOf2())
5948
- Pow2 = RHS1C;
5949
- // isPowerOf2 is only for non-zero powers of 2.
5950
- if (Pow2 != nullptr && !Pow2->getAPIntValue().isMinSignedValue()) {
5951
- const APInt &C = Pow2->getAPIntValue();
5952
- SDValue AddOp =
5953
- DAG.getNode(ISD::ADD, DL, OpVT, LHS0, DAG.getConstant(C, DL, OpVT));
5940
+ // A == C0 | A == C1
5941
+ // IF IsPow2(smax(C0, C1)-smin(C0, C1))
5942
+ // -> ((A - smin(C0, C1)) & ~(smax(C0, C1)-smin(C0, C1))) == 0
5943
+ // A != C0 & A != C1
5944
+ // IF IsPow2(smax(C0, C1)-smin(C0, C1))
5945
+ // -> ((A - smin(C0, C1)) & ~(smax(C0, C1)-smin(C0, C1))) != 0
5946
+ const APInt &MaxC = APIntOps::smax(APRhs, APLhs);
5947
+ const APInt &MinC = APIntOps::smin(APRhs, APLhs);
5948
+ APInt Dif = MaxC - MinC;
5949
+ if (!Dif.isZero() && Dif.isPowerOf2()) {
5950
+ SDValue AddOp = DAG.getNode(ISD::ADD, DL, OpVT, LHS0,
5951
+ DAG.getConstant(-MinC, DL, OpVT));
5954
5952
SDValue AndOp = DAG.getNode(ISD::AND, DL, OpVT, AddOp,
5955
- DAG.getConstant(~(C + C) , DL, OpVT));
5953
+ DAG.getConstant(~Dif , DL, OpVT));
5956
5954
return DAG.getNode(ISD::SETCC, DL, VT, AndOp,
5957
5955
DAG.getConstant(0, DL, OpVT), LHS.getOperand(2));
5958
5956
}
0 commit comments