Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit d277be2

Browse files
committed
[X86] Expand mul by pow2 + 2 using a shift and two adds similar to what we do for pow2 - 2.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@337874 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 7cc443c commit d277be2

File tree

4 files changed

+162
-11
lines changed

4 files changed

+162
-11
lines changed

lib/Target/X86/X86ISelLowering.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33920,35 +33920,39 @@ static SDValue combineMul(SDNode *N, SelectionDAG &DAG,
3392033920
int64_t SignMulAmt = C->getSExtValue();
3392133921
if ((SignMulAmt != INT64_MIN) && (SignMulAmt != INT64_MAX) &&
3392233922
(SignMulAmt != -INT64_MAX)) {
33923-
int NumSign = SignMulAmt > 0 ? 1 : -1;
33924-
bool IsPowerOf2_64PlusOne = isPowerOf2_64(NumSign * SignMulAmt - 1);
33925-
bool IsPowerOf2_64MinusOne = isPowerOf2_64(NumSign * SignMulAmt + 1);
33926-
bool IsPowerOf2_64MinusTwo = isPowerOf2_64(NumSign * SignMulAmt + 2);
33927-
if (IsPowerOf2_64PlusOne) {
33923+
int64_t AbsMulAmt = SignMulAmt < 0 ? -SignMulAmt : SignMulAmt;
33924+
if (isPowerOf2_64(AbsMulAmt - 1)) {
3392833925
// (mul x, 2^N + 1) => (add (shl x, N), x)
3392933926
NewMul = DAG.getNode(
3393033927
ISD::ADD, DL, VT, N->getOperand(0),
3393133928
DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
33932-
DAG.getConstant(Log2_64(NumSign * SignMulAmt - 1), DL,
33929+
DAG.getConstant(Log2_64(AbsMulAmt - 1), DL,
3393333930
MVT::i8)));
3393433931
// To negate, subtract the number from zero
3393533932
if (SignMulAmt < 0)
3393633933
NewMul = DAG.getNode(ISD::SUB, DL, VT,
3393733934
DAG.getConstant(0, DL, VT), NewMul);
33938-
} else if (IsPowerOf2_64MinusOne) {
33935+
} else if (isPowerOf2_64(AbsMulAmt + 1)) {
3393933936
// (mul x, 2^N - 1) => (sub (shl x, N), x)
3394033937
NewMul = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
33941-
DAG.getConstant(Log2_64(NumSign * SignMulAmt + 1),
33938+
DAG.getConstant(Log2_64(AbsMulAmt + 1),
3394233939
DL, MVT::i8));
3394333940
// To negate, reverse the operands of the subtract.
3394433941
if (SignMulAmt < 0)
3394533942
NewMul = DAG.getNode(ISD::SUB, DL, VT, N->getOperand(0), NewMul);
3394633943
else
3394733944
NewMul = DAG.getNode(ISD::SUB, DL, VT, NewMul, N->getOperand(0));
33948-
} else if (IsPowerOf2_64MinusTwo && NumSign == 1) {
33949-
// (mul x, 2^N - 1) => (sub (shl x, N), x)
33945+
} else if (SignMulAmt >= 0 && isPowerOf2_64(AbsMulAmt - 2)) {
33946+
// (mul x, 2^N + 2) => (add (add (shl x, N), x), x)
33947+
NewMul = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
33948+
DAG.getConstant(Log2_64(AbsMulAmt - 2),
33949+
DL, MVT::i8));
33950+
NewMul = DAG.getNode(ISD::ADD, DL, VT, NewMul, N->getOperand(0));
33951+
NewMul = DAG.getNode(ISD::ADD, DL, VT, NewMul, N->getOperand(0));
33952+
} else if (SignMulAmt >= 0 && isPowerOf2_64(AbsMulAmt + 2)) {
33953+
// (mul x, 2^N - 2) => (sub (sub (shl x, N), x), x)
3395033954
NewMul = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
33951-
DAG.getConstant(Log2_64(NumSign * SignMulAmt + 2),
33955+
DAG.getConstant(Log2_64(AbsMulAmt + 2),
3395233956
DL, MVT::i8));
3395333957
NewMul = DAG.getNode(ISD::SUB, DL, VT, NewMul, N->getOperand(0));
3395433958
NewMul = DAG.getNode(ISD::SUB, DL, VT, NewMul, N->getOperand(0));

test/CodeGen/X86/mul-constant-i16.ll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,30 @@ define i16 @test_mul_by_62(i16 %x) {
702702
ret i16 %mul
703703
}
704704

705+
define i16 @test_mul_by_66(i16 %x) {
706+
; X86-LABEL: test_mul_by_66:
707+
; X86: # %bb.0:
708+
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
709+
; X86-NEXT: movl %ecx, %eax
710+
; X86-NEXT: shll $6, %eax
711+
; X86-NEXT: addl %ecx, %eax
712+
; X86-NEXT: addl %ecx, %eax
713+
; X86-NEXT: # kill: def $ax killed $ax killed $eax
714+
; X86-NEXT: retl
715+
;
716+
; X64-LABEL: test_mul_by_66:
717+
; X64: # %bb.0:
718+
; X64-NEXT: # kill: def $edi killed $edi def $rdi
719+
; X64-NEXT: movl %edi, %eax
720+
; X64-NEXT: shll $6, %eax
721+
; X64-NEXT: leal (%rax,%rdi), %eax
722+
; X64-NEXT: addl %edi, %eax
723+
; X64-NEXT: # kill: def $ax killed $ax killed $eax
724+
; X64-NEXT: retq
725+
%mul = mul nsw i16 %x, 66
726+
ret i16 %mul
727+
}
728+
705729
define i16 @test_mul_by_73(i16 %x) {
706730
; X86-LABEL: test_mul_by_73:
707731
; X86: # %bb.0:

test/CodeGen/X86/mul-constant-i32.ll

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,6 +1833,66 @@ define i32 @test_mul_by_62(i32 %x) {
18331833
ret i32 %mul
18341834
}
18351835

1836+
define i32 @test_mul_by_66(i32 %x) {
1837+
; X86-LABEL: test_mul_by_66:
1838+
; X86: # %bb.0:
1839+
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
1840+
; X86-NEXT: movl %ecx, %eax
1841+
; X86-NEXT: shll $6, %eax
1842+
; X86-NEXT: addl %ecx, %eax
1843+
; X86-NEXT: addl %ecx, %eax
1844+
; X86-NEXT: retl
1845+
;
1846+
; X64-HSW-LABEL: test_mul_by_66:
1847+
; X64-HSW: # %bb.0:
1848+
; X64-HSW-NEXT: # kill: def $edi killed $edi def $rdi
1849+
; X64-HSW-NEXT: movl %edi, %eax # sched: [1:0.25]
1850+
; X64-HSW-NEXT: shll $6, %eax # sched: [1:0.50]
1851+
; X64-HSW-NEXT: leal (%rax,%rdi), %eax # sched: [1:0.50]
1852+
; X64-HSW-NEXT: addl %edi, %eax # sched: [1:0.25]
1853+
; X64-HSW-NEXT: retq # sched: [7:1.00]
1854+
;
1855+
; X64-JAG-LABEL: test_mul_by_66:
1856+
; X64-JAG: # %bb.0:
1857+
; X64-JAG-NEXT: # kill: def $edi killed $edi def $rdi
1858+
; X64-JAG-NEXT: movl %edi, %eax # sched: [1:0.50]
1859+
; X64-JAG-NEXT: shll $6, %eax # sched: [1:0.50]
1860+
; X64-JAG-NEXT: leal (%rax,%rdi), %eax # sched: [1:0.50]
1861+
; X64-JAG-NEXT: addl %edi, %eax # sched: [1:0.50]
1862+
; X64-JAG-NEXT: retq # sched: [4:1.00]
1863+
;
1864+
; X86-NOOPT-LABEL: test_mul_by_66:
1865+
; X86-NOOPT: # %bb.0:
1866+
; X86-NOOPT-NEXT: imull $66, {{[0-9]+}}(%esp), %eax
1867+
; X86-NOOPT-NEXT: retl
1868+
;
1869+
; HSW-NOOPT-LABEL: test_mul_by_66:
1870+
; HSW-NOOPT: # %bb.0:
1871+
; HSW-NOOPT-NEXT: imull $66, %edi, %eax # sched: [3:1.00]
1872+
; HSW-NOOPT-NEXT: retq # sched: [7:1.00]
1873+
;
1874+
; JAG-NOOPT-LABEL: test_mul_by_66:
1875+
; JAG-NOOPT: # %bb.0:
1876+
; JAG-NOOPT-NEXT: imull $66, %edi, %eax # sched: [3:1.00]
1877+
; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
1878+
;
1879+
; X64-SLM-LABEL: test_mul_by_66:
1880+
; X64-SLM: # %bb.0:
1881+
; X64-SLM-NEXT: # kill: def $edi killed $edi def $rdi
1882+
; X64-SLM-NEXT: movl %edi, %eax # sched: [1:0.50]
1883+
; X64-SLM-NEXT: shll $6, %eax # sched: [1:1.00]
1884+
; X64-SLM-NEXT: leal (%rax,%rdi), %eax # sched: [1:1.00]
1885+
; X64-SLM-NEXT: addl %edi, %eax # sched: [1:0.50]
1886+
; X64-SLM-NEXT: retq # sched: [4:1.00]
1887+
;
1888+
; SLM-NOOPT-LABEL: test_mul_by_66:
1889+
; SLM-NOOPT: # %bb.0:
1890+
; SLM-NOOPT-NEXT: imull $66, %edi, %eax # sched: [3:1.00]
1891+
; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
1892+
%mul = mul nsw i32 %x, 66
1893+
ret i32 %mul
1894+
}
1895+
18361896
define i32 @test_mul_by_73(i32 %x) {
18371897
; X86-LABEL: test_mul_by_73:
18381898
; X86: # %bb.0:

test/CodeGen/X86/mul-constant-i64.ll

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1932,6 +1932,69 @@ define i64 @test_mul_by_62(i64 %x) {
19321932
ret i64 %mul
19331933
}
19341934

1935+
define i64 @test_mul_by_66(i64 %x) {
1936+
; X86-LABEL: test_mul_by_66:
1937+
; X86: # %bb.0:
1938+
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
1939+
; X86-NEXT: movl %eax, %ecx
1940+
; X86-NEXT: shll $6, %ecx
1941+
; X86-NEXT: addl %eax, %ecx
1942+
; X86-NEXT: addl %eax, %ecx
1943+
; X86-NEXT: movl $66, %eax
1944+
; X86-NEXT: mull {{[0-9]+}}(%esp)
1945+
; X86-NEXT: addl %ecx, %edx
1946+
; X86-NEXT: retl
1947+
;
1948+
; X64-HSW-LABEL: test_mul_by_66:
1949+
; X64-HSW: # %bb.0:
1950+
; X64-HSW-NEXT: movq %rdi, %rax # sched: [1:0.25]
1951+
; X64-HSW-NEXT: shlq $6, %rax # sched: [1:0.50]
1952+
; X64-HSW-NEXT: leaq (%rax,%rdi), %rax # sched: [1:0.50]
1953+
; X64-HSW-NEXT: addq %rdi, %rax # sched: [1:0.25]
1954+
; X64-HSW-NEXT: retq # sched: [7:1.00]
1955+
;
1956+
; X64-JAG-LABEL: test_mul_by_66:
1957+
; X64-JAG: # %bb.0:
1958+
; X64-JAG-NEXT: movq %rdi, %rax # sched: [1:0.50]
1959+
; X64-JAG-NEXT: shlq $6, %rax # sched: [1:0.50]
1960+
; X64-JAG-NEXT: leaq (%rax,%rdi), %rax # sched: [1:0.50]
1961+
; X64-JAG-NEXT: addq %rdi, %rax # sched: [1:0.50]
1962+
; X64-JAG-NEXT: retq # sched: [4:1.00]
1963+
;
1964+
; X86-NOOPT-LABEL: test_mul_by_66:
1965+
; X86-NOOPT: # %bb.0:
1966+
; X86-NOOPT-NEXT: movl $66, %eax
1967+
; X86-NOOPT-NEXT: mull {{[0-9]+}}(%esp)
1968+
; X86-NOOPT-NEXT: imull $66, {{[0-9]+}}(%esp), %ecx
1969+
; X86-NOOPT-NEXT: addl %ecx, %edx
1970+
; X86-NOOPT-NEXT: retl
1971+
;
1972+
; HSW-NOOPT-LABEL: test_mul_by_66:
1973+
; HSW-NOOPT: # %bb.0:
1974+
; HSW-NOOPT-NEXT: imulq $66, %rdi, %rax # sched: [3:1.00]
1975+
; HSW-NOOPT-NEXT: retq # sched: [7:1.00]
1976+
;
1977+
; JAG-NOOPT-LABEL: test_mul_by_66:
1978+
; JAG-NOOPT: # %bb.0:
1979+
; JAG-NOOPT-NEXT: imulq $66, %rdi, %rax # sched: [6:4.00]
1980+
; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
1981+
;
1982+
; X64-SLM-LABEL: test_mul_by_66:
1983+
; X64-SLM: # %bb.0:
1984+
; X64-SLM-NEXT: movq %rdi, %rax # sched: [1:0.50]
1985+
; X64-SLM-NEXT: shlq $6, %rax # sched: [1:1.00]
1986+
; X64-SLM-NEXT: addq %rdi, %rax # sched: [1:0.50]
1987+
; X64-SLM-NEXT: addq %rdi, %rax # sched: [1:0.50]
1988+
; X64-SLM-NEXT: retq # sched: [4:1.00]
1989+
;
1990+
; SLM-NOOPT-LABEL: test_mul_by_66:
1991+
; SLM-NOOPT: # %bb.0:
1992+
; SLM-NOOPT-NEXT: imulq $66, %rdi, %rax # sched: [3:1.00]
1993+
; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
1994+
%mul = mul nsw i64 %x, 66
1995+
ret i64 %mul
1996+
}
1997+
19351998
define i64 @test_mul_by_73(i64 %x) {
19361999
; X86-LABEL: test_mul_by_73:
19372000
; X86: # %bb.0:

0 commit comments

Comments
 (0)