mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
[X86] Reduce some 32-bit imuls into lea + shl
Reduce integer multiplication by a constant of the form k*2^c, where k is in {3,5,9} into a lea + shl. Previously it was only done for imulq on 64-bit platforms, but it makes sense for imull and 32-bit as well. Differential Revision: http://reviews.llvm.org/D7196 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227308 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e5b95695ea
commit
0906c8fc1c
@ -1721,8 +1721,7 @@ void X86TargetLowering::resetOperationActions() {
|
|||||||
setTargetDAGCombine(ISD::SETCC);
|
setTargetDAGCombine(ISD::SETCC);
|
||||||
setTargetDAGCombine(ISD::INTRINSIC_WO_CHAIN);
|
setTargetDAGCombine(ISD::INTRINSIC_WO_CHAIN);
|
||||||
setTargetDAGCombine(ISD::BUILD_VECTOR);
|
setTargetDAGCombine(ISD::BUILD_VECTOR);
|
||||||
if (Subtarget->is64Bit())
|
setTargetDAGCombine(ISD::MUL);
|
||||||
setTargetDAGCombine(ISD::MUL);
|
|
||||||
setTargetDAGCombine(ISD::XOR);
|
setTargetDAGCombine(ISD::XOR);
|
||||||
|
|
||||||
computeRegisterProperties();
|
computeRegisterProperties();
|
||||||
@ -24046,7 +24045,7 @@ static SDValue PerformMulCombine(SDNode *N, SelectionDAG &DAG,
|
|||||||
return SDValue();
|
return SDValue();
|
||||||
|
|
||||||
EVT VT = N->getValueType(0);
|
EVT VT = N->getValueType(0);
|
||||||
if (VT != MVT::i64)
|
if (VT != MVT::i64 && VT != MVT::i32)
|
||||||
return SDValue();
|
return SDValue();
|
||||||
|
|
||||||
ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1));
|
ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1));
|
||||||
|
110
test/CodeGen/X86/imul.ll
Normal file
110
test/CodeGen/X86/imul.ll
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu | FileCheck %s --check-prefix=X64
|
||||||
|
; RUN: llc < %s -mtriple=x86_64-pc-linux-gnux32 | FileCheck %s --check-prefix=X64
|
||||||
|
; RUN: llc < %s -mtriple=i686-pc-linux | FileCheck %s --check-prefix=X86
|
||||||
|
|
||||||
|
define i32 @mul4_32(i32 %A) {
|
||||||
|
; X64-LABEL: mul4_32:
|
||||||
|
; X64: leal
|
||||||
|
; X86-LABEL: mul4_32:
|
||||||
|
; X86: shll
|
||||||
|
%mul = mul i32 %A, 4
|
||||||
|
ret i32 %mul
|
||||||
|
}
|
||||||
|
|
||||||
|
define i64 @mul4_64(i64 %A) {
|
||||||
|
; X64-LABEL: mul4_64:
|
||||||
|
; X64: leaq
|
||||||
|
; X86-LABEL: mul4_64:
|
||||||
|
; X86: shldl
|
||||||
|
; X86: shll
|
||||||
|
%mul = mul i64 %A, 4
|
||||||
|
ret i64 %mul
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @mul4096_32(i32 %A) {
|
||||||
|
; X64-LABEL: mul4096_32:
|
||||||
|
; X64: shll
|
||||||
|
; X86-LABEL: mul4096_32:
|
||||||
|
; X86: shll
|
||||||
|
%mul = mul i32 %A, 4096
|
||||||
|
ret i32 %mul
|
||||||
|
}
|
||||||
|
|
||||||
|
define i64 @mul4096_64(i64 %A) {
|
||||||
|
; X64-LABEL: mul4096_64:
|
||||||
|
; X64: shlq
|
||||||
|
; X86-LABEL: mul4096_64:
|
||||||
|
; X86: shldl
|
||||||
|
; X86: shll
|
||||||
|
%mul = mul i64 %A, 4096
|
||||||
|
ret i64 %mul
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @mulmin4096_32(i32 %A) {
|
||||||
|
; X64-LABEL: mulmin4096_32:
|
||||||
|
; X64: shll
|
||||||
|
; X64-NEXT: negl
|
||||||
|
; X86-LABEL: mulmin4096_32:
|
||||||
|
; X86: shll
|
||||||
|
; X86-NEXT: negl
|
||||||
|
%mul = mul i32 %A, -4096
|
||||||
|
ret i32 %mul
|
||||||
|
}
|
||||||
|
|
||||||
|
define i64 @mulmin4096_64(i64 %A) {
|
||||||
|
; X64-LABEL: mulmin4096_64:
|
||||||
|
; X64: shlq
|
||||||
|
; X64-NEXT: negq
|
||||||
|
; X86-LABEL: mulmin4096_64:
|
||||||
|
; X86: shldl
|
||||||
|
; X86-NEXT: shll
|
||||||
|
; X86-NEXT: xorl
|
||||||
|
; X86-NEXT: negl
|
||||||
|
; X86-NEXT: sbbl
|
||||||
|
%mul = mul i64 %A, -4096
|
||||||
|
ret i64 %mul
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @mul3_32(i32 %A) {
|
||||||
|
; X64-LABEL: mul3_32:
|
||||||
|
; X64: leal
|
||||||
|
; X86-LABEL: mul3_32:
|
||||||
|
; But why?!
|
||||||
|
; X86: imull
|
||||||
|
%mul = mul i32 %A, 3
|
||||||
|
ret i32 %mul
|
||||||
|
}
|
||||||
|
|
||||||
|
define i64 @mul3_64(i64 %A) {
|
||||||
|
; X64-LABEL: mul3_64:
|
||||||
|
; X64: leaq
|
||||||
|
; X86-LABEL: mul3_64:
|
||||||
|
; X86: mull
|
||||||
|
; X86-NEXT: imull
|
||||||
|
%mul = mul i64 %A, 3
|
||||||
|
ret i64 %mul
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @mul40_32(i32 %A) {
|
||||||
|
; X64-LABEL: mul40_32:
|
||||||
|
; X64: shll
|
||||||
|
; X64-NEXT: leal
|
||||||
|
; X86-LABEL: mul40_32:
|
||||||
|
; X86: shll
|
||||||
|
; X86-NEXT: leal
|
||||||
|
%mul = mul i32 %A, 40
|
||||||
|
ret i32 %mul
|
||||||
|
}
|
||||||
|
|
||||||
|
define i64 @mul40_64(i64 %A) {
|
||||||
|
; X64-LABEL: mul40_64:
|
||||||
|
; X64: shlq
|
||||||
|
; X64-NEXT: leaq
|
||||||
|
; X86-LABEL: mul40_64:
|
||||||
|
; X86: leal
|
||||||
|
; X86-NEXT: movl
|
||||||
|
; X86-NEXT: mull
|
||||||
|
; X86-NEXT: leal
|
||||||
|
%mul = mul i64 %A, 40
|
||||||
|
ret i64 %mul
|
||||||
|
}
|
@ -1,25 +0,0 @@
|
|||||||
; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu | FileCheck %s
|
|
||||||
; RUN: llc < %s -mtriple=x86_64-pc-linux-gnux32 | FileCheck %s
|
|
||||||
|
|
||||||
; Test that 64-bit LEAs are generated for both LP64 and ILP32 in 64-bit mode.
|
|
||||||
declare i64 @foo64()
|
|
||||||
|
|
||||||
define i64 @test64() {
|
|
||||||
%tmp.0 = tail call i64 @foo64( )
|
|
||||||
%tmp.1 = mul i64 %tmp.0, 9
|
|
||||||
; CHECK-NOT: mul
|
|
||||||
; CHECK: leaq
|
|
||||||
ret i64 %tmp.1
|
|
||||||
}
|
|
||||||
|
|
||||||
; Test that 32-bit LEAs are generated for both LP64 and ILP32 in 64-bit mode.
|
|
||||||
declare i32 @foo32()
|
|
||||||
|
|
||||||
define i32 @test32() {
|
|
||||||
%tmp.0 = tail call i32 @foo32( )
|
|
||||||
%tmp.1 = mul i32 %tmp.0, 9
|
|
||||||
; CHECK-NOT: mul
|
|
||||||
; CHECK: leal
|
|
||||||
ret i32 %tmp.1
|
|
||||||
}
|
|
||||||
|
|
@ -59,7 +59,9 @@ exit:
|
|||||||
;
|
;
|
||||||
; X32: @user
|
; X32: @user
|
||||||
; expensive address computation in the preheader
|
; expensive address computation in the preheader
|
||||||
; X32: imul
|
; X32: shll $4
|
||||||
|
; X32: lea
|
||||||
|
; X32: lea
|
||||||
; X32: %loop
|
; X32: %loop
|
||||||
; complex address modes
|
; complex address modes
|
||||||
; X32: (%{{[^)]+}},%{{[^)]+}},
|
; X32: (%{{[^)]+}},%{{[^)]+}},
|
||||||
|
Loading…
Reference in New Issue
Block a user