diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2793,16 +2793,26 @@ /// the opcode and bypass the mask operation. static SDValue foldAddSubMasked1(bool IsAdd, SDValue N0, SDValue N1, SelectionDAG &DAG, const SDLoc &DL) { + if (N1.getOpcode() == ISD::ZERO_EXTEND) + N1 = N1.getOperand(0); + if (N1.getOpcode() != ISD::AND || !isOneOrOneSplat(N1->getOperand(1))) return SDValue(); EVT VT = N0.getValueType(); - if (DAG.ComputeNumSignBits(N1.getOperand(0)) != VT.getScalarSizeInBits()) + SDValue N10 = N1.getOperand(0); + if (N10.getValueType() != VT && N10.getOpcode() == ISD::TRUNCATE) + N10 = N10.getOperand(0); + + if (N10.getValueType() != VT) + return SDValue(); + + if (DAG.ComputeNumSignBits(N10) != VT.getScalarSizeInBits()) return SDValue(); // add N0, (and (AssertSext X, i1), 1) --> sub N0, X // sub N0, (and (AssertSext X, i1), 1) --> add N0, X - return DAG.getNode(IsAdd ? ISD::SUB : ISD::ADD, DL, VT, N0, N1.getOperand(0)); + return DAG.getNode(IsAdd ? ISD::SUB : ISD::ADD, DL, VT, N0, N10); } /// Helper for doing combines based on N0 and N1 being added to each other. diff --git a/llvm/test/CodeGen/X86/known-signbits-vector.ll b/llvm/test/CodeGen/X86/known-signbits-vector.ll --- a/llvm/test/CodeGen/X86/known-signbits-vector.ll +++ b/llvm/test/CodeGen/X86/known-signbits-vector.ll @@ -679,8 +679,6 @@ ; X64: # %bb.0: ; X64-NEXT: vcmpeqsd %xmm1, %xmm0, %xmm0 ; X64-NEXT: vmovq %xmm0, %rax -; X64-NEXT: andl $1, %eax -; X64-NEXT: negq %rax ; X64-NEXT: retq %3 = fcmp oeq double %0, %1 %4 = sext i1 %3 to i64