Index: lib/Target/X86/X86ISelDAGToDAG.cpp =================================================================== --- lib/Target/X86/X86ISelDAGToDAG.cpp +++ lib/Target/X86/X86ISelDAGToDAG.cpp @@ -2638,6 +2638,51 @@ } break; } + + case ISD::ZERO_EXTEND: { + if (NVT != MVT::i32) + break; + + SDValue N0 = Node->getOperand(0); + if (N0->getOpcode() != X86ISD::SETCC) + break; + + SDValue N01 = N0->getOperand(1); + + // 0 = xor r,r. This clobbers EFLAGS; let the scheduler figure that out. + SDValue Zero = SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, NVT), 0); + + // Select the things below us, if they haven't been selected already. + Select(N01.getNode()); + + // Copy the flags out whatever's below us. Produce a glue. + SDValue Flags = + CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS, + N01, /*Glue=*/SDValue()); + + // Pick a SETCC opcode. + unsigned SetCCOpc = + X86::getSETFromCond((X86::CondCode)N0->getConstantOperandVal(0)); + + // Now we can select our node; make abundant use of glue. + SDNode *SetCC = CurDAG->getMachineNode(SetCCOpc, SDLoc(N0), MVT::i8, + MVT::Glue, Flags.getValue(1)); + + // And insert it into the zero reg, gluing again. + SDNode *NewNode = CurDAG->getMachineNode( + X86::INSERT_SUBREG, dl, MVT::i32, + {Zero, N0, CurDAG->getTargetConstant(X86::sub_8bit, dl, MVT::i32), + SDValue(SetCC, 1)}); + + ReplaceUses(N0, SDValue(SetCC, 0)); + ReplaceUses(SDValue(Node, 0), SDValue(NewNode, 0)); + + CurDAG->RemoveDeadNode(N0.getNode()); + CurDAG->RemoveDeadNode(Node); + return; + } + + case ISD::STORE: { // Change a chain of {load; incr or dec; store} of the same value into // a simple increment or decrement through memory of that value, if the