mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-13 23:00:33 +00:00
[X86ISelLowering] Add additional support for multiplication-to-shift conversion.
Summary: This patch adds support of conversion (mul x, 2^N + 1) => (add (shl x, N), x) and (mul x, 2^N - 1) => (sub (shl x, N), x) if the multiplication can not be converted to LEA + SHL or LEA + LEA. LLVM has already supported this on ARM, and it should also be useful on X86. Note the patch currently only applies to cases where the constant operand is positive, and I am planing to add another patch to support negative cases after this. Reviewers: craig.topper, RKSimon Subscribers: aemerson, llvm-commits Differential Revision: http://reviews.llvm.org/D14603 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@255415 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9bc6874751
commit
f99bcae76f
@ -24738,9 +24738,11 @@ static SDValue PerformMulCombine(SDNode *N, SelectionDAG &DAG,
|
||||
MulAmt1 = 3;
|
||||
MulAmt2 = MulAmt / 3;
|
||||
}
|
||||
|
||||
SDLoc DL(N);
|
||||
SDValue NewMul;
|
||||
if (MulAmt2 &&
|
||||
(isPowerOf2_64(MulAmt2) || MulAmt2 == 3 || MulAmt2 == 5 || MulAmt2 == 9)){
|
||||
SDLoc DL(N);
|
||||
|
||||
if (isPowerOf2_64(MulAmt2) &&
|
||||
!(N->hasOneUse() && N->use_begin()->getOpcode() == ISD::ADD))
|
||||
@ -24749,7 +24751,6 @@ static SDValue PerformMulCombine(SDNode *N, SelectionDAG &DAG,
|
||||
// is an add.
|
||||
std::swap(MulAmt1, MulAmt2);
|
||||
|
||||
SDValue NewMul;
|
||||
if (isPowerOf2_64(MulAmt1))
|
||||
NewMul = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
|
||||
DAG.getConstant(Log2_64(MulAmt1), DL, MVT::i8));
|
||||
@ -24763,10 +24764,31 @@ static SDValue PerformMulCombine(SDNode *N, SelectionDAG &DAG,
|
||||
else
|
||||
NewMul = DAG.getNode(X86ISD::MUL_IMM, DL, VT, NewMul,
|
||||
DAG.getConstant(MulAmt2, DL, VT));
|
||||
}
|
||||
|
||||
if (!NewMul) {
|
||||
assert(MulAmt != 0 && MulAmt != (VT == MVT::i64 ? UINT64_MAX : UINT32_MAX)
|
||||
&& "Both cases that could cause potential overflows should have "
|
||||
"already been handled.");
|
||||
if (isPowerOf2_64(MulAmt - 1))
|
||||
// (mul x, 2^N + 1) => (add (shl x, N), x)
|
||||
NewMul = DAG.getNode(ISD::ADD, DL, VT, N->getOperand(0),
|
||||
DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
|
||||
DAG.getConstant(Log2_64(MulAmt - 1), DL,
|
||||
MVT::i8)));
|
||||
|
||||
else if (isPowerOf2_64(MulAmt + 1))
|
||||
// (mul x, 2^N - 1) => (sub (shl x, N), x)
|
||||
NewMul = DAG.getNode(ISD::SUB, DL, VT, DAG.getNode(ISD::SHL, DL, VT,
|
||||
N->getOperand(0),
|
||||
DAG.getConstant(Log2_64(MulAmt + 1),
|
||||
DL, MVT::i8)), N->getOperand(0));
|
||||
}
|
||||
|
||||
if (NewMul)
|
||||
// Do not add new nodes to DAG combiner worklist.
|
||||
DCI.CombineTo(N, NewMul, false);
|
||||
}
|
||||
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
|
@ -126,3 +126,48 @@ define i32 @mul40_32_minsize(i32 %A) minsize {
|
||||
%mul = mul i32 %A, 40
|
||||
ret i32 %mul
|
||||
}
|
||||
|
||||
define i32 @mul33_32(i32 %A) {
|
||||
; X64-LABEL: mul33_32:
|
||||
; X64: shll
|
||||
; X64-NEXT: leal
|
||||
; X86-LABEL: mul33_32:
|
||||
; X86: shll
|
||||
; X86-NEXT: addl
|
||||
%mul = mul i32 %A, 33
|
||||
ret i32 %mul
|
||||
}
|
||||
|
||||
define i32 @mul31_32(i32 %A) {
|
||||
; X64-LABEL: mul31_32:
|
||||
; X64: shll
|
||||
; X64-NEXT: subl
|
||||
; X86-LABEL: mul31_32:
|
||||
; X86: shll
|
||||
; X86-NEXT: subl
|
||||
%mul = mul i32 %A, 31
|
||||
ret i32 %mul
|
||||
}
|
||||
|
||||
define i32 @mul0_32(i32 %A) {
|
||||
; X64-LABEL: mul0_32:
|
||||
; X64: xorl %eax, %eax
|
||||
%mul = mul i32 %A, 0
|
||||
ret i32 %mul
|
||||
}
|
||||
|
||||
define i32 @mul4294967295_32(i32 %A) {
|
||||
; X64-LABEL: mul4294967295_32:
|
||||
; X64: negl %edi
|
||||
; X64-NEXT: movl %edi, %eax
|
||||
%mul = mul i32 %A, 4294967295
|
||||
ret i32 %mul
|
||||
}
|
||||
|
||||
define i64 @mul18446744073709551615_64(i64 %A) {
|
||||
; X64-LABEL: mul18446744073709551615_64:
|
||||
; X64: negq %rdi
|
||||
; X64-NEXT: movq %rdi, %rax
|
||||
%mul = mul i64 %A, 18446744073709551615
|
||||
ret i64 %mul
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user