]> granicus.if.org Git - llvm/commitdiff
[X86] Teach EmitTest to handle ISD::SSUBO/USUBO in order to use the Z flag from the...
authorCraig Topper <craig.topper@intel.com>
Mon, 14 Oct 2019 06:47:56 +0000 (06:47 +0000)
committerCraig Topper <craig.topper@intel.com>
Mon, 14 Oct 2019 06:47:56 +0000 (06:47 +0000)
This prevents isel from emitting a TEST instruction that
optimizeCompareInstr will need to remove later.

In some of the modified tests, the SUB gets duplicated due to
the flags being needed in two places and being clobbered in
between. optimizeCompareInstr was able to optimize away the TEST
that was using the result of one of them, but optimizeCompareInstr
doesn't know to turn SUB into CMP after removing the TEST. It
only knows how to turn SUB into CMP if the result was already
dead.

With this change the TEST never exists, so optimizeCompareInstr
doesn't have to remove it. Then it can just turn the SUB into
CMP immediately.

Fixes PR43649.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@374755 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/known-bits.ll
test/CodeGen/X86/ssub_sat.ll
test/CodeGen/X86/ssub_sat_vec.ll

index a340eff978984fff3a235e7e1e9fa3ec070659a1..c649a90ddff782942fec0e07cf27df190ba20e6d 100644 (file)
@@ -20079,6 +20079,13 @@ static SDValue EmitTest(SDValue Op, unsigned X86CC, const SDLoc &dl,
   case X86ISD::XOR:
   case X86ISD::AND:
     return SDValue(Op.getNode(), 1);
+  case ISD::SSUBO:
+  case ISD::USUBO: {
+    // /USUBO/SSUBO will become a X86ISD::SUB and we can use its Z flag.
+    SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::i32);
+    return DAG.getNode(X86ISD::SUB, dl, VTs, Op->getOperand(0),
+                       Op->getOperand(1)).getValue(1);
+  }
   default:
   default_case:
     break;
index d9a7921131f475f4342e59298b9bcc75c58b839a..8e2e9c05fdcd8c0cadc6b4e8485d88979e551bef 100644 (file)
@@ -190,26 +190,22 @@ define {i32, i1} @knownbits_uaddo_saddo(i64 %a0, i64 %a1) nounwind {
 define {i32, i1} @knownbits_usubo_ssubo(i64 %a0, i64 %a1) nounwind {
 ; X32-LABEL: knownbits_usubo_ssubo:
 ; X32:       # %bb.0:
-; X32-NEXT:    pushl %ebx
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X32-NEXT:    movl %ecx, %edx
-; X32-NEXT:    subl %eax, %edx
-; X32-NEXT:    setb %bl
-; X32-NEXT:    testl %eax, %eax
-; X32-NEXT:    setns %al
+; X32-NEXT:    cmpl %eax, %ecx
+; X32-NEXT:    setb %dh
+; X32-NEXT:    setns %dl
 ; X32-NEXT:    testl %ecx, %ecx
 ; X32-NEXT:    setns %cl
-; X32-NEXT:    cmpb %al, %cl
-; X32-NEXT:    setne %al
-; X32-NEXT:    testl %edx, %edx
-; X32-NEXT:    setns %dl
 ; X32-NEXT:    cmpb %dl, %cl
+; X32-NEXT:    setne %ch
+; X32-NEXT:    testl %eax, %eax
+; X32-NEXT:    setns %al
+; X32-NEXT:    cmpb %al, %cl
 ; X32-NEXT:    setne %dl
-; X32-NEXT:    andb %al, %dl
-; X32-NEXT:    orb %bl, %dl
+; X32-NEXT:    andb %ch, %dl
+; X32-NEXT:    orb %dh, %dl
 ; X32-NEXT:    xorl %eax, %eax
-; X32-NEXT:    popl %ebx
 ; X32-NEXT:    retl
 ;
 ; X64-LABEL: knownbits_usubo_ssubo:
index 62724e981f7d76faf8d4585c9879403b26087395..51ca6d8a7948ef646955f6c86ebfe0de1be62af4 100644 (file)
@@ -12,24 +12,20 @@ declare <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32>, <4 x i32>)
 define i32 @func(i32 %x, i32 %y) nounwind {
 ; X86-LABEL: func:
 ; X86:       # %bb.0:
-; X86-NEXT:    pushl %esi
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; X86-NEXT:    xorl %ecx, %ecx
-; X86-NEXT:    movl %eax, %esi
-; X86-NEXT:    subl %edx, %esi
+; X86-NEXT:    cmpl %edx, %eax
 ; X86-NEXT:    setns %cl
 ; X86-NEXT:    addl $2147483647, %ecx # imm = 0x7FFFFFFF
 ; X86-NEXT:    subl %edx, %eax
 ; X86-NEXT:    cmovol %ecx, %eax
-; X86-NEXT:    popl %esi
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: func:
 ; X64:       # %bb.0:
 ; X64-NEXT:    xorl %eax, %eax
-; X64-NEXT:    movl %edi, %ecx
-; X64-NEXT:    subl %esi, %ecx
+; X64-NEXT:    cmpl %esi, %edi
 ; X64-NEXT:    setns %al
 ; X64-NEXT:    addl $2147483647, %eax # imm = 0x7FFFFFFF
 ; X64-NEXT:    subl %esi, %edi
@@ -79,8 +75,7 @@ define i64 @func2(i64 %x, i64 %y) nounwind {
 ; X64-LABEL: func2:
 ; X64:       # %bb.0:
 ; X64-NEXT:    xorl %ecx, %ecx
-; X64-NEXT:    movq %rdi, %rax
-; X64-NEXT:    subq %rsi, %rax
+; X64-NEXT:    cmpq %rsi, %rdi
 ; X64-NEXT:    setns %cl
 ; X64-NEXT:    movabsq $9223372036854775807, %rax # imm = 0x7FFFFFFFFFFFFFFF
 ; X64-NEXT:    addq %rcx, %rax
@@ -94,25 +89,21 @@ define i64 @func2(i64 %x, i64 %y) nounwind {
 define i16 @func16(i16 %x, i16 %y) nounwind {
 ; X86-LABEL: func16:
 ; X86:       # %bb.0:
-; X86-NEXT:    pushl %esi
 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
 ; X86-NEXT:    xorl %ecx, %ecx
-; X86-NEXT:    movl %eax, %esi
-; X86-NEXT:    subw %dx, %si
+; X86-NEXT:    cmpw %dx, %ax
 ; X86-NEXT:    setns %cl
 ; X86-NEXT:    addl $32767, %ecx # imm = 0x7FFF
 ; X86-NEXT:    subw %dx, %ax
 ; X86-NEXT:    cmovol %ecx, %eax
 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
-; X86-NEXT:    popl %esi
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: func16:
 ; X64:       # %bb.0:
 ; X64-NEXT:    xorl %eax, %eax
-; X64-NEXT:    movl %edi, %ecx
-; X64-NEXT:    subw %si, %cx
+; X64-NEXT:    cmpw %si, %di
 ; X64-NEXT:    setns %al
 ; X64-NEXT:    addl $32767, %eax # imm = 0x7FFF
 ; X64-NEXT:    subw %si, %di
@@ -129,8 +120,7 @@ define i8 @func8(i8 %x, i8 %y) nounwind {
 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %al
 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %dl
 ; X86-NEXT:    xorl %ecx, %ecx
-; X86-NEXT:    movb %al, %ah
-; X86-NEXT:    subb %dl, %ah
+; X86-NEXT:    cmpb %dl, %al
 ; X86-NEXT:    setns %cl
 ; X86-NEXT:    addl $127, %ecx
 ; X86-NEXT:    subb %dl, %al
@@ -142,8 +132,7 @@ define i8 @func8(i8 %x, i8 %y) nounwind {
 ; X64-LABEL: func8:
 ; X64:       # %bb.0:
 ; X64-NEXT:    xorl %ecx, %ecx
-; X64-NEXT:    movl %edi, %eax
-; X64-NEXT:    subb %sil, %al
+; X64-NEXT:    cmpb %sil, %dil
 ; X64-NEXT:    setns %cl
 ; X64-NEXT:    addl $127, %ecx
 ; X64-NEXT:    subb %sil, %dil
@@ -163,8 +152,7 @@ define i4 @func3(i4 %x, i4 %y) nounwind {
 ; X86-NEXT:    shlb $4, %dl
 ; X86-NEXT:    shlb $4, %al
 ; X86-NEXT:    xorl %ecx, %ecx
-; X86-NEXT:    movb %al, %ah
-; X86-NEXT:    subb %dl, %ah
+; X86-NEXT:    cmpb %dl, %al
 ; X86-NEXT:    setns %cl
 ; X86-NEXT:    addl $127, %ecx
 ; X86-NEXT:    subb %dl, %al
@@ -179,8 +167,7 @@ define i4 @func3(i4 %x, i4 %y) nounwind {
 ; X64-NEXT:    shlb $4, %sil
 ; X64-NEXT:    shlb $4, %dil
 ; X64-NEXT:    xorl %ecx, %ecx
-; X64-NEXT:    movl %edi, %eax
-; X64-NEXT:    subb %sil, %al
+; X64-NEXT:    cmpb %sil, %dil
 ; X64-NEXT:    setns %cl
 ; X64-NEXT:    addl $127, %ecx
 ; X64-NEXT:    subb %sil, %dil
@@ -196,15 +183,13 @@ define i4 @func3(i4 %x, i4 %y) nounwind {
 define <4 x i32> @vec(<4 x i32> %x, <4 x i32> %y) nounwind {
 ; X86-LABEL: vec:
 ; X86:       # %bb.0:
-; X86-NEXT:    pushl %ebp
 ; X86-NEXT:    pushl %ebx
 ; X86-NEXT:    pushl %edi
 ; X86-NEXT:    pushl %esi
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; X86-NEXT:    xorl %eax, %eax
-; X86-NEXT:    movl %ecx, %esi
-; X86-NEXT:    subl %edx, %esi
+; X86-NEXT:    cmpl %edx, %ecx
 ; X86-NEXT:    setns %al
 ; X86-NEXT:    addl $2147483647, %eax # imm = 0x7FFFFFFF
 ; X86-NEXT:    subl %edx, %ecx
@@ -212,8 +197,7 @@ define <4 x i32> @vec(<4 x i32> %x, <4 x i32> %y) nounwind {
 ; X86-NEXT:    cmovol %eax, %ecx
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
 ; X86-NEXT:    xorl %eax, %eax
-; X86-NEXT:    movl %edx, %edi
-; X86-NEXT:    subl %esi, %edi
+; X86-NEXT:    cmpl %esi, %edx
 ; X86-NEXT:    setns %al
 ; X86-NEXT:    addl $2147483647, %eax # imm = 0x7FFFFFFF
 ; X86-NEXT:    subl %esi, %edx
@@ -221,8 +205,7 @@ define <4 x i32> @vec(<4 x i32> %x, <4 x i32> %y) nounwind {
 ; X86-NEXT:    cmovol %eax, %edx
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
 ; X86-NEXT:    xorl %eax, %eax
-; X86-NEXT:    movl %esi, %ebx
-; X86-NEXT:    subl %edi, %ebx
+; X86-NEXT:    cmpl %edi, %esi
 ; X86-NEXT:    setns %al
 ; X86-NEXT:    addl $2147483647, %eax # imm = 0x7FFFFFFF
 ; X86-NEXT:    subl %edi, %esi
@@ -230,8 +213,7 @@ define <4 x i32> @vec(<4 x i32> %x, <4 x i32> %y) nounwind {
 ; X86-NEXT:    cmovol %eax, %esi
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    xorl %ebx, %ebx
-; X86-NEXT:    movl %edi, %ebp
-; X86-NEXT:    subl %eax, %ebp
+; X86-NEXT:    cmpl %eax, %edi
 ; X86-NEXT:    setns %bl
 ; X86-NEXT:    addl $2147483647, %ebx # imm = 0x7FFFFFFF
 ; X86-NEXT:    subl %eax, %edi
@@ -244,7 +226,6 @@ define <4 x i32> @vec(<4 x i32> %x, <4 x i32> %y) nounwind {
 ; X86-NEXT:    popl %esi
 ; X86-NEXT:    popl %edi
 ; X86-NEXT:    popl %ebx
-; X86-NEXT:    popl %ebp
 ; X86-NEXT:    retl $4
 ;
 ; X64-LABEL: vec:
index 43e8fca83044df1320558f82560ce8a716878a25..73fbb7c0029b6c424b966d4dfcc6ec60629aad23 100644 (file)
@@ -408,30 +408,28 @@ define void @v12i16(<12 x i16>* %px, <12 x i16>* %py, <12 x i16>* %pz) nounwind
 define void @v1i8(<1 x i8>* %px, <1 x i8>* %py, <1 x i8>* %pz) nounwind {
 ; SSE-LABEL: v1i8:
 ; SSE:       # %bb.0:
-; SSE-NEXT:    movb (%rdi), %cl
-; SSE-NEXT:    movb (%rsi), %dil
+; SSE-NEXT:    movb (%rdi), %al
+; SSE-NEXT:    movb (%rsi), %cl
 ; SSE-NEXT:    xorl %esi, %esi
-; SSE-NEXT:    movl %ecx, %eax
-; SSE-NEXT:    subb %dil, %al
+; SSE-NEXT:    cmpb %cl, %al
 ; SSE-NEXT:    setns %sil
 ; SSE-NEXT:    addl $127, %esi
-; SSE-NEXT:    subb %dil, %cl
-; SSE-NEXT:    movzbl %cl, %eax
+; SSE-NEXT:    subb %cl, %al
+; SSE-NEXT:    movzbl %al, %eax
 ; SSE-NEXT:    cmovol %esi, %eax
 ; SSE-NEXT:    movb %al, (%rdx)
 ; SSE-NEXT:    retq
 ;
 ; AVX-LABEL: v1i8:
 ; AVX:       # %bb.0:
-; AVX-NEXT:    movb (%rdi), %cl
-; AVX-NEXT:    movb (%rsi), %dil
+; AVX-NEXT:    movb (%rdi), %al
+; AVX-NEXT:    movb (%rsi), %cl
 ; AVX-NEXT:    xorl %esi, %esi
-; AVX-NEXT:    movl %ecx, %eax
-; AVX-NEXT:    subb %dil, %al
+; AVX-NEXT:    cmpb %cl, %al
 ; AVX-NEXT:    setns %sil
 ; AVX-NEXT:    addl $127, %esi
-; AVX-NEXT:    subb %dil, %cl
-; AVX-NEXT:    movzbl %cl, %eax
+; AVX-NEXT:    subb %cl, %al
+; AVX-NEXT:    movzbl %al, %eax
 ; AVX-NEXT:    cmovol %esi, %eax
 ; AVX-NEXT:    movb %al, (%rdx)
 ; AVX-NEXT:    retq
@@ -448,8 +446,7 @@ define void @v1i16(<1 x i16>* %px, <1 x i16>* %py, <1 x i16>* %pz) nounwind {
 ; SSE-NEXT:    movzwl (%rdi), %eax
 ; SSE-NEXT:    movzwl (%rsi), %ecx
 ; SSE-NEXT:    xorl %esi, %esi
-; SSE-NEXT:    movl %eax, %edi
-; SSE-NEXT:    subw %cx, %di
+; SSE-NEXT:    cmpw %cx, %ax
 ; SSE-NEXT:    setns %sil
 ; SSE-NEXT:    addl $32767, %esi # imm = 0x7FFF
 ; SSE-NEXT:    subw %cx, %ax
@@ -462,8 +459,7 @@ define void @v1i16(<1 x i16>* %px, <1 x i16>* %py, <1 x i16>* %pz) nounwind {
 ; AVX-NEXT:    movzwl (%rdi), %eax
 ; AVX-NEXT:    movzwl (%rsi), %ecx
 ; AVX-NEXT:    xorl %esi, %esi
-; AVX-NEXT:    movl %eax, %edi
-; AVX-NEXT:    subw %cx, %di
+; AVX-NEXT:    cmpw %cx, %ax
 ; AVX-NEXT:    setns %sil
 ; AVX-NEXT:    addl $32767, %esi # imm = 0x7FFF
 ; AVX-NEXT:    subw %cx, %ax