diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index ec37585de9ad..6df807250022 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -36047,14 +36047,15 @@ static SDValue combineToExtendCMOV(SDNode *Extend, SelectionDAG &DAG) { if (TargetVT != MVT::i32 && TargetVT != MVT::i64) return SDValue(); - // Only extend from i16. - if (VT != MVT::i16) + // Only extend from i16 unless its a sign_extend from i32. Zext/aext from i32 + // are free. + if (VT != MVT::i16 && !(ExtendOpcode == ISD::SIGN_EXTEND && VT == MVT::i32)) return SDValue(); // If this a zero extend to i64, we should only extend to i32 and use a free // zero extend to finish. EVT ExtendVT = TargetVT; - if (TargetVT == MVT::i64 && ExtendOpcode == ISD::ZERO_EXTEND) + if (TargetVT == MVT::i64 && ExtendOpcode != ISD::SIGN_EXTEND) ExtendVT = MVT::i32; CMovOp0 = DAG.getNode(ExtendOpcode, DL, ExtendVT, CMovOp0); @@ -36065,7 +36066,7 @@ static SDValue combineToExtendCMOV(SDNode *Extend, SelectionDAG &DAG) { // Finish extending if needed. if (ExtendVT != TargetVT) - Res = DAG.getNode(ISD::ZERO_EXTEND, DL, TargetVT, Res); + Res = DAG.getNode(ExtendOpcode, DL, TargetVT, Res); return Res; } diff --git a/llvm/test/CodeGen/X86/cmov-promotion.ll b/llvm/test/CodeGen/X86/cmov-promotion.ll index 9dc137aab287..59ddc77b9c75 100644 --- a/llvm/test/CodeGen/X86/cmov-promotion.ll +++ b/llvm/test/CodeGen/X86/cmov-promotion.ll @@ -294,10 +294,9 @@ define i64 @cmov_spromotion_32_to_64(i1 %c) { ; CMOV-LABEL: cmov_spromotion_32_to_64: ; CMOV: # %bb.0: ; CMOV-NEXT: testb $1, %dil -; CMOV-NEXT: movl $12414, %eax # imm = 0x307E -; CMOV-NEXT: movl $-1, %ecx -; CMOV-NEXT: cmovnel %eax, %ecx -; CMOV-NEXT: movslq %ecx, %rax +; CMOV-NEXT: movl $12414, %ecx # imm = 0x307E +; CMOV-NEXT: movq $-1, %rax +; CMOV-NEXT: cmovneq %rcx, %rax ; CMOV-NEXT: retq ; ; NO_CMOV-LABEL: cmov_spromotion_32_to_64: diff --git a/llvm/test/CodeGen/X86/vector-compare-all_of.ll b/llvm/test/CodeGen/X86/vector-compare-all_of.ll index 0a756dfc8a4c..f419b30e5499 100644 --- a/llvm/test/CodeGen/X86/vector-compare-all_of.ll +++ b/llvm/test/CodeGen/X86/vector-compare-all_of.ll @@ -87,9 +87,8 @@ define i64 @test_v4f64_legal_sext(<4 x double> %a0, <4 x double> %a1) { ; SSE-NEXT: movmskps %xmm2, %eax ; SSE-NEXT: xorl %ecx, %ecx ; SSE-NEXT: cmpl $15, %eax -; SSE-NEXT: movl $-1, %eax -; SSE-NEXT: cmovnel %ecx, %eax -; SSE-NEXT: cltq +; SSE-NEXT: movq $-1, %rax +; SSE-NEXT: cmovneq %rcx, %rax ; SSE-NEXT: retq ; ; AVX-LABEL: test_v4f64_legal_sext: @@ -100,9 +99,8 @@ define i64 @test_v4f64_legal_sext(<4 x double> %a0, <4 x double> %a1) { ; AVX-NEXT: vmovmskps %xmm0, %eax ; AVX-NEXT: xorl %ecx, %ecx ; AVX-NEXT: cmpl $15, %eax -; AVX-NEXT: movl $-1, %eax -; AVX-NEXT: cmovnel %ecx, %eax -; AVX-NEXT: cltq +; AVX-NEXT: movq $-1, %rax +; AVX-NEXT: cmovneq %rcx, %rax ; AVX-NEXT: vzeroupper ; AVX-NEXT: retq ; @@ -369,9 +367,8 @@ define i64 @test_v4i64_legal_sext(<4 x i64> %a0, <4 x i64> %a1) { ; SSE-NEXT: movmskps %xmm0, %eax ; SSE-NEXT: xorl %ecx, %ecx ; SSE-NEXT: cmpl $15, %eax -; SSE-NEXT: movl $-1, %eax -; SSE-NEXT: cmovnel %ecx, %eax -; SSE-NEXT: cltq +; SSE-NEXT: movq $-1, %rax +; SSE-NEXT: cmovneq %rcx, %rax ; SSE-NEXT: retq ; ; AVX1-LABEL: test_v4i64_legal_sext: @@ -384,9 +381,8 @@ define i64 @test_v4i64_legal_sext(<4 x i64> %a0, <4 x i64> %a1) { ; AVX1-NEXT: vmovmskps %xmm0, %eax ; AVX1-NEXT: xorl %ecx, %ecx ; AVX1-NEXT: cmpl $15, %eax -; AVX1-NEXT: movl $-1, %eax -; AVX1-NEXT: cmovnel %ecx, %eax -; AVX1-NEXT: cltq +; AVX1-NEXT: movq $-1, %rax +; AVX1-NEXT: cmovneq %rcx, %rax ; AVX1-NEXT: vzeroupper ; AVX1-NEXT: retq ; @@ -398,9 +394,8 @@ define i64 @test_v4i64_legal_sext(<4 x i64> %a0, <4 x i64> %a1) { ; AVX2-NEXT: vmovmskps %xmm0, %eax ; AVX2-NEXT: xorl %ecx, %ecx ; AVX2-NEXT: cmpl $15, %eax -; AVX2-NEXT: movl $-1, %eax -; AVX2-NEXT: cmovnel %ecx, %eax -; AVX2-NEXT: cltq +; AVX2-NEXT: movq $-1, %rax +; AVX2-NEXT: cmovneq %rcx, %rax ; AVX2-NEXT: vzeroupper ; AVX2-NEXT: retq ;