From f4d03213f3ca31c67339a82489fc930f4cfd56f6 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 14 Oct 2019 06:47:56 +0000 Subject: [PATCH] [X86] Teach EmitTest to handle ISD::SSUBO/USUBO in order to use the Z flag from the subtract directly during isel. 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. llvm-svn: 374755 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 7 +++++ llvm/test/CodeGen/X86/known-bits.ll | 22 +++++++--------- llvm/test/CodeGen/X86/ssub_sat.ll | 45 ++++++++++----------------------- llvm/test/CodeGen/X86/ssub_sat_vec.ll | 28 +++++++++----------- 4 files changed, 41 insertions(+), 61 deletions(-) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index a340eff9..c649a90 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -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; diff --git a/llvm/test/CodeGen/X86/known-bits.ll b/llvm/test/CodeGen/X86/known-bits.ll index d9a7921..8e2e9c0 100644 --- a/llvm/test/CodeGen/X86/known-bits.ll +++ b/llvm/test/CodeGen/X86/known-bits.ll @@ -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: diff --git a/llvm/test/CodeGen/X86/ssub_sat.ll b/llvm/test/CodeGen/X86/ssub_sat.ll index 62724e9..51ca6d8 100644 --- a/llvm/test/CodeGen/X86/ssub_sat.ll +++ b/llvm/test/CodeGen/X86/ssub_sat.ll @@ -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: diff --git a/llvm/test/CodeGen/X86/ssub_sat_vec.ll b/llvm/test/CodeGen/X86/ssub_sat_vec.ll index 43e8fca..73fbb7c 100644 --- a/llvm/test/CodeGen/X86/ssub_sat_vec.ll +++ b/llvm/test/CodeGen/X86/ssub_sat_vec.ll @@ -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 -- 2.7.4