Skip to content

Conversation

@AZero13
Copy link
Contributor

@AZero13 AZero13 commented Jun 27, 2025

No description provided.

@llvmbot llvmbot added the llvm:SelectionDAG SelectionDAGISel as well label Jun 27, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 27, 2025

@llvm/pr-subscribers-llvm-selectiondag

Author: AZero13 (AZero13)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/146079.diff

1 Files Affected:

  • (modified) llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp (+25-2)
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 000f8cc6786a5..62faf3cb1d8c8 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -4240,14 +4240,26 @@ SDValue TargetLowering::foldSetCCWithOr(EVT VT, SDValue N0, SDValue N1, SelectionDAG &DAG = DCI.DAG; EVT OpVT = N0.getValueType(); - if (!N0.hasOneUse() || !OpVT.isInteger() || + if (N0.getOpcode() != ISD::OR || !OpVT.isInteger() || (Cond != ISD::SETEQ && Cond != ISD::SETNE)) return SDValue(); + // (X | Y) != 0 --> zextOrTrunc(X | Y) + // iff everything but LSB is known zero: + if (Cond == ISD::SETNE && isNullConstant(N1) && + (getBooleanContents(OpVT) == TargetLowering::UndefinedBooleanContent || + getBooleanContents(OpVT) == TargetLowering::ZeroOrOneBooleanContent)) { + unsigned NumEltBits = OpVT.getScalarSizeInBits(); + APInt UpperBits = APInt::getHighBitsSet(NumEltBits, NumEltBits - 1); + if (DAG.MaskedValueIsZero(N0, UpperBits)) + return DAG.getBoolExtOrTrunc(N0, DL, VT, OpVT); + } + // (X | Y) == Y // (X | Y) != Y SDValue X; - if (sd_match(N0, m_Or(m_Value(X), m_Specific(N1))) && hasAndNotCompare(N1)) { + if (N0.hasOneUse() && sd_match(N0, m_Or(m_Value(X), m_Specific(N1))) && + hasAndNotCompare(N1)) { // If the target supports an 'and-not' or 'and-complement' logic operation, // try to use that to make a comparison operation more efficient. @@ -4447,6 +4459,17 @@ SDValue TargetLowering::foldSetCCWithBinOp(EVT VT, SDValue N0, SDValue N1, if (X == N1) return DAG.getSetCC(DL, VT, Y, DAG.getConstant(0, DL, OpVT), Cond); + // (X ^ Y) != 0 --> zextOrTrunc(X ^ Y) + // iff everything but LSB is known zero: + if (BOpcode == ISD::XOR && Cond == ISD::SETNE && isNullConstant(N1) && + (getBooleanContents(OpVT) == TargetLowering::UndefinedBooleanContent || + getBooleanContents(OpVT) == TargetLowering::ZeroOrOneBooleanContent)) { + unsigned NumEltBits = OpVT.getScalarSizeInBits(); + APInt UpperBits = APInt::getHighBitsSet(NumEltBits, NumEltBits - 1); + if (DAG.MaskedValueIsZero(N0, UpperBits)) + return DAG.getBoolExtOrTrunc(N0, DL, VT, OpVT); + } + if (Y != N1) return SDValue(); 
Copy link
Contributor

@arsenm arsenm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

llvm:SelectionDAG SelectionDAGISel as well

3 participants