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 @@ -9923,16 +9923,23 @@ // However when after the source operand of SRL is optimized into AND, the SRL // itself may not be optimized further. Look for it and add the BRCOND into // the worklist. + // + // The also tends to happen for binary operations when SimplifyDemandedBits + // is involved. + // + // FIXME: This is unecessary if we process the DAG in topological order, + // which we plan to do. This workaround can be removed once the DAG is + // processed in topological order. if (N->hasOneUse()) { SDNode *Use = *N->use_begin(); - if (Use->getOpcode() == ISD::BRCOND) - AddToWorklist(Use); - else if (Use->getOpcode() == ISD::TRUNCATE && Use->hasOneUse()) { - // Also look pass the truncate. + + // Look pass the truncate. + if (Use->getOpcode() == ISD::TRUNCATE && Use->hasOneUse()) Use = *Use->use_begin(); - if (Use->getOpcode() == ISD::BRCOND) - AddToWorklist(Use); - } + + if (Use->getOpcode() == ISD::BRCOND || Use->getOpcode() == ISD::AND || + Use->getOpcode() == ISD::OR || Use->getOpcode() == ISD::XOR) + AddToWorklist(Use); } // Try to transform this shift into a multiply-high if diff --git a/llvm/test/CodeGen/X86/bool-math.ll b/llvm/test/CodeGen/X86/bool-math.ll --- a/llvm/test/CodeGen/X86/bool-math.ll +++ b/llvm/test/CodeGen/X86/bool-math.ll @@ -262,10 +262,9 @@ define i1 @opaque_constant(i48 %x, i48 %y) { ; X64-LABEL: opaque_constant: ; X64: # %bb.0: -; X64-NEXT: movq %rsi, %rax -; X64-NEXT: shrq $32, %rdi +; X64-NEXT: movq %rdi, %rax +; X64-NEXT: xorq %rsi, %rax ; X64-NEXT: shrq $32, %rax -; X64-NEXT: xorl %edi, %eax ; X64-NEXT: andl $1, %eax ; X64-NEXT: # kill: def $al killed $al killed $rax ; X64-NEXT: retq