Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 988e5b9

Browse files
committed
[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
1 parent 1f74921 commit 988e5b9

File tree

2 files changed

+17
-54
lines changed

2 files changed

+17
-54
lines changed

lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3024,6 +3024,11 @@ SDValue DAGCombiner::visitSDIV(SDNode *N) {
30243024
// fold (sdiv X, -1) -> 0-X
30253025
if (N1C && N1C->isAllOnesValue())
30263026
return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), N0);
3027+
// fold (sdiv X, MIN_SIGNED) -> select(X == MIN_SIGNED, 1, 0)
3028+
if (N1C && N1C->getAPIntValue().isMinSignedValue())
3029+
return DAG.getSelect(DL, VT, DAG.getSetCC(DL, VT, N0, N1, ISD::SETEQ),
3030+
DAG.getConstant(1, DL, VT),
3031+
DAG.getConstant(0, DL, VT));
30273032

30283033
if (SDValue V = simplifyDivRem(N, DAG))
30293034
return V;

test/CodeGen/X86/combine-sdiv.ll

Lines changed: 12 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,13 @@ define <4 x i32> @combine_vec_sdiv_by_negone(<4 x i32> %x) {
5252
ret <4 x i32> %1
5353
}
5454

55-
; TODO fold (sdiv x, INT_MIN) -> select((icmp eq x, INT_MIN), 1, 0)
55+
; fold (sdiv x, INT_MIN) -> select((icmp eq x, INT_MIN), 1, 0)
5656
define i32 @combine_sdiv_by_minsigned(i32 %x) {
5757
; CHECK-LABEL: combine_sdiv_by_minsigned:
5858
; CHECK: # %bb.0:
59-
; CHECK-NEXT: movslq %edi, %rcx
60-
; CHECK-NEXT: movq %rcx, %rax
61-
; CHECK-NEXT: shlq $31, %rax
62-
; CHECK-NEXT: subq %rcx, %rax
63-
; CHECK-NEXT: shrq $32, %rax
64-
; CHECK-NEXT: subl %ecx, %eax
65-
; CHECK-NEXT: movl %eax, %ecx
66-
; CHECK-NEXT: shrl $31, %ecx
67-
; CHECK-NEXT: sarl $30, %eax
68-
; CHECK-NEXT: addl %ecx, %eax
69-
; CHECK-NEXT: # kill: def $eax killed $eax killed $rax
59+
; CHECK-NEXT: xorl %eax, %eax
60+
; CHECK-NEXT: cmpl $-2147483648, %edi # imm = 0x80000000
61+
; CHECK-NEXT: sete %al
7062
; CHECK-NEXT: retq
7163
%1 = sdiv i32 %x, -2147483648
7264
ret i32 %1
@@ -75,61 +67,27 @@ define i32 @combine_sdiv_by_minsigned(i32 %x) {
7567
define <4 x i32> @combine_vec_sdiv_by_minsigned(<4 x i32> %x) {
7668
; SSE-LABEL: combine_vec_sdiv_by_minsigned:
7769
; SSE: # %bb.0:
78-
; SSE-NEXT: pshufd {{.*#+}} xmm2 = xmm0[1,1,3,3]
79-
; SSE-NEXT: movdqa {{.*#+}} xmm1 = [2147483647,2147483647,2147483647,2147483647]
80-
; SSE-NEXT: pmuldq %xmm1, %xmm2
81-
; SSE-NEXT: pmuldq %xmm0, %xmm1
82-
; SSE-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
83-
; SSE-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3],xmm1[4,5],xmm2[6,7]
84-
; SSE-NEXT: psubd %xmm0, %xmm1
85-
; SSE-NEXT: movdqa %xmm1, %xmm0
70+
; SSE-NEXT: pcmpeqd {{.*}}(%rip), %xmm0
8671
; SSE-NEXT: psrld $31, %xmm0
87-
; SSE-NEXT: psrad $30, %xmm1
88-
; SSE-NEXT: paddd %xmm0, %xmm1
89-
; SSE-NEXT: movdqa %xmm1, %xmm0
9072
; SSE-NEXT: retq
9173
;
9274
; AVX1-LABEL: combine_vec_sdiv_by_minsigned:
9375
; AVX1: # %bb.0:
94-
; AVX1-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,3,3]
95-
; AVX1-NEXT: vmovdqa {{.*#+}} xmm2 = [2147483647,2147483647,2147483647,2147483647]
96-
; AVX1-NEXT: vpmuldq %xmm2, %xmm1, %xmm1
97-
; AVX1-NEXT: vpmuldq %xmm2, %xmm0, %xmm2
98-
; AVX1-NEXT: vpshufd {{.*#+}} xmm2 = xmm2[1,1,3,3]
99-
; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm2[0,1],xmm1[2,3],xmm2[4,5],xmm1[6,7]
100-
; AVX1-NEXT: vpsubd %xmm0, %xmm1, %xmm0
101-
; AVX1-NEXT: vpsrld $31, %xmm0, %xmm1
102-
; AVX1-NEXT: vpsrad $30, %xmm0, %xmm0
103-
; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm0
76+
; AVX1-NEXT: vpcmpeqd {{.*}}(%rip), %xmm0, %xmm0
77+
; AVX1-NEXT: vpsrld $31, %xmm0, %xmm0
10478
; AVX1-NEXT: retq
10579
;
10680
; AVX2ORLATER-LABEL: combine_vec_sdiv_by_minsigned:
10781
; AVX2ORLATER: # %bb.0:
108-
; AVX2ORLATER-NEXT: vpbroadcastd {{.*#+}} xmm1 = [2147483647,2147483647,2147483647,2147483647]
109-
; AVX2ORLATER-NEXT: vpshufd {{.*#+}} xmm2 = xmm1[1,1,3,3]
110-
; AVX2ORLATER-NEXT: vpshufd {{.*#+}} xmm3 = xmm0[1,1,3,3]
111-
; AVX2ORLATER-NEXT: vpmuldq %xmm2, %xmm3, %xmm2
112-
; AVX2ORLATER-NEXT: vpmuldq %xmm1, %xmm0, %xmm1
113-
; AVX2ORLATER-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
114-
; AVX2ORLATER-NEXT: vpblendd {{.*#+}} xmm1 = xmm1[0],xmm2[1],xmm1[2],xmm2[3]
115-
; AVX2ORLATER-NEXT: vpsubd %xmm0, %xmm1, %xmm0
116-
; AVX2ORLATER-NEXT: vpsrld $31, %xmm0, %xmm1
117-
; AVX2ORLATER-NEXT: vpsrad $30, %xmm0, %xmm0
118-
; AVX2ORLATER-NEXT: vpaddd %xmm1, %xmm0, %xmm0
82+
; AVX2ORLATER-NEXT: vpbroadcastd {{.*#+}} xmm1 = [2147483648,2147483648,2147483648,2147483648]
83+
; AVX2ORLATER-NEXT: vpcmpeqd %xmm1, %xmm0, %xmm0
84+
; AVX2ORLATER-NEXT: vpsrld $31, %xmm0, %xmm0
11985
; AVX2ORLATER-NEXT: retq
12086
;
12187
; XOP-LABEL: combine_vec_sdiv_by_minsigned:
12288
; XOP: # %bb.0:
123-
; XOP-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,3,3]
124-
; XOP-NEXT: vmovdqa {{.*#+}} xmm2 = [2147483647,2147483647,2147483647,2147483647]
125-
; XOP-NEXT: vpmuldq %xmm2, %xmm1, %xmm1
126-
; XOP-NEXT: vpmuldq %xmm2, %xmm0, %xmm2
127-
; XOP-NEXT: vpshufd {{.*#+}} xmm2 = xmm2[1,1,3,3]
128-
; XOP-NEXT: vpblendw {{.*#+}} xmm1 = xmm2[0,1],xmm1[2,3],xmm2[4,5],xmm1[6,7]
129-
; XOP-NEXT: vpsubd %xmm0, %xmm1, %xmm0
130-
; XOP-NEXT: vpsrld $31, %xmm0, %xmm1
131-
; XOP-NEXT: vpsrad $30, %xmm0, %xmm0
132-
; XOP-NEXT: vpaddd %xmm1, %xmm0, %xmm0
89+
; XOP-NEXT: vpcomeqd {{.*}}(%rip), %xmm0, %xmm0
90+
; XOP-NEXT: vpsrld $31, %xmm0, %xmm0
13391
; XOP-NEXT: retq
13492
%1 = sdiv <4 x i32> %x, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>
13593
ret <4 x i32> %1

0 commit comments

Comments
 (0)