[llvm] [X86] Extend checkSignTestSetCCCombine to handle SHL/SIGN_EXTEND_INREG (PR #178376)

Abhiram Jampani via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 28 00:16:00 PST 2026


https://github.com/Abhiramjampani created https://github.com/llvm/llvm-project/pull/178376

Resolves #178246

This extends [checkSignTestSetCCCombine](cci:1://file:///D:/OpenSource/llvm-project/llvm/lib/Target/X86/X86ISelLowering.cpp:48937:0-49001:1) to also peek through `SHL` and `SIGN_EXTEND_INREG` opcodes when handling [CMP(X,0)](cci:1://file:///D:/OpenSource/llvm-project/llvm/lib/Target/X86/X86ISelLowering.cpp:58346:0-58491:1) sign bit tests.

Previously, only [CMP(SRA(X,Y),0)](cci:1://file:///D:/OpenSource/llvm-project/llvm/lib/Target/X86/X86ISelLowering.cpp:58346:0-58491:1) patterns were handled. The bitmask adjustment code for `SHL` and `SIGN_EXTEND_INREG` already existed but was unreachable in the [CMP(X,0)](cci:1://file:///D:/OpenSource/llvm-project/llvm/lib/Target/X86/X86ISelLowering.cpp:58346:0-58491:1) path due to an early return.

>From e9be2f2dd01a70d935fe01701b3e693b2aef3fdf Mon Sep 17 00:00:00 2001
From: Abhiram Jampani <lcs2022059 at iiitl.ac.in>
Date: Wed, 28 Jan 2026 13:40:51 +0530
Subject: [PATCH] [X86] checkSignTestSetCCCombine - extend to handle
 SHL/SIGN_EXTEND_INREG in CMP(X,0)

---
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  10 +-
 .../X86/fold-int-pow2-with-fmul-or-fdiv.ll    |  10 +-
 llvm/test/CodeGen/X86/is_fpclass-fp80.ll      |  22 +--
 llvm/test/CodeGen/X86/known-signbits-shl.ll   |   9 +-
 llvm/test/CodeGen/X86/sdiv_fix.ll             | 182 +++++++++---------
 llvm/test/CodeGen/X86/sdiv_fix_sat.ll         | 168 ++++++++--------
 llvm/test/CodeGen/X86/sshl_sat.ll             | 154 ++++++++-------
 .../X86/use-cr-result-of-dom-icmp-st.ll       |  18 +-
 8 files changed, 297 insertions(+), 276 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 1b3e0148262d6..9a1d76a5ade80 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -48954,9 +48954,15 @@ static SDValue checkSignTestSetCCCombine(SDValue Cmp, X86::CondCode &CC,
     // Peek through a SRA node as we just need the signbit.
     // TODO: Remove one use limit once sdiv-fix regressions are fixed.
     // TODO: Use SimplifyDemandedBits instead of just SRA?
-    if (Src.getOpcode() != ISD::SRA || !Src.hasOneUse())
+    
+    // Also allow SHL and SIGN_EXTEND_INREG patterns - the bitmask adjustment
+    // is handled below in the SHL/SIGN_EXTEND_INREG handling code.
+    if (Src.getOpcode() == ISD::SRA && Src.hasOneUse()) {
+      Src = Src.getOperand(0);
+    } else if (Src.getOpcode() != ISD::SHL &&
+               Src.getOpcode() != ISD::SIGN_EXTEND_INREG) {
       return SDValue();
-    Src = Src.getOperand(0);
+    }
   } else if (Cmp.getOpcode() == X86ISD::OR) {
     // OR(X,Y) -> see if only one operand contributes to the signbit.
     // TODO: XOR(X,Y) -> see if only one operand contributes to the signbit.
diff --git a/llvm/test/CodeGen/X86/fold-int-pow2-with-fmul-or-fdiv.ll b/llvm/test/CodeGen/X86/fold-int-pow2-with-fmul-or-fdiv.ll
index dea6b47a5961a..dc366ef252abb 100644
--- a/llvm/test/CodeGen/X86/fold-int-pow2-with-fmul-or-fdiv.ll
+++ b/llvm/test/CodeGen/X86/fold-int-pow2-with-fmul-or-fdiv.ll
@@ -1280,8 +1280,9 @@ define float @fdiv_pow_shl_cnt_fail_maybe_z(i64 %cnt) nounwind {
 ; CHECK-SSE-NEXT:    movl $8, %eax
 ; CHECK-SSE-NEXT:    # kill: def $cl killed $cl killed $rcx
 ; CHECK-SSE-NEXT:    shlq %cl, %rax
-; CHECK-SSE-NEXT:    testq %rax, %rax
-; CHECK-SSE-NEXT:    js .LBB24_1
+; CHECK-SSE-NEXT:    movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000
+; CHECK-SSE-NEXT:    testq %rcx, %rax
+; CHECK-SSE-NEXT:    jne .LBB24_1
 ; CHECK-SSE-NEXT:  # %bb.2:
 ; CHECK-SSE-NEXT:    cvtsi2ss %rax, %xmm1
 ; CHECK-SSE-NEXT:    jmp .LBB24_3
@@ -1300,8 +1301,9 @@ define float @fdiv_pow_shl_cnt_fail_maybe_z(i64 %cnt) nounwind {
 ; CHECK-AVX2-NEXT:    movl $8, %eax
 ; CHECK-AVX2-NEXT:    # kill: def $cl killed $cl killed $rcx
 ; CHECK-AVX2-NEXT:    shlq %cl, %rax
-; CHECK-AVX2-NEXT:    testq %rax, %rax
-; CHECK-AVX2-NEXT:    js .LBB24_1
+; CHECK-AVX2-NEXT:    movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000
+; CHECK-AVX2-NEXT:    testq %rcx, %rax
+; CHECK-AVX2-NEXT:    jne .LBB24_1
 ; CHECK-AVX2-NEXT:  # %bb.2:
 ; CHECK-AVX2-NEXT:    vcvtsi2ss %rax, %xmm15, %xmm0
 ; CHECK-AVX2-NEXT:    jmp .LBB24_3
diff --git a/llvm/test/CodeGen/X86/is_fpclass-fp80.ll b/llvm/test/CodeGen/X86/is_fpclass-fp80.ll
index 52d294ca01720..2d875d7689529 100644
--- a/llvm/test/CodeGen/X86/is_fpclass-fp80.ll
+++ b/llvm/test/CodeGen/X86/is_fpclass-fp80.ll
@@ -541,18 +541,18 @@ define i1 @is_negsubnormal_f80(x86_fp80 %x) nounwind {
 ; X64-LABEL: is_negsubnormal_f80:
 ; X64:       # %bb.0: # %entry
 ; X64-NEXT:    movzwl {{[0-9]+}}(%rsp), %eax
-; X64-NEXT:    movswq %ax, %rcx
-; X64-NEXT:    movq {{[0-9]+}}(%rsp), %rdx
-; X64-NEXT:    andl $32767, %eax # imm = 0x7FFF
-; X64-NEXT:    addq $-1, %rdx
-; X64-NEXT:    adcq $-1, %rax
+; X64-NEXT:    movq {{[0-9]+}}(%rsp), %rcx
+; X64-NEXT:    movl %eax, %edx
+; X64-NEXT:    andl $32767, %edx # imm = 0x7FFF
+; X64-NEXT:    addq $-1, %rcx
+; X64-NEXT:    adcq $-1, %rdx
 ; X64-NEXT:    movabsq $9223372036854775807, %rsi # imm = 0x7FFFFFFFFFFFFFFF
-; X64-NEXT:    cmpq %rsi, %rdx
-; X64-NEXT:    sbbq $0, %rax
-; X64-NEXT:    setb %dl
-; X64-NEXT:    testq %rcx, %rcx
-; X64-NEXT:    sets %al
-; X64-NEXT:    andb %dl, %al
+; X64-NEXT:    cmpq %rsi, %rcx
+; X64-NEXT:    sbbq $0, %rdx
+; X64-NEXT:    setb %cl
+; X64-NEXT:    testl $32768, %eax # imm = 0x8000
+; X64-NEXT:    setne %al
+; X64-NEXT:    andb %cl, %al
 ; X64-NEXT:    retq
 entry:
   %0 = tail call i1 @llvm.is.fpclass.f80(x86_fp80 %x, i32 16)  ; 0x10 = "-subnormal"
diff --git a/llvm/test/CodeGen/X86/known-signbits-shl.ll b/llvm/test/CodeGen/X86/known-signbits-shl.ll
index 57d557dec11b9..60d2595f730a8 100644
--- a/llvm/test/CodeGen/X86/known-signbits-shl.ll
+++ b/llvm/test/CodeGen/X86/known-signbits-shl.ll
@@ -42,10 +42,11 @@ define void @computeNumSignBits_shl_zext_2(i8 %x, ptr %p) nounwind {
 ; X64-NEXT:    movzbl %dil, %eax
 ; X64-NEXT:    movl %eax, %ecx
 ; X64-NEXT:    shll $10, %ecx
-; X64-NEXT:    xorl %edx, %edx
-; X64-NEXT:    testw %cx, %cx
-; X64-NEXT:    sets %dl
-; X64-NEXT:    addl $32767, %edx # imm = 0x7FFF
+; X64-NEXT:    movl %eax, %edx
+; X64-NEXT:    andl $32, %edx
+; X64-NEXT:    cmpw $1, %dx
+; X64-NEXT:    movl $32767, %edx # imm = 0x7FFF
+; X64-NEXT:    sbbl $-1, %edx
 ; X64-NEXT:    shll $14, %eax
 ; X64-NEXT:    movswl %ax, %edi
 ; X64-NEXT:    shrl $4, %edi
diff --git a/llvm/test/CodeGen/X86/sdiv_fix.ll b/llvm/test/CodeGen/X86/sdiv_fix.ll
index 392bc83d9d5d8..b7054c86cec06 100644
--- a/llvm/test/CodeGen/X86/sdiv_fix.ll
+++ b/llvm/test/CodeGen/X86/sdiv_fix.ll
@@ -12,51 +12,49 @@ declare  <4 x i32> @llvm.sdiv.fix.v4i32(<4 x i32>, <4 x i32>, i32)
 define i16 @func(i16 %x, i16 %y) nounwind {
 ; X64-LABEL: func:
 ; X64:       # %bb.0:
-; X64-NEXT:    movswl %si, %esi
-; X64-NEXT:    movswl %di, %ecx
-; X64-NEXT:    shll $7, %ecx
-; X64-NEXT:    movl %ecx, %eax
+; X64-NEXT:    movswl %si, %ecx
+; X64-NEXT:    movswl %di, %edi
+; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    shll $7, %eax
 ; X64-NEXT:    cltd
-; X64-NEXT:    idivl %esi
+; X64-NEXT:    idivl %ecx
 ; X64-NEXT:    # kill: def $eax killed $eax def $rax
-; X64-NEXT:    leal -1(%rax), %edi
-; X64-NEXT:    testl %esi, %esi
-; X64-NEXT:    sets %sil
-; X64-NEXT:    testl %ecx, %ecx
-; X64-NEXT:    sets %cl
-; X64-NEXT:    xorb %sil, %cl
+; X64-NEXT:    leal -1(%rax), %ecx
+; X64-NEXT:    testl $32768, %esi # imm = 0x8000
+; X64-NEXT:    setne %sil
+; X64-NEXT:    testl $16777216, %edi # imm = 0x1000000
+; X64-NEXT:    setne %dil
+; X64-NEXT:    xorb %sil, %dil
 ; X64-NEXT:    testl %edx, %edx
 ; X64-NEXT:    setne %dl
-; X64-NEXT:    testb %cl, %dl
-; X64-NEXT:    cmovnel %edi, %eax
+; X64-NEXT:    testb %dil, %dl
+; X64-NEXT:    cmovnel %ecx, %eax
 ; X64-NEXT:    # kill: def $ax killed $ax killed $rax
 ; X64-NEXT:    retq
 ;
 ; X86-LABEL: func:
 ; X86:       # %bb.0:
-; X86-NEXT:    pushl %ebx
 ; X86-NEXT:    pushl %edi
 ; X86-NEXT:    pushl %esi
-; X86-NEXT:    movswl {{[0-9]+}}(%esp), %esi
 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    shll $7, %ecx
-; X86-NEXT:    movl %ecx, %eax
+; X86-NEXT:    movswl {{[0-9]+}}(%esp), %esi
+; X86-NEXT:    movl %esi, %eax
+; X86-NEXT:    shll $7, %eax
 ; X86-NEXT:    cltd
-; X86-NEXT:    idivl %esi
+; X86-NEXT:    idivl %ecx
 ; X86-NEXT:    leal -1(%eax), %edi
-; X86-NEXT:    testl %esi, %esi
-; X86-NEXT:    sets %bl
 ; X86-NEXT:    testl %ecx, %ecx
 ; X86-NEXT:    sets %cl
-; X86-NEXT:    xorb %bl, %cl
+; X86-NEXT:    testl $16777216, %esi # imm = 0x1000000
+; X86-NEXT:    setne %ch
+; X86-NEXT:    xorb %cl, %ch
 ; X86-NEXT:    testl %edx, %edx
-; X86-NEXT:    setne %dl
-; X86-NEXT:    testb %cl, %dl
+; X86-NEXT:    setne %cl
+; X86-NEXT:    testb %ch, %cl
 ; X86-NEXT:    cmovnel %edi, %eax
 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-NEXT:    popl %esi
 ; X86-NEXT:    popl %edi
-; X86-NEXT:    popl %ebx
 ; X86-NEXT:    retl
   %tmp = call i16 @llvm.sdiv.fix.i16(i16 %x, i16 %y, i32 7)
   ret i16 %tmp
@@ -65,22 +63,22 @@ define i16 @func(i16 %x, i16 %y) nounwind {
 define i16 @func2(i8 %x, i8 %y) nounwind {
 ; X64-LABEL: func2:
 ; X64:       # %bb.0:
-; X64-NEXT:    movsbl %sil, %esi
-; X64-NEXT:    movsbl %dil, %ecx
-; X64-NEXT:    shll $14, %ecx
-; X64-NEXT:    movl %ecx, %eax
+; X64-NEXT:    movsbl %sil, %ecx
+; X64-NEXT:    movsbl %dil, %esi
+; X64-NEXT:    movl %esi, %eax
+; X64-NEXT:    shll $14, %eax
 ; X64-NEXT:    cltd
-; X64-NEXT:    idivl %esi
+; X64-NEXT:    idivl %ecx
 ; X64-NEXT:    # kill: def $eax killed $eax def $rax
 ; X64-NEXT:    leal -1(%rax), %edi
-; X64-NEXT:    testl %esi, %esi
-; X64-NEXT:    sets %sil
-; X64-NEXT:    testl %ecx, %ecx
-; X64-NEXT:    sets %cl
-; X64-NEXT:    xorb %sil, %cl
+; X64-NEXT:    testb $-128, %cl
+; X64-NEXT:    setne %cl
+; X64-NEXT:    testl $131072, %esi # imm = 0x20000
+; X64-NEXT:    setne %sil
+; X64-NEXT:    xorb %cl, %sil
 ; X64-NEXT:    testl %edx, %edx
-; X64-NEXT:    setne %dl
-; X64-NEXT:    testb %cl, %dl
+; X64-NEXT:    setne %cl
+; X64-NEXT:    testb %sil, %cl
 ; X64-NEXT:    cmovel %eax, %edi
 ; X64-NEXT:    addl %edi, %edi
 ; X64-NEXT:    movswl %di, %eax
@@ -93,24 +91,24 @@ define i16 @func2(i8 %x, i8 %y) nounwind {
 ; X86-NEXT:    pushl %ebx
 ; X86-NEXT:    pushl %edi
 ; X86-NEXT:    pushl %esi
+; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %esi
 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %edi
-; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    shll $14, %ecx
-; X86-NEXT:    movl %ecx, %eax
+; X86-NEXT:    movl %edi, %eax
+; X86-NEXT:    shll $14, %eax
 ; X86-NEXT:    cltd
-; X86-NEXT:    idivl %edi
-; X86-NEXT:    leal -1(%eax), %esi
-; X86-NEXT:    testl %edi, %edi
+; X86-NEXT:    idivl %esi
+; X86-NEXT:    leal -1(%eax), %ecx
+; X86-NEXT:    testl %esi, %esi
 ; X86-NEXT:    sets %bl
-; X86-NEXT:    testl %ecx, %ecx
-; X86-NEXT:    sets %cl
-; X86-NEXT:    xorb %bl, %cl
+; X86-NEXT:    testl $131072, %edi # imm = 0x20000
+; X86-NEXT:    setne %bh
+; X86-NEXT:    xorb %bl, %bh
 ; X86-NEXT:    testl %edx, %edx
 ; X86-NEXT:    setne %dl
-; X86-NEXT:    testb %cl, %dl
-; X86-NEXT:    cmovel %eax, %esi
-; X86-NEXT:    addl %esi, %esi
-; X86-NEXT:    movswl %si, %eax
+; X86-NEXT:    testb %bh, %dl
+; X86-NEXT:    cmovel %eax, %ecx
+; X86-NEXT:    addl %ecx, %ecx
+; X86-NEXT:    movswl %cx, %eax
 ; X86-NEXT:    shrl %eax
 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-NEXT:    popl %esi
@@ -127,17 +125,18 @@ define i16 @func2(i8 %x, i8 %y) nounwind {
 define i16 @func3(i15 %x, i8 %y) nounwind {
 ; X64-LABEL: func3:
 ; X64:       # %bb.0:
+; X64-NEXT:    # kill: def $edi killed $edi def $rdi
 ; X64-NEXT:    shll $8, %esi
 ; X64-NEXT:    movswl %si, %ecx
-; X64-NEXT:    addl %edi, %edi
+; X64-NEXT:    leal (%rdi,%rdi), %eax
 ; X64-NEXT:    shrl $4, %ecx
-; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-NEXT:    cwtd
 ; X64-NEXT:    idivw %cx
 ; X64-NEXT:    # kill: def $ax killed $ax def $rax
 ; X64-NEXT:    leal -1(%rax), %esi
-; X64-NEXT:    testw %di, %di
-; X64-NEXT:    sets %dil
+; X64-NEXT:    testl $16384, %edi # imm = 0x4000
+; X64-NEXT:    setne %dil
 ; X64-NEXT:    testw %cx, %cx
 ; X64-NEXT:    sets %cl
 ; X64-NEXT:    xorb %dil, %cl
@@ -155,19 +154,19 @@ define i16 @func3(i15 %x, i8 %y) nounwind {
 ; X86:       # %bb.0:
 ; X86-NEXT:    pushl %edi
 ; X86-NEXT:    pushl %esi
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    shll $8, %eax
 ; X86-NEXT:    movswl %ax, %esi
-; X86-NEXT:    addl %ecx, %ecx
+; X86-NEXT:    leal (%ecx,%ecx), %eax
 ; X86-NEXT:    shrl $4, %esi
-; X86-NEXT:    movl %ecx, %eax
+; X86-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-NEXT:    cwtd
 ; X86-NEXT:    idivw %si
 ; X86-NEXT:    # kill: def $ax killed $ax def $eax
 ; X86-NEXT:    leal -1(%eax), %edi
-; X86-NEXT:    testw %cx, %cx
-; X86-NEXT:    sets %cl
+; X86-NEXT:    testl $16384, %ecx # imm = 0x4000
+; X86-NEXT:    setne %cl
 ; X86-NEXT:    testw %si, %si
 ; X86-NEXT:    sets %ch
 ; X86-NEXT:    xorb %cl, %ch
@@ -192,27 +191,27 @@ define i16 @func3(i15 %x, i8 %y) nounwind {
 define i4 @func4(i4 %x, i4 %y) nounwind {
 ; X64-LABEL: func4:
 ; X64:       # %bb.0:
+; X64-NEXT:    # kill: def $edi killed $edi def $rdi
 ; X64-NEXT:    shlb $4, %sil
 ; X64-NEXT:    sarb $4, %sil
 ; X64-NEXT:    shlb $4, %dil
 ; X64-NEXT:    sarb $4, %dil
-; X64-NEXT:    shlb $2, %dil
-; X64-NEXT:    movsbl %dil, %ecx
-; X64-NEXT:    movl %ecx, %eax
+; X64-NEXT:    leal (,%rdi,4), %eax
+; X64-NEXT:    cbtw
 ; X64-NEXT:    idivb %sil
-; X64-NEXT:    movsbl %ah, %edx
-; X64-NEXT:    movzbl %al, %edi
-; X64-NEXT:    leal -1(%rdi), %eax
+; X64-NEXT:    movsbl %ah, %ecx
+; X64-NEXT:    movzbl %al, %edx
+; X64-NEXT:    leal -1(%rdx), %eax
 ; X64-NEXT:    movzbl %al, %eax
 ; X64-NEXT:    testb %sil, %sil
 ; X64-NEXT:    sets %sil
+; X64-NEXT:    testb $32, %dil
+; X64-NEXT:    setne %dil
+; X64-NEXT:    xorb %sil, %dil
 ; X64-NEXT:    testb %cl, %cl
-; X64-NEXT:    sets %cl
-; X64-NEXT:    xorb %sil, %cl
-; X64-NEXT:    testb %dl, %dl
-; X64-NEXT:    setne %dl
-; X64-NEXT:    testb %cl, %dl
-; X64-NEXT:    cmovel %edi, %eax
+; X64-NEXT:    setne %cl
+; X64-NEXT:    testb %dil, %cl
+; X64-NEXT:    cmovel %edx, %eax
 ; X64-NEXT:    # kill: def $al killed $al killed $eax
 ; X64-NEXT:    retq
 ;
@@ -226,8 +225,9 @@ define i4 @func4(i4 %x, i4 %y) nounwind {
 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
 ; X86-NEXT:    shlb $4, %dl
 ; X86-NEXT:    sarb $4, %dl
-; X86-NEXT:    shlb $2, %dl
-; X86-NEXT:    movsbl %dl, %eax
+; X86-NEXT:    movl %edx, %eax
+; X86-NEXT:    shlb $2, %al
+; X86-NEXT:    cbtw
 ; X86-NEXT:    idivb %cl
 ; X86-NEXT:    movsbl %ah, %ebx
 ; X86-NEXT:    movzbl %al, %esi
@@ -235,8 +235,8 @@ define i4 @func4(i4 %x, i4 %y) nounwind {
 ; X86-NEXT:    movzbl %al, %eax
 ; X86-NEXT:    testb %cl, %cl
 ; X86-NEXT:    sets %cl
-; X86-NEXT:    testb %dl, %dl
-; X86-NEXT:    sets %dl
+; X86-NEXT:    testb $32, %dl
+; X86-NEXT:    setne %dl
 ; X86-NEXT:    xorb %cl, %dl
 ; X86-NEXT:    testb %bl, %bl
 ; X86-NEXT:    setne %cl
@@ -385,17 +385,17 @@ define i18 @func6(i16 %x, i16 %y) nounwind {
 ; X64-LABEL: func6:
 ; X64:       # %bb.0:
 ; X64-NEXT:    movswl %di, %ecx
-; X64-NEXT:    movswl %si, %esi
-; X64-NEXT:    shll $7, %ecx
+; X64-NEXT:    movswl %si, %edi
 ; X64-NEXT:    movl %ecx, %eax
+; X64-NEXT:    shll $7, %eax
 ; X64-NEXT:    cltd
-; X64-NEXT:    idivl %esi
+; X64-NEXT:    idivl %edi
 ; X64-NEXT:    # kill: def $eax killed $eax def $rax
 ; X64-NEXT:    leal -1(%rax), %edi
-; X64-NEXT:    testl %esi, %esi
-; X64-NEXT:    sets %sil
-; X64-NEXT:    testl %ecx, %ecx
-; X64-NEXT:    sets %cl
+; X64-NEXT:    testl $32768, %esi # imm = 0x8000
+; X64-NEXT:    setne %sil
+; X64-NEXT:    testl $16777216, %ecx # imm = 0x1000000
+; X64-NEXT:    setne %cl
 ; X64-NEXT:    xorb %sil, %cl
 ; X64-NEXT:    testl %edx, %edx
 ; X64-NEXT:    setne %dl
@@ -406,28 +406,26 @@ define i18 @func6(i16 %x, i16 %y) nounwind {
 ;
 ; X86-LABEL: func6:
 ; X86:       # %bb.0:
-; X86-NEXT:    pushl %ebx
 ; X86-NEXT:    pushl %edi
 ; X86-NEXT:    pushl %esi
-; X86-NEXT:    movswl {{[0-9]+}}(%esp), %esi
 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    shll $7, %ecx
-; X86-NEXT:    movl %ecx, %eax
+; X86-NEXT:    movswl {{[0-9]+}}(%esp), %esi
+; X86-NEXT:    movl %esi, %eax
+; X86-NEXT:    shll $7, %eax
 ; X86-NEXT:    cltd
-; X86-NEXT:    idivl %esi
+; X86-NEXT:    idivl %ecx
 ; X86-NEXT:    leal -1(%eax), %edi
-; X86-NEXT:    testl %esi, %esi
-; X86-NEXT:    sets %bl
 ; X86-NEXT:    testl %ecx, %ecx
 ; X86-NEXT:    sets %cl
-; X86-NEXT:    xorb %bl, %cl
+; X86-NEXT:    testl $16777216, %esi # imm = 0x1000000
+; X86-NEXT:    setne %ch
+; X86-NEXT:    xorb %cl, %ch
 ; X86-NEXT:    testl %edx, %edx
-; X86-NEXT:    setne %dl
-; X86-NEXT:    testb %cl, %dl
+; X86-NEXT:    setne %cl
+; X86-NEXT:    testb %ch, %cl
 ; X86-NEXT:    cmovnel %edi, %eax
 ; X86-NEXT:    popl %esi
 ; X86-NEXT:    popl %edi
-; X86-NEXT:    popl %ebx
 ; X86-NEXT:    retl
   %x2 = sext i16 %x to i18
   %y2 = sext i16 %y to i18
diff --git a/llvm/test/CodeGen/X86/sdiv_fix_sat.ll b/llvm/test/CodeGen/X86/sdiv_fix_sat.ll
index 7df490f984928..2b5771d5bbfd6 100644
--- a/llvm/test/CodeGen/X86/sdiv_fix_sat.ll
+++ b/llvm/test/CodeGen/X86/sdiv_fix_sat.ll
@@ -13,23 +13,24 @@ define i16 @func(i16 %x, i16 %y) nounwind {
 ;
 ; X64-LABEL: func:
 ; X64:       # %bb.0:
-; X64-NEXT:    movswl %si, %esi
-; X64-NEXT:    movswl %di, %ecx
-; X64-NEXT:    shll $8, %ecx
-; X64-NEXT:    movl %ecx, %eax
+; X64-NEXT:    movswl %si, %ecx
+; X64-NEXT:    movswl %di, %edi
+; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    shll $8, %eax
 ; X64-NEXT:    cltd
-; X64-NEXT:    idivl %esi
+; X64-NEXT:    idivl %ecx
 ; X64-NEXT:    # kill: def $eax killed $eax def $rax
-; X64-NEXT:    leal -1(%rax), %edi
-; X64-NEXT:    testl %esi, %esi
-; X64-NEXT:    sets %sil
-; X64-NEXT:    testl %ecx, %ecx
-; X64-NEXT:    sets %cl
-; X64-NEXT:    xorb %sil, %cl
+; X64-NEXT:    leal -1(%rax), %ecx
+; X64-NEXT:    testl $32768, %esi # imm = 0x8000
+; X64-NEXT:    setne %sil
+; X64-NEXT:    addl %edi, %edi
+; X64-NEXT:    testl $16777216, %edi # imm = 0x1000000
+; X64-NEXT:    setne %dil
+; X64-NEXT:    xorb %sil, %dil
 ; X64-NEXT:    testl %edx, %edx
 ; X64-NEXT:    setne %dl
-; X64-NEXT:    testb %cl, %dl
-; X64-NEXT:    cmovnel %edi, %eax
+; X64-NEXT:    testb %dil, %dl
+; X64-NEXT:    cmovnel %ecx, %eax
 ; X64-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
 ; X64-NEXT:    movl $65535, %ecx # imm = 0xFFFF
 ; X64-NEXT:    cmovgel %ecx, %eax
@@ -47,15 +48,16 @@ define i16 @func(i16 %x, i16 %y) nounwind {
 ; X86-NEXT:    pushl %esi
 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %esi
 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    shll $8, %ecx
 ; X86-NEXT:    movl %ecx, %eax
+; X86-NEXT:    shll $8, %eax
 ; X86-NEXT:    cltd
 ; X86-NEXT:    idivl %esi
 ; X86-NEXT:    leal -1(%eax), %edi
 ; X86-NEXT:    testl %esi, %esi
 ; X86-NEXT:    sets %bl
-; X86-NEXT:    testl %ecx, %ecx
-; X86-NEXT:    sets %cl
+; X86-NEXT:    addl %ecx, %ecx
+; X86-NEXT:    testl $16777216, %ecx # imm = 0x1000000
+; X86-NEXT:    setne %cl
 ; X86-NEXT:    xorb %bl, %cl
 ; X86-NEXT:    testl %edx, %edx
 ; X86-NEXT:    setne %dl
@@ -81,22 +83,22 @@ define i16 @func2(i8 %x, i8 %y) nounwind {
 ;
 ; X64-LABEL: func2:
 ; X64:       # %bb.0:
-; X64-NEXT:    movsbl %sil, %esi
-; X64-NEXT:    movsbl %dil, %ecx
-; X64-NEXT:    shll $14, %ecx
-; X64-NEXT:    movl %ecx, %eax
+; X64-NEXT:    movsbl %sil, %ecx
+; X64-NEXT:    movsbl %dil, %esi
+; X64-NEXT:    movl %esi, %eax
+; X64-NEXT:    shll $14, %eax
 ; X64-NEXT:    cltd
-; X64-NEXT:    idivl %esi
+; X64-NEXT:    idivl %ecx
 ; X64-NEXT:    # kill: def $eax killed $eax def $rax
 ; X64-NEXT:    leal -1(%rax), %edi
-; X64-NEXT:    testl %esi, %esi
-; X64-NEXT:    sets %sil
-; X64-NEXT:    testl %ecx, %ecx
-; X64-NEXT:    sets %cl
-; X64-NEXT:    xorb %sil, %cl
+; X64-NEXT:    testb $-128, %cl
+; X64-NEXT:    setne %cl
+; X64-NEXT:    testl $131072, %esi # imm = 0x20000
+; X64-NEXT:    setne %sil
+; X64-NEXT:    xorb %cl, %sil
 ; X64-NEXT:    testl %edx, %edx
-; X64-NEXT:    setne %dl
-; X64-NEXT:    testb %cl, %dl
+; X64-NEXT:    setne %cl
+; X64-NEXT:    testb %sil, %cl
 ; X64-NEXT:    cmovnel %edi, %eax
 ; X64-NEXT:    cmpl $16383, %eax # imm = 0x3FFF
 ; X64-NEXT:    movl $16383, %ecx # imm = 0x3FFF
@@ -109,24 +111,23 @@ define i16 @func2(i8 %x, i8 %y) nounwind {
 ;
 ; X86-LABEL: func2:
 ; X86:       # %bb.0:
-; X86-NEXT:    pushl %ebx
 ; X86-NEXT:    pushl %edi
 ; X86-NEXT:    pushl %esi
-; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %esi
 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    shll $14, %ecx
-; X86-NEXT:    movl %ecx, %eax
+; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %esi
+; X86-NEXT:    movl %esi, %eax
+; X86-NEXT:    shll $14, %eax
 ; X86-NEXT:    cltd
-; X86-NEXT:    idivl %esi
+; X86-NEXT:    idivl %ecx
 ; X86-NEXT:    leal -1(%eax), %edi
-; X86-NEXT:    testl %esi, %esi
-; X86-NEXT:    sets %bl
 ; X86-NEXT:    testl %ecx, %ecx
 ; X86-NEXT:    sets %cl
-; X86-NEXT:    xorb %bl, %cl
+; X86-NEXT:    testl $131072, %esi # imm = 0x20000
+; X86-NEXT:    setne %ch
+; X86-NEXT:    xorb %cl, %ch
 ; X86-NEXT:    testl %edx, %edx
-; X86-NEXT:    setne %dl
-; X86-NEXT:    testb %cl, %dl
+; X86-NEXT:    setne %cl
+; X86-NEXT:    testb %ch, %cl
 ; X86-NEXT:    cmovnel %edi, %eax
 ; X86-NEXT:    cmpl $16383, %eax # imm = 0x3FFF
 ; X86-NEXT:    movl $16383, %ecx # imm = 0x3FFF
@@ -137,7 +138,6 @@ define i16 @func2(i8 %x, i8 %y) nounwind {
 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-NEXT:    popl %esi
 ; X86-NEXT:    popl %edi
-; X86-NEXT:    popl %ebx
 ; X86-NEXT:    retl
   %x2 = sext i8 %x to i15
   %y2 = sext i8 %y to i15
@@ -150,17 +150,18 @@ define i16 @func3(i15 %x, i8 %y) nounwind {
 ;
 ; X64-LABEL: func3:
 ; X64:       # %bb.0:
+; X64-NEXT:    # kill: def $edi killed $edi def $rdi
 ; X64-NEXT:    shll $8, %esi
 ; X64-NEXT:    movswl %si, %ecx
-; X64-NEXT:    addl %edi, %edi
+; X64-NEXT:    leal (%rdi,%rdi), %eax
 ; X64-NEXT:    shrl $4, %ecx
-; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-NEXT:    cwtd
 ; X64-NEXT:    idivw %cx
 ; X64-NEXT:    # kill: def $ax killed $ax def $rax
 ; X64-NEXT:    leal -1(%rax), %esi
-; X64-NEXT:    testw %di, %di
-; X64-NEXT:    sets %dil
+; X64-NEXT:    testl $16384, %edi # imm = 0x4000
+; X64-NEXT:    setne %dil
 ; X64-NEXT:    testw %cx, %cx
 ; X64-NEXT:    sets %cl
 ; X64-NEXT:    xorb %dil, %cl
@@ -183,19 +184,19 @@ define i16 @func3(i15 %x, i8 %y) nounwind {
 ; X86:       # %bb.0:
 ; X86-NEXT:    pushl %edi
 ; X86-NEXT:    pushl %esi
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    shll $8, %eax
 ; X86-NEXT:    movswl %ax, %esi
-; X86-NEXT:    addl %ecx, %ecx
+; X86-NEXT:    leal (%ecx,%ecx), %eax
 ; X86-NEXT:    shrl $4, %esi
-; X86-NEXT:    movl %ecx, %eax
+; X86-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-NEXT:    cwtd
 ; X86-NEXT:    idivw %si
 ; X86-NEXT:    # kill: def $ax killed $ax def $eax
 ; X86-NEXT:    leal -1(%eax), %edi
-; X86-NEXT:    testw %cx, %cx
-; X86-NEXT:    sets %cl
+; X86-NEXT:    testl $16384, %ecx # imm = 0x4000
+; X86-NEXT:    setne %cl
 ; X86-NEXT:    testw %si, %si
 ; X86-NEXT:    sets %ch
 ; X86-NEXT:    xorb %cl, %ch
@@ -226,30 +227,30 @@ define i4 @func4(i4 %x, i4 %y) nounwind {
 ;
 ; X64-LABEL: func4:
 ; X64:       # %bb.0:
+; X64-NEXT:    # kill: def $edi killed $edi def $rdi
 ; X64-NEXT:    shlb $4, %sil
 ; X64-NEXT:    sarb $4, %sil
 ; X64-NEXT:    shlb $4, %dil
 ; X64-NEXT:    sarb $4, %dil
-; X64-NEXT:    shlb $2, %dil
-; X64-NEXT:    movsbl %dil, %ecx
-; X64-NEXT:    movl %ecx, %eax
+; X64-NEXT:    leal (,%rdi,4), %eax
+; X64-NEXT:    cbtw
 ; X64-NEXT:    idivb %sil
-; X64-NEXT:    movsbl %ah, %edx
+; X64-NEXT:    movsbl %ah, %ecx
 ; X64-NEXT:    movzbl %al, %eax
-; X64-NEXT:    leal -1(%rax), %edi
-; X64-NEXT:    movzbl %dil, %edi
+; X64-NEXT:    leal -1(%rax), %edx
+; X64-NEXT:    movzbl %dl, %edx
 ; X64-NEXT:    testb %sil, %sil
 ; X64-NEXT:    sets %sil
+; X64-NEXT:    testb $32, %dil
+; X64-NEXT:    setne %dil
+; X64-NEXT:    xorb %sil, %dil
 ; X64-NEXT:    testb %cl, %cl
-; X64-NEXT:    sets %cl
-; X64-NEXT:    xorb %sil, %cl
-; X64-NEXT:    testb %dl, %dl
-; X64-NEXT:    setne %dl
-; X64-NEXT:    testb %cl, %dl
-; X64-NEXT:    cmovel %eax, %edi
-; X64-NEXT:    cmpb $7, %dil
+; X64-NEXT:    setne %cl
+; X64-NEXT:    testb %dil, %cl
+; X64-NEXT:    cmovel %eax, %edx
+; X64-NEXT:    cmpb $7, %dl
 ; X64-NEXT:    movl $7, %ecx
-; X64-NEXT:    cmovll %edi, %ecx
+; X64-NEXT:    cmovll %edx, %ecx
 ; X64-NEXT:    cmpb $-7, %cl
 ; X64-NEXT:    movl $248, %eax
 ; X64-NEXT:    cmovgel %ecx, %eax
@@ -266,8 +267,9 @@ define i4 @func4(i4 %x, i4 %y) nounwind {
 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
 ; X86-NEXT:    shlb $4, %dl
 ; X86-NEXT:    sarb $4, %dl
-; X86-NEXT:    shlb $2, %dl
-; X86-NEXT:    movsbl %dl, %eax
+; X86-NEXT:    movl %edx, %eax
+; X86-NEXT:    shlb $2, %al
+; X86-NEXT:    cbtw
 ; X86-NEXT:    idivb %cl
 ; X86-NEXT:    movsbl %ah, %ebx
 ; X86-NEXT:    movzbl %al, %esi
@@ -275,8 +277,8 @@ define i4 @func4(i4 %x, i4 %y) nounwind {
 ; X86-NEXT:    movzbl %al, %eax
 ; X86-NEXT:    testb %cl, %cl
 ; X86-NEXT:    sets %cl
-; X86-NEXT:    testb %dl, %dl
-; X86-NEXT:    sets %dl
+; X86-NEXT:    testb $32, %dl
+; X86-NEXT:    setne %dl
 ; X86-NEXT:    xorb %cl, %dl
 ; X86-NEXT:    testb %bl, %bl
 ; X86-NEXT:    setne %cl
@@ -486,17 +488,17 @@ define i18 @func6(i16 %x, i16 %y) nounwind {
 ; X64-LABEL: func6:
 ; X64:       # %bb.0:
 ; X64-NEXT:    movswl %di, %ecx
-; X64-NEXT:    movswl %si, %esi
-; X64-NEXT:    shll $7, %ecx
+; X64-NEXT:    movswl %si, %edi
 ; X64-NEXT:    movl %ecx, %eax
+; X64-NEXT:    shll $7, %eax
 ; X64-NEXT:    cltd
-; X64-NEXT:    idivl %esi
+; X64-NEXT:    idivl %edi
 ; X64-NEXT:    # kill: def $eax killed $eax def $rax
 ; X64-NEXT:    leal -1(%rax), %edi
-; X64-NEXT:    testl %esi, %esi
-; X64-NEXT:    sets %sil
-; X64-NEXT:    testl %ecx, %ecx
-; X64-NEXT:    sets %cl
+; X64-NEXT:    testl $32768, %esi # imm = 0x8000
+; X64-NEXT:    setne %sil
+; X64-NEXT:    testl $16777216, %ecx # imm = 0x1000000
+; X64-NEXT:    setne %cl
 ; X64-NEXT:    xorb %sil, %cl
 ; X64-NEXT:    testl %edx, %edx
 ; X64-NEXT:    setne %dl
@@ -513,24 +515,23 @@ define i18 @func6(i16 %x, i16 %y) nounwind {
 ;
 ; X86-LABEL: func6:
 ; X86:       # %bb.0:
-; X86-NEXT:    pushl %ebx
 ; X86-NEXT:    pushl %edi
 ; X86-NEXT:    pushl %esi
-; X86-NEXT:    movswl {{[0-9]+}}(%esp), %esi
 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    shll $7, %ecx
-; X86-NEXT:    movl %ecx, %eax
+; X86-NEXT:    movswl {{[0-9]+}}(%esp), %esi
+; X86-NEXT:    movl %esi, %eax
+; X86-NEXT:    shll $7, %eax
 ; X86-NEXT:    cltd
-; X86-NEXT:    idivl %esi
+; X86-NEXT:    idivl %ecx
 ; X86-NEXT:    leal -1(%eax), %edi
-; X86-NEXT:    testl %esi, %esi
-; X86-NEXT:    sets %bl
 ; X86-NEXT:    testl %ecx, %ecx
 ; X86-NEXT:    sets %cl
-; X86-NEXT:    xorb %bl, %cl
+; X86-NEXT:    testl $16777216, %esi # imm = 0x1000000
+; X86-NEXT:    setne %ch
+; X86-NEXT:    xorb %cl, %ch
 ; X86-NEXT:    testl %edx, %edx
-; X86-NEXT:    setne %dl
-; X86-NEXT:    testb %cl, %dl
+; X86-NEXT:    setne %cl
+; X86-NEXT:    testb %ch, %cl
 ; X86-NEXT:    cmovnel %edi, %eax
 ; X86-NEXT:    cmpl $131071, %eax # imm = 0x1FFFF
 ; X86-NEXT:    movl $131071, %ecx # imm = 0x1FFFF
@@ -540,7 +541,6 @@ define i18 @func6(i16 %x, i16 %y) nounwind {
 ; X86-NEXT:    cmovll %ecx, %eax
 ; X86-NEXT:    popl %esi
 ; X86-NEXT:    popl %edi
-; X86-NEXT:    popl %ebx
 ; X86-NEXT:    retl
   %x2 = sext i16 %x to i18
   %y2 = sext i16 %y to i18
diff --git a/llvm/test/CodeGen/X86/sshl_sat.ll b/llvm/test/CodeGen/X86/sshl_sat.ll
index 469b62453f37f..a167404393641 100644
--- a/llvm/test/CodeGen/X86/sshl_sat.ll
+++ b/llvm/test/CodeGen/X86/sshl_sat.ll
@@ -57,18 +57,19 @@ define i16 @func2(i8 %x, i8 %y) nounwind {
 ; X64:       # %bb.0:
 ; X64-NEXT:    movl %esi, %ecx
 ; X64-NEXT:    movsbl %dil, %eax
-; X64-NEXT:    addl %eax, %eax
 ; X64-NEXT:    movl %eax, %edx
-; X64-NEXT:    xorl %esi, %esi
-; X64-NEXT:    testw %ax, %ax
-; X64-NEXT:    sets %sil
-; X64-NEXT:    addl $32767, %esi # imm = 0x7FFF
+; X64-NEXT:    andl $16384, %edx # imm = 0x4000
+; X64-NEXT:    cmpw $1, %dx
+; X64-NEXT:    movl $32767, %edx # imm = 0x7FFF
+; X64-NEXT:    sbbl $-1, %edx
+; X64-NEXT:    addl %eax, %eax
+; X64-NEXT:    movl %eax, %esi
 ; X64-NEXT:    shll %cl, %eax
 ; X64-NEXT:    movswl %ax, %edi
 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 ; X64-NEXT:    sarl %cl, %edi
-; X64-NEXT:    cmpw %di, %dx
-; X64-NEXT:    cmovnel %esi, %eax
+; X64-NEXT:    cmpw %di, %si
+; X64-NEXT:    cmovnel %edx, %eax
 ; X64-NEXT:    cwtl
 ; X64-NEXT:    shrl %eax
 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
@@ -76,24 +77,27 @@ define i16 @func2(i8 %x, i8 %y) nounwind {
 ;
 ; X86-LABEL: func2:
 ; X86:       # %bb.0:
+; X86-NEXT:    pushl %edi
 ; X86-NEXT:    pushl %esi
 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    addl %eax, %eax
 ; X86-NEXT:    movl %eax, %edx
-; X86-NEXT:    shll %cl, %edx
-; X86-NEXT:    movswl %dx, %esi
-; X86-NEXT:    sarl %cl, %esi
-; X86-NEXT:    xorl %ecx, %ecx
-; X86-NEXT:    testw %ax, %ax
-; X86-NEXT:    sets %cl
-; X86-NEXT:    addl $32767, %ecx # imm = 0x7FFF
-; X86-NEXT:    cmpw %si, %ax
-; X86-NEXT:    cmovel %edx, %ecx
-; X86-NEXT:    movswl %cx, %eax
+; X86-NEXT:    andl $16384, %edx # imm = 0x4000
+; X86-NEXT:    cmpw $1, %dx
+; X86-NEXT:    movl $32767, %edx # imm = 0x7FFF
+; X86-NEXT:    sbbl $-1, %edx
+; X86-NEXT:    addl %eax, %eax
+; X86-NEXT:    movl %eax, %esi
+; X86-NEXT:    shll %cl, %esi
+; X86-NEXT:    movswl %si, %edi
+; X86-NEXT:    sarl %cl, %edi
+; X86-NEXT:    cmpw %di, %ax
+; X86-NEXT:    cmovnel %edx, %esi
+; X86-NEXT:    movswl %si, %eax
 ; X86-NEXT:    shrl %eax
 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-NEXT:    popl %esi
+; X86-NEXT:    popl %edi
 ; X86-NEXT:    retl
   %x2 = sext i8 %x to i15
   %y2 = sext i8 %y to i15
@@ -107,45 +111,49 @@ define i16 @func3(i15 %x, i8 %y) nounwind {
 ; X64:       # %bb.0:
 ; X64-NEXT:    movl %esi, %ecx
 ; X64-NEXT:    shll $7, %ecx
-; X64-NEXT:    addl %edi, %edi
 ; X64-NEXT:    movl %edi, %eax
-; X64-NEXT:    shll %cl, %eax
-; X64-NEXT:    movswl %ax, %edx
+; X64-NEXT:    andl $16384, %eax # imm = 0x4000
+; X64-NEXT:    cmpw $1, %ax
+; X64-NEXT:    movl $32767, %eax # imm = 0x7FFF
+; X64-NEXT:    sbbl $-1, %eax
+; X64-NEXT:    addl %edi, %edi
+; X64-NEXT:    movl %edi, %edx
+; X64-NEXT:    shll %cl, %edx
+; X64-NEXT:    movswl %dx, %esi
 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
-; X64-NEXT:    sarl %cl, %edx
-; X64-NEXT:    xorl %ecx, %ecx
-; X64-NEXT:    testw %di, %di
-; X64-NEXT:    sets %cl
-; X64-NEXT:    addl $32767, %ecx # imm = 0x7FFF
-; X64-NEXT:    cmpw %dx, %di
-; X64-NEXT:    cmovel %eax, %ecx
-; X64-NEXT:    movswl %cx, %eax
+; X64-NEXT:    sarl %cl, %esi
+; X64-NEXT:    cmpw %si, %di
+; X64-NEXT:    cmovnel %eax, %edx
+; X64-NEXT:    movswl %dx, %eax
 ; X64-NEXT:    shrl %eax
 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-NEXT:    retq
 ;
 ; X86-LABEL: func3:
 ; X86:       # %bb.0:
+; X86-NEXT:    pushl %edi
 ; X86-NEXT:    pushl %esi
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    shll $7, %ecx
-; X86-NEXT:    addl %eax, %eax
 ; X86-NEXT:    movl %eax, %edx
-; X86-NEXT:    shll %cl, %edx
-; X86-NEXT:    movswl %dx, %esi
+; X86-NEXT:    andl $16384, %edx # imm = 0x4000
+; X86-NEXT:    cmpw $1, %dx
+; X86-NEXT:    movl $32767, %edx # imm = 0x7FFF
+; X86-NEXT:    sbbl $-1, %edx
+; X86-NEXT:    addl %eax, %eax
+; X86-NEXT:    movl %eax, %esi
+; X86-NEXT:    shll %cl, %esi
+; X86-NEXT:    movswl %si, %edi
 ; X86-NEXT:    # kill: def $cl killed $cl killed $ecx
-; X86-NEXT:    sarl %cl, %esi
-; X86-NEXT:    xorl %ecx, %ecx
-; X86-NEXT:    testw %ax, %ax
-; X86-NEXT:    sets %cl
-; X86-NEXT:    addl $32767, %ecx # imm = 0x7FFF
-; X86-NEXT:    cmpw %si, %ax
-; X86-NEXT:    cmovel %edx, %ecx
-; X86-NEXT:    movswl %cx, %eax
+; X86-NEXT:    sarl %cl, %edi
+; X86-NEXT:    cmpw %di, %ax
+; X86-NEXT:    cmovnel %edx, %esi
+; X86-NEXT:    movswl %si, %eax
 ; X86-NEXT:    shrl %eax
 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-NEXT:    popl %esi
+; X86-NEXT:    popl %edi
 ; X86-NEXT:    retl
   %y2 = sext i8 %y to i15
   %y3 = shl i15 %y2, 7
@@ -158,18 +166,19 @@ define i4 @func4(i4 %x, i4 %y) nounwind {
 ; X64-LABEL: func4:
 ; X64:       # %bb.0:
 ; X64-NEXT:    movl %esi, %ecx
+; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    andb $8, %al
+; X64-NEXT:    cmpb $1, %al
+; X64-NEXT:    movl $127, %eax
+; X64-NEXT:    sbbl $-1, %eax
 ; X64-NEXT:    andb $15, %cl
 ; X64-NEXT:    shlb $4, %dil
-; X64-NEXT:    movl %edi, %eax
-; X64-NEXT:    shlb %cl, %al
-; X64-NEXT:    movzbl %al, %edx
+; X64-NEXT:    movl %edi, %edx
+; X64-NEXT:    shlb %cl, %dl
+; X64-NEXT:    movzbl %dl, %edx
 ; X64-NEXT:    movl %edx, %esi
 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 ; X64-NEXT:    sarb %cl, %sil
-; X64-NEXT:    xorl %eax, %eax
-; X64-NEXT:    testb %dil, %dil
-; X64-NEXT:    sets %al
-; X64-NEXT:    addl $127, %eax
 ; X64-NEXT:    cmpb %sil, %dil
 ; X64-NEXT:    cmovel %edx, %eax
 ; X64-NEXT:    sarb $4, %al
@@ -179,20 +188,21 @@ define i4 @func4(i4 %x, i4 %y) nounwind {
 ; X86-LABEL: func4:
 ; X86:       # %bb.0:
 ; X86-NEXT:    pushl %esi
-; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-NEXT:    movl %edx, %eax
+; X86-NEXT:    andb $8, %al
+; X86-NEXT:    cmpb $1, %al
+; X86-NEXT:    movl $127, %esi
+; X86-NEXT:    sbbl $-1, %esi
 ; X86-NEXT:    andb $15, %cl
 ; X86-NEXT:    shlb $4, %dl
 ; X86-NEXT:    movb %dl, %ch
 ; X86-NEXT:    shlb %cl, %ch
-; X86-NEXT:    movzbl %ch, %esi
+; X86-NEXT:    movzbl %ch, %eax
 ; X86-NEXT:    sarb %cl, %ch
-; X86-NEXT:    xorl %eax, %eax
-; X86-NEXT:    testb %dl, %dl
-; X86-NEXT:    sets %al
-; X86-NEXT:    addl $127, %eax
 ; X86-NEXT:    cmpb %ch, %dl
-; X86-NEXT:    cmovel %esi, %eax
+; X86-NEXT:    cmovnel %esi, %eax
 ; X86-NEXT:    sarb $4, %al
 ; X86-NEXT:    # kill: def $al killed $al killed $eax
 ; X86-NEXT:    popl %esi
@@ -269,18 +279,19 @@ define i18 @func6(i16 %x, i16 %y) nounwind {
 ; X64:       # %bb.0:
 ; X64-NEXT:    movl %esi, %ecx
 ; X64-NEXT:    movswl %di, %edx
+; X64-NEXT:    movl %edx, %eax
+; X64-NEXT:    andl $131072, %eax # imm = 0x20000
+; X64-NEXT:    cmpl $1, %eax
+; X64-NEXT:    movl $2147483647, %esi # imm = 0x7FFFFFFF
+; X64-NEXT:    sbbl $-1, %esi
 ; X64-NEXT:    shll $14, %edx
-; X64-NEXT:    movl %edx, %esi
-; X64-NEXT:    shll %cl, %esi
-; X64-NEXT:    movl %esi, %edi
+; X64-NEXT:    movl %edx, %eax
+; X64-NEXT:    shll %cl, %eax
+; X64-NEXT:    movl %eax, %edi
 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
 ; X64-NEXT:    sarl %cl, %edi
-; X64-NEXT:    xorl %eax, %eax
-; X64-NEXT:    testl %edx, %edx
-; X64-NEXT:    sets %al
-; X64-NEXT:    addl $2147483647, %eax # imm = 0x7FFFFFFF
 ; X64-NEXT:    cmpl %edi, %edx
-; X64-NEXT:    cmovel %esi, %eax
+; X64-NEXT:    cmovnel %esi, %eax
 ; X64-NEXT:    sarl $14, %eax
 ; X64-NEXT:    retq
 ;
@@ -290,17 +301,18 @@ define i18 @func6(i16 %x, i16 %y) nounwind {
 ; X86-NEXT:    pushl %esi
 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %edx
+; X86-NEXT:    movl %edx, %eax
+; X86-NEXT:    andl $131072, %eax # imm = 0x20000
+; X86-NEXT:    cmpl $1, %eax
+; X86-NEXT:    movl $2147483647, %esi # imm = 0x7FFFFFFF
+; X86-NEXT:    sbbl $-1, %esi
 ; X86-NEXT:    shll $14, %edx
-; X86-NEXT:    movl %edx, %esi
-; X86-NEXT:    shll %cl, %esi
-; X86-NEXT:    movl %esi, %edi
+; X86-NEXT:    movl %edx, %eax
+; X86-NEXT:    shll %cl, %eax
+; X86-NEXT:    movl %eax, %edi
 ; X86-NEXT:    sarl %cl, %edi
-; X86-NEXT:    xorl %eax, %eax
-; X86-NEXT:    testl %edx, %edx
-; X86-NEXT:    sets %al
-; X86-NEXT:    addl $2147483647, %eax # imm = 0x7FFFFFFF
 ; X86-NEXT:    cmpl %edi, %edx
-; X86-NEXT:    cmovel %esi, %eax
+; X86-NEXT:    cmovnel %esi, %eax
 ; X86-NEXT:    sarl $14, %eax
 ; X86-NEXT:    popl %esi
 ; X86-NEXT:    popl %edi
diff --git a/llvm/test/CodeGen/X86/use-cr-result-of-dom-icmp-st.ll b/llvm/test/CodeGen/X86/use-cr-result-of-dom-icmp-st.ll
index 95831d506d3c0..b637bee4257d9 100644
--- a/llvm/test/CodeGen/X86/use-cr-result-of-dom-icmp-st.ll
+++ b/llvm/test/CodeGen/X86/use-cr-result-of-dom-icmp-st.ll
@@ -67,8 +67,9 @@ define i64 @ll_a_op_b__1(i64 %a, i64 %b) {
 ; DEFAULT-NEXT:    movq %rsi, %rcx
 ; DEFAULT-NEXT:    movq %rdi, %rax
 ; DEFAULT-NEXT:    shlq %cl, %rax
-; DEFAULT-NEXT:    testq %rax, %rax
-; DEFAULT-NEXT:    js .LBB1_1
+; DEFAULT-NEXT:    movq %rax, %rdx
+; DEFAULT-NEXT:    shrq $63, %rdx
+; DEFAULT-NEXT:    jne .LBB1_1
 ; DEFAULT-NEXT:  # %bb.2: # %return
 ; DEFAULT-NEXT:    movq %rcx, %rax
 ; DEFAULT-NEXT:    retq
@@ -85,8 +86,9 @@ define i64 @ll_a_op_b__1(i64 %a, i64 %b) {
 ; EQ2ICMP-NEXT:    movq %rdi, %rdx
 ; EQ2ICMP-NEXT:    movl %eax, %ecx
 ; EQ2ICMP-NEXT:    shlq %cl, %rdx
-; EQ2ICMP-NEXT:    testq %rdx, %rdx
-; EQ2ICMP-NEXT:    js .LBB1_1
+; EQ2ICMP-NEXT:    movq %rdx, %rcx
+; EQ2ICMP-NEXT:    shrq $63, %rcx
+; EQ2ICMP-NEXT:    jne .LBB1_1
 ; EQ2ICMP-NEXT:  # %bb.2: # %return
 ; EQ2ICMP-NEXT:    retq
 ; EQ2ICMP-NEXT:  .LBB1_1: # %if.end
@@ -502,8 +504,8 @@ define i64 @i_a_op_b__1(i32 signext %a, i32 signext %b) {
 ; DEFAULT-NEXT:    movl %esi, %ecx
 ; DEFAULT-NEXT:    movl %edi, %eax
 ; DEFAULT-NEXT:    shll %cl, %eax
-; DEFAULT-NEXT:    testl %eax, %eax
-; DEFAULT-NEXT:    js .LBB11_1
+; DEFAULT-NEXT:    testl $-2147483648, %eax # imm = 0x80000000
+; DEFAULT-NEXT:    jne .LBB11_1
 ; DEFAULT-NEXT:  # %bb.2: # %return
 ; DEFAULT-NEXT:    movslq %ecx, %rax
 ; DEFAULT-NEXT:    retq
@@ -521,8 +523,8 @@ define i64 @i_a_op_b__1(i32 signext %a, i32 signext %b) {
 ; EQ2ICMP-NEXT:    movl %esi, %ecx
 ; EQ2ICMP-NEXT:    movl %edi, %eax
 ; EQ2ICMP-NEXT:    shll %cl, %eax
-; EQ2ICMP-NEXT:    testl %eax, %eax
-; EQ2ICMP-NEXT:    js .LBB11_1
+; EQ2ICMP-NEXT:    testl $-2147483648, %eax # imm = 0x80000000
+; EQ2ICMP-NEXT:    jne .LBB11_1
 ; EQ2ICMP-NEXT:  # %bb.2: # %return
 ; EQ2ICMP-NEXT:    movslq %ecx, %rax
 ; EQ2ICMP-NEXT:    retq



More information about the llvm-commits mailing list