forked from OSchip/llvm-project
[DAG] Fold (X & Y) != 0 --> zextOrTrunc(X & Y) iff everything but LSB is known zero (PR51312)
Fixes parity codegen issue where we know all but the lowest bit is zero, we can replace the ICMPNE with 0 comparison with a ext/trunc Differential Revision: https://reviews.llvm.org/D117983
This commit is contained in:
parent
116ab78694
commit
7c66aaddb1
|
@ -3254,17 +3254,29 @@ bool TargetLowering::isExtendedTrueVal(const ConstantSDNode *N, EVT VT,
|
|||
SDValue TargetLowering::foldSetCCWithAnd(EVT VT, SDValue N0, SDValue N1,
|
||||
ISD::CondCode Cond, const SDLoc &DL,
|
||||
DAGCombinerInfo &DCI) const {
|
||||
// Match these patterns in any of their permutations:
|
||||
// (X & Y) == Y
|
||||
// (X & Y) != Y
|
||||
if (N1.getOpcode() == ISD::AND && N0.getOpcode() != ISD::AND)
|
||||
std::swap(N0, N1);
|
||||
|
||||
SelectionDAG &DAG = DCI.DAG;
|
||||
EVT OpVT = N0.getValueType();
|
||||
if (N0.getOpcode() != ISD::AND || !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(VT) == TargetLowering::UndefinedBooleanContent ||
|
||||
getBooleanContents(VT) == 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);
|
||||
}
|
||||
|
||||
// Match these patterns in any of their permutations:
|
||||
// (X & Y) == Y
|
||||
// (X & Y) != Y
|
||||
SDValue X, Y;
|
||||
if (N0.getOperand(0) == N1) {
|
||||
X = N0.getOperand(1);
|
||||
|
@ -3276,7 +3288,6 @@ SDValue TargetLowering::foldSetCCWithAnd(EVT VT, SDValue N0, SDValue N1,
|
|||
return SDValue();
|
||||
}
|
||||
|
||||
SelectionDAG &DAG = DCI.DAG;
|
||||
SDValue Zero = DAG.getConstant(0, DL, OpVT);
|
||||
if (DAG.isKnownToBeAPowerOfTwo(Y)) {
|
||||
// Simplify X & Y == Y to X & Y != 0 if Y has exactly one bit set.
|
||||
|
|
|
@ -36,8 +36,8 @@ define i1 @canonical_parity(<16 x i1> %x) {
|
|||
; POPCNT-NEXT: psllw $7, %xmm0
|
||||
; POPCNT-NEXT: pmovmskb %xmm0, %eax
|
||||
; POPCNT-NEXT: popcntl %eax, %eax
|
||||
; POPCNT-NEXT: testb $1, %al
|
||||
; POPCNT-NEXT: setne %al
|
||||
; POPCNT-NEXT: andl $1, %eax
|
||||
; POPCNT-NEXT: # kill: def $al killed $al killed $eax
|
||||
; POPCNT-NEXT: retq
|
||||
%i1 = bitcast <16 x i1> %x to i16
|
||||
%i2 = call i16 @llvm.ctpop.i16(i16 %i1)
|
||||
|
|
Loading…
Reference in New Issue