From 988e5b9752d5344b23a501ef7b7dec2feddbdfae Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Wed, 27 Jun 2018 10:21:06 +0000 Subject: [PATCH] [DAGCombiner] Fold SDIV(%X, MIN_SIGNED) -> SELECT(%X == MIN_SIGNED, 1, 0) Fixes PR37569. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@335719 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 5 +++ test/CodeGen/X86/combine-sdiv.ll | 66 ++++++-------------------------- 2 files changed, 17 insertions(+), 54 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d690f86790d..136bd54077f 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3024,6 +3024,11 @@ SDValue DAGCombiner::visitSDIV(SDNode *N) { // fold (sdiv X, -1) -> 0-X if (N1C && N1C->isAllOnesValue()) return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), N0); + // fold (sdiv X, MIN_SIGNED) -> select(X == MIN_SIGNED, 1, 0) + if (N1C && N1C->getAPIntValue().isMinSignedValue()) + return DAG.getSelect(DL, VT, DAG.getSetCC(DL, VT, N0, N1, ISD::SETEQ), + DAG.getConstant(1, DL, VT), + DAG.getConstant(0, DL, VT)); if (SDValue V = simplifyDivRem(N, DAG)) return V; diff --git a/test/CodeGen/X86/combine-sdiv.ll b/test/CodeGen/X86/combine-sdiv.ll index 2a96b719b6f..c13ba04d5cd 100644 --- a/test/CodeGen/X86/combine-sdiv.ll +++ b/test/CodeGen/X86/combine-sdiv.ll @@ -52,21 +52,13 @@ define <4 x i32> @combine_vec_sdiv_by_negone(<4 x i32> %x) { ret <4 x i32> %1 } -; TODO fold (sdiv x, INT_MIN) -> select((icmp eq x, INT_MIN), 1, 0) +; fold (sdiv x, INT_MIN) -> select((icmp eq x, INT_MIN), 1, 0) define i32 @combine_sdiv_by_minsigned(i32 %x) { ; CHECK-LABEL: combine_sdiv_by_minsigned: ; CHECK: # %bb.0: -; CHECK-NEXT: movslq %edi, %rcx -; CHECK-NEXT: movq %rcx, %rax -; CHECK-NEXT: shlq $31, %rax -; CHECK-NEXT: subq %rcx, %rax -; CHECK-NEXT: shrq $32, %rax -; CHECK-NEXT: subl %ecx, %eax -; CHECK-NEXT: movl %eax, %ecx -; CHECK-NEXT: shrl $31, %ecx -; CHECK-NEXT: sarl $30, %eax -; CHECK-NEXT: addl %ecx, %eax -; CHECK-NEXT: # kill: def $eax killed $eax killed $rax +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: cmpl $-2147483648, %edi # imm = 0x80000000 +; CHECK-NEXT: sete %al ; CHECK-NEXT: retq %1 = sdiv i32 %x, -2147483648 ret i32 %1 @@ -75,61 +67,27 @@ define i32 @combine_sdiv_by_minsigned(i32 %x) { define <4 x i32> @combine_vec_sdiv_by_minsigned(<4 x i32> %x) { ; SSE-LABEL: combine_vec_sdiv_by_minsigned: ; SSE: # %bb.0: -; SSE-NEXT: pshufd {{.*#+}} xmm2 = xmm0[1,1,3,3] -; SSE-NEXT: movdqa {{.*#+}} xmm1 = [2147483647,2147483647,2147483647,2147483647] -; SSE-NEXT: pmuldq %xmm1, %xmm2 -; SSE-NEXT: pmuldq %xmm0, %xmm1 -; SSE-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3] -; SSE-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3],xmm1[4,5],xmm2[6,7] -; SSE-NEXT: psubd %xmm0, %xmm1 -; SSE-NEXT: movdqa %xmm1, %xmm0 +; SSE-NEXT: pcmpeqd {{.*}}(%rip), %xmm0 ; SSE-NEXT: psrld $31, %xmm0 -; SSE-NEXT: psrad $30, %xmm1 -; SSE-NEXT: paddd %xmm0, %xmm1 -; SSE-NEXT: movdqa %xmm1, %xmm0 ; SSE-NEXT: retq ; ; AVX1-LABEL: combine_vec_sdiv_by_minsigned: ; AVX1: # %bb.0: -; AVX1-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,3,3] -; AVX1-NEXT: vmovdqa {{.*#+}} xmm2 = [2147483647,2147483647,2147483647,2147483647] -; AVX1-NEXT: vpmuldq %xmm2, %xmm1, %xmm1 -; AVX1-NEXT: vpmuldq %xmm2, %xmm0, %xmm2 -; AVX1-NEXT: vpshufd {{.*#+}} xmm2 = xmm2[1,1,3,3] -; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm2[0,1],xmm1[2,3],xmm2[4,5],xmm1[6,7] -; AVX1-NEXT: vpsubd %xmm0, %xmm1, %xmm0 -; AVX1-NEXT: vpsrld $31, %xmm0, %xmm1 -; AVX1-NEXT: vpsrad $30, %xmm0, %xmm0 -; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpcmpeqd {{.*}}(%rip), %xmm0, %xmm0 +; AVX1-NEXT: vpsrld $31, %xmm0, %xmm0 ; AVX1-NEXT: retq ; ; AVX2ORLATER-LABEL: combine_vec_sdiv_by_minsigned: ; AVX2ORLATER: # %bb.0: -; AVX2ORLATER-NEXT: vpbroadcastd {{.*#+}} xmm1 = [2147483647,2147483647,2147483647,2147483647] -; AVX2ORLATER-NEXT: vpshufd {{.*#+}} xmm2 = xmm1[1,1,3,3] -; AVX2ORLATER-NEXT: vpshufd {{.*#+}} xmm3 = xmm0[1,1,3,3] -; AVX2ORLATER-NEXT: vpmuldq %xmm2, %xmm3, %xmm2 -; AVX2ORLATER-NEXT: vpmuldq %xmm1, %xmm0, %xmm1 -; AVX2ORLATER-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[1,1,3,3] -; AVX2ORLATER-NEXT: vpblendd {{.*#+}} xmm1 = xmm1[0],xmm2[1],xmm1[2],xmm2[3] -; AVX2ORLATER-NEXT: vpsubd %xmm0, %xmm1, %xmm0 -; AVX2ORLATER-NEXT: vpsrld $31, %xmm0, %xmm1 -; AVX2ORLATER-NEXT: vpsrad $30, %xmm0, %xmm0 -; AVX2ORLATER-NEXT: vpaddd %xmm1, %xmm0, %xmm0 +; AVX2ORLATER-NEXT: vpbroadcastd {{.*#+}} xmm1 = [2147483648,2147483648,2147483648,2147483648] +; AVX2ORLATER-NEXT: vpcmpeqd %xmm1, %xmm0, %xmm0 +; AVX2ORLATER-NEXT: vpsrld $31, %xmm0, %xmm0 ; AVX2ORLATER-NEXT: retq ; ; XOP-LABEL: combine_vec_sdiv_by_minsigned: ; XOP: # %bb.0: -; XOP-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,3,3] -; XOP-NEXT: vmovdqa {{.*#+}} xmm2 = [2147483647,2147483647,2147483647,2147483647] -; XOP-NEXT: vpmuldq %xmm2, %xmm1, %xmm1 -; XOP-NEXT: vpmuldq %xmm2, %xmm0, %xmm2 -; XOP-NEXT: vpshufd {{.*#+}} xmm2 = xmm2[1,1,3,3] -; XOP-NEXT: vpblendw {{.*#+}} xmm1 = xmm2[0,1],xmm1[2,3],xmm2[4,5],xmm1[6,7] -; XOP-NEXT: vpsubd %xmm0, %xmm1, %xmm0 -; XOP-NEXT: vpsrld $31, %xmm0, %xmm1 -; XOP-NEXT: vpsrad $30, %xmm0, %xmm0 -; XOP-NEXT: vpaddd %xmm1, %xmm0, %xmm0 +; XOP-NEXT: vpcomeqd {{.*}}(%rip), %xmm0, %xmm0 +; XOP-NEXT: vpsrld $31, %xmm0, %xmm0 ; XOP-NEXT: retq %1 = sdiv <4 x i32> %x, ret <4 x i32> %1 -- 2.11.0