Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -39877,18 +39877,24 @@ // Try to combine sext_in_reg of a cmov of constants by extending the constants. static SDValue combineSextInRegCmov(SDNode *N, SelectionDAG &DAG) { + assert(N->getOpcode() == ISD::SIGN_EXTEND_INREG); + EVT VT = N->getValueType(0); SDValue N0 = N->getOperand(0); SDValue N1 = N->getOperand(1); EVT ExtraVT = cast(N1)->getVT(); - if (ExtraVT != MVT::i16) + if (ExtraVT != MVT::i8 && ExtraVT != MVT::i16) return SDValue(); - // Look through single use any_extends. - if (N0.getOpcode() == ISD::ANY_EXTEND && N0.hasOneUse()) + // Look through single use any_extends / truncs. + SDValue IntemediateBitwidthOp; + if ((N0.getOpcode() == ISD::ANY_EXTEND || N0.getOpcode() == ISD::TRUNCATE) && + N0.hasOneUse()) { + IntemediateBitwidthOp = N0; N0 = N0.getOperand(0); + } // See if we have a single use cmov. if (N0.getOpcode() != X86ISD::CMOV || !N0.hasOneUse()) @@ -39904,10 +39910,10 @@ SDLoc DL(N); - // If we looked through an any_extend above, add one to the constants. - if (N0.getValueType() != VT) { - CMovOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, VT, CMovOp0); - CMovOp1 = DAG.getNode(ISD::ANY_EXTEND, DL, VT, CMovOp1); + // If we looked through an any_extend/trunc above, add one to the constants. + if (IntemediateBitwidthOp) { + CMovOp0 = DAG.getNode(IntemediateBitwidthOp.getOpcode(), DL, VT, CMovOp0); + CMovOp1 = DAG.getNode(IntemediateBitwidthOp.getOpcode(), DL, VT, CMovOp1); } CMovOp0 = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, CMovOp0, N1); @@ -39919,6 +39925,8 @@ static SDValue combineSignExtendInReg(SDNode *N, SelectionDAG &DAG, const X86Subtarget &Subtarget) { + assert(N->getOpcode() == ISD::SIGN_EXTEND_INREG); + if (SDValue V = combineSextInRegCmov(N, DAG)) return V; Index: test/CodeGen/X86/cmov-promotion.ll =================================================================== --- test/CodeGen/X86/cmov-promotion.ll +++ test/CodeGen/X86/cmov-promotion.ll @@ -152,11 +152,9 @@ ; CMOV-LABEL: cmov_spromotion_8_to_16: ; CMOV: # %bb.0: ; CMOV-NEXT: testb $1, %dil -; CMOV-NEXT: movl $117, %eax -; CMOV-NEXT: movl $237, %ecx -; CMOV-NEXT: cmovnel %eax, %ecx -; CMOV-NEXT: movsbl %cl, %eax -; CMOV-NEXT: # kill: def $ax killed $ax killed $eax +; CMOV-NEXT: movw $117, %cx +; CMOV-NEXT: movw $-19, %ax +; CMOV-NEXT: cmovnew %cx, %ax ; CMOV-NEXT: retq ; ; NO_CMOV-LABEL: cmov_spromotion_8_to_16: @@ -179,10 +177,9 @@ ; CMOV-LABEL: cmov_spromotion_8_to_32: ; CMOV: # %bb.0: ; CMOV-NEXT: testb $1, %dil -; CMOV-NEXT: movl $126, %eax -; CMOV-NEXT: movl $255, %ecx -; CMOV-NEXT: cmovnel %eax, %ecx -; CMOV-NEXT: movsbl %cl, %eax +; CMOV-NEXT: movl $126, %ecx +; CMOV-NEXT: movl $-1, %eax +; CMOV-NEXT: cmovnel %ecx, %eax ; CMOV-NEXT: retq ; ; NO_CMOV-LABEL: cmov_spromotion_8_to_32: @@ -204,10 +201,9 @@ ; CMOV-LABEL: cmov_spromotion_8_to_64: ; CMOV: # %bb.0: ; CMOV-NEXT: testb $1, %dil -; CMOV-NEXT: movl $126, %eax -; CMOV-NEXT: movl $255, %ecx -; CMOV-NEXT: cmovnel %eax, %ecx -; CMOV-NEXT: movsbq %cl, %rax +; CMOV-NEXT: movl $126, %ecx +; CMOV-NEXT: movq $-1, %rax +; CMOV-NEXT: cmovneq %rcx, %rax ; CMOV-NEXT: retq ; ; NO_CMOV-LABEL: cmov_spromotion_8_to_64: