From 0906c8fc1c684ecbfe731c3c2f5d224dd8a6c1ce Mon Sep 17 00:00:00 2001 From: Michael Kuperstein Date: Wed, 28 Jan 2015 14:08:22 +0000 Subject: [PATCH] [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 --- lib/Target/X86/X86ISelLowering.cpp | 5 +- test/CodeGen/X86/imul.ll | 110 ++++++++++++++++++ test/CodeGen/X86/imul64-lea.ll | 25 ---- .../LoopStrengthReduce/X86/ivchain-X86.ll | 4 +- 4 files changed, 115 insertions(+), 29 deletions(-) create mode 100644 test/CodeGen/X86/imul.ll delete mode 100644 test/CodeGen/X86/imul64-lea.ll diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index dc89fce83a0..5aa0d9d6dbb 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1721,8 +1721,7 @@ void X86TargetLowering::resetOperationActions() { setTargetDAGCombine(ISD::SETCC); setTargetDAGCombine(ISD::INTRINSIC_WO_CHAIN); setTargetDAGCombine(ISD::BUILD_VECTOR); - if (Subtarget->is64Bit()) - setTargetDAGCombine(ISD::MUL); + setTargetDAGCombine(ISD::MUL); setTargetDAGCombine(ISD::XOR); computeRegisterProperties(); @@ -24046,7 +24045,7 @@ static SDValue PerformMulCombine(SDNode *N, SelectionDAG &DAG, return SDValue(); EVT VT = N->getValueType(0); - if (VT != MVT::i64) + if (VT != MVT::i64 && VT != MVT::i32) return SDValue(); ConstantSDNode *C = dyn_cast(N->getOperand(1)); diff --git a/test/CodeGen/X86/imul.ll b/test/CodeGen/X86/imul.ll new file mode 100644 index 00000000000..c64b4e302b9 --- /dev/null +++ b/test/CodeGen/X86/imul.ll @@ -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 +} diff --git a/test/CodeGen/X86/imul64-lea.ll b/test/CodeGen/X86/imul64-lea.ll deleted file mode 100644 index 047c129ddb3..00000000000 --- a/test/CodeGen/X86/imul64-lea.ll +++ /dev/null @@ -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 -} - diff --git a/test/Transforms/LoopStrengthReduce/X86/ivchain-X86.ll b/test/Transforms/LoopStrengthReduce/X86/ivchain-X86.ll index 937791dca41..d8636a8ad41 100644 --- a/test/Transforms/LoopStrengthReduce/X86/ivchain-X86.ll +++ b/test/Transforms/LoopStrengthReduce/X86/ivchain-X86.ll @@ -59,7 +59,9 @@ exit: ; ; X32: @user ; expensive address computation in the preheader -; X32: imul +; X32: shll $4 +; X32: lea +; X32: lea ; X32: %loop ; complex address modes ; X32: (%{{[^)]+}},%{{[^)]+}}, -- 2.34.1