[llvm] r304972 - This patch closes PR28513: an optimization of multiplication by different constants.
Eric Christopher via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 16 10:07:57 PDT 2017
Hi Andrew,
This isn't a great commit message. What was the issue and how did you fix
it? What's the difference? This probably should have gone up for re-review
after.
Also, relatedly, we're seeing failures in grub with this. We'll work on
getting a testcase, but can you please revert this in the meantime?
Thanks!
-eric
On Thu, Jun 8, 2017 at 3:20 AM Andrew V. Tischenko via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: avt77
> Date: Thu Jun 8 05:20:13 2017
> New Revision: 304972
>
> URL: http://llvm.org/viewvc/llvm-project?rev=304972&view=rev
> Log:
> This patch closes PR28513: an optimization of multiplication by different
> constants.
> The initial patch was rejected: I fixed the issue and re-apply it.
>
> Added:
> llvm/trunk/test/CodeGen/X86/mul-constant-result.ll
> Modified:
> llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
> llvm/trunk/test/CodeGen/X86/mul-constant-i16.ll
> llvm/trunk/test/CodeGen/X86/mul-constant-i32.ll
> llvm/trunk/test/CodeGen/X86/mul-constant-i64.ll
>
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=304972&r1=304971&r2=304972&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Jun 8 05:20:13 2017
> @@ -81,6 +81,12 @@ static cl::opt<int> ExperimentalPrefLoop
> " of the loop header PC will be 0)."),
> cl::Hidden);
>
> +static cl::opt<bool> MulConstantOptimization(
> + "mul-constant-optimization", cl::init(true),
> + cl::desc("Replace 'mul x, Const' with more effective instructions
> like "
> + "SHIFT, LEA, etc."),
> + cl::Hidden);
> +
> /// Call this when the user attempts to do something unsupported, like
> /// returning a double without SSE2 enabled on x86_64. This is not fatal,
> unlike
> /// report_fatal_error, so calling code should attempt to recover without
> @@ -31031,6 +31037,77 @@ static SDValue reduceVMULWidth(SDNode *N
> }
> }
>
> +static SDValue combineMulSpecial(uint64_t MulAmt, SDNode *N, SelectionDAG
> &DAG,
> + EVT VT, SDLoc DL) {
> +
> + auto combineMulShlAddOrSub = [&](int Mult, int Shift, bool isAdd) {
> + SDValue Result = DAG.getNode(X86ISD::MUL_IMM, DL, VT,
> N->getOperand(0),
> + DAG.getConstant(Mult, DL, VT));
> + Result = DAG.getNode(ISD::SHL, DL, VT, Result,
> + DAG.getConstant(Shift, DL, MVT::i8));
> + Result = DAG.getNode(isAdd ? ISD::ADD : ISD::SUB, DL, VT, Result,
> + N->getOperand(0));
> + return Result;
> + };
> +
> + auto combineMulMulAddOrSub = [&](bool isAdd) {
> + SDValue Result = DAG.getNode(X86ISD::MUL_IMM, DL, VT,
> N->getOperand(0),
> + DAG.getConstant(9, DL, VT));
> + Result = DAG.getNode(ISD::MUL, DL, VT, Result, DAG.getConstant(3, DL,
> VT));
> + Result = DAG.getNode(isAdd ? ISD::ADD : ISD::SUB, DL, VT, Result,
> + N->getOperand(0));
> + return Result;
> + };
> +
> + switch (MulAmt) {
> + default:
> + break;
> + case 11:
> + // mul x, 11 => add ((shl (mul x, 5), 1), x)
> + return combineMulShlAddOrSub(5, 1, /*isAdd*/ true);
> + case 21:
> + // mul x, 21 => add ((shl (mul x, 5), 2), x)
> + return combineMulShlAddOrSub(5, 2, /*isAdd*/ true);
> + case 22:
> + // mul x, 22 => add (add ((shl (mul x, 5), 2), x), x)
> + return DAG.getNode(ISD::ADD, DL, VT, N->getOperand(0),
> + combineMulShlAddOrSub(5, 2, /*isAdd*/ true));
> + case 19:
> + // mul x, 19 => sub ((shl (mul x, 5), 2), x)
> + return combineMulShlAddOrSub(5, 2, /*isAdd*/ false);
> + case 13:
> + // mul x, 13 => add ((shl (mul x, 3), 2), x)
> + return combineMulShlAddOrSub(3, 2, /*isAdd*/ true);
> + case 23:
> + // mul x, 13 => sub ((shl (mul x, 3), 3), x)
> + return combineMulShlAddOrSub(3, 3, /*isAdd*/ false);
> + case 14:
> + // mul x, 14 => add (add ((shl (mul x, 3), 2), x), x)
> + return DAG.getNode(ISD::ADD, DL, VT, N->getOperand(0),
> + combineMulShlAddOrSub(3, 2, /*isAdd*/ true));
> + case 26:
> + // mul x, 26 => sub ((mul (mul x, 9), 3), x)
> + return combineMulMulAddOrSub(/*isAdd*/ false);
> + case 28:
> + // mul x, 28 => add ((mul (mul x, 9), 3), x)
> + return combineMulMulAddOrSub(/*isAdd*/ true);
> + case 29:
> + // mul x, 29 => add (add ((mul (mul x, 9), 3), x), x)
> + return DAG.getNode(ISD::ADD, DL, VT, N->getOperand(0),
> + combineMulMulAddOrSub(/*isAdd*/ true));
> + case 30:
> + // mul x, 30 => sub (sub ((shl x, 5), x), x)
> + return DAG.getNode(
> + ISD::SUB, DL, VT,
> + DAG.getNode(ISD::SUB, DL, VT,
> + DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
> + DAG.getConstant(5, DL, MVT::i8)),
> + N->getOperand(0)),
> + N->getOperand(0));
> + }
> + return SDValue();
> +}
> +
> /// Optimize a single multiply with constant into two operations in order
> to
> /// implement it with two cheaper instructions, e.g. LEA + SHL, LEA + LEA.
> static SDValue combineMul(SDNode *N, SelectionDAG &DAG,
> @@ -31040,6 +31117,8 @@ static SDValue combineMul(SDNode *N, Sel
> if (DCI.isBeforeLegalize() && VT.isVector())
> return reduceVMULWidth(N, DAG, Subtarget);
>
> + if (!MulConstantOptimization)
> + return SDValue();
> // An imul is usually smaller than the alternative sequence.
> if (DAG.getMachineFunction().getFunction()->optForMinSize())
> return SDValue();
> @@ -31095,7 +31174,8 @@ static SDValue combineMul(SDNode *N, Sel
> else
> NewMul = DAG.getNode(X86ISD::MUL_IMM, DL, VT, NewMul,
> DAG.getConstant(MulAmt2, DL, VT));
> - }
> + } else if (!Subtarget.slowLEA())
> + NewMul = combineMulSpecial(MulAmt, N, DAG, VT, DL);
>
> if (!NewMul) {
> assert(MulAmt != 0 &&
>
> Modified: llvm/trunk/test/CodeGen/X86/mul-constant-i16.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/mul-constant-i16.ll?rev=304972&r1=304971&r2=304972&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/mul-constant-i16.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/mul-constant-i16.ll Thu Jun 8 05:20:13
> 2017
> @@ -188,13 +188,16 @@ define i16 @test_mul_by_11(i16 %x) {
> ; X86-LABEL: test_mul_by_11:
> ; X86: # BB#0:
> ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
> -; X86-NEXT: imull $11, %eax, %eax
> +; X86-NEXT: leal (%eax,%eax,4), %ecx
> +; X86-NEXT: leal (%eax,%ecx,2), %eax
> ; X86-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X86-NEXT: retl
> ;
> ; X64-LABEL: test_mul_by_11:
> ; X64: # BB#0:
> -; X64-NEXT: imull $11, %edi, %eax
> +; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-NEXT: leal (%rdi,%rdi,4), %eax
> +; X64-NEXT: leal (%rdi,%rax,2), %eax
> ; X64-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X64-NEXT: retq
> %mul = mul nsw i16 %x, 11
> @@ -225,13 +228,16 @@ define i16 @test_mul_by_13(i16 %x) {
> ; X86-LABEL: test_mul_by_13:
> ; X86: # BB#0:
> ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
> -; X86-NEXT: imull $13, %eax, %eax
> +; X86-NEXT: leal (%eax,%eax,2), %ecx
> +; X86-NEXT: leal (%eax,%ecx,4), %eax
> ; X86-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X86-NEXT: retl
> ;
> ; X64-LABEL: test_mul_by_13:
> ; X64: # BB#0:
> -; X64-NEXT: imull $13, %edi, %eax
> +; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-NEXT: leal (%rdi,%rdi,2), %eax
> +; X64-NEXT: leal (%rdi,%rax,4), %eax
> ; X64-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X64-NEXT: retq
> %mul = mul nsw i16 %x, 13
> @@ -241,14 +247,19 @@ define i16 @test_mul_by_13(i16 %x) {
> define i16 @test_mul_by_14(i16 %x) {
> ; X86-LABEL: test_mul_by_14:
> ; X86: # BB#0:
> -; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
> -; X86-NEXT: imull $14, %eax, %eax
> +; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx
> +; X86-NEXT: leal (%ecx,%ecx,2), %eax
> +; X86-NEXT: leal (%ecx,%eax,4), %eax
> +; X86-NEXT: addl %ecx, %eax
> ; X86-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X86-NEXT: retl
> ;
> ; X64-LABEL: test_mul_by_14:
> ; X64: # BB#0:
> -; X64-NEXT: imull $14, %edi, %eax
> +; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-NEXT: leal (%rdi,%rdi,2), %eax
> +; X64-NEXT: leal (%rdi,%rax,4), %eax
> +; X64-NEXT: addl %edi, %eax
> ; X64-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X64-NEXT: retq
> %mul = mul nsw i16 %x, 14
> @@ -337,14 +348,19 @@ define i16 @test_mul_by_18(i16 %x) {
> define i16 @test_mul_by_19(i16 %x) {
> ; X86-LABEL: test_mul_by_19:
> ; X86: # BB#0:
> -; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
> -; X86-NEXT: imull $19, %eax, %eax
> +; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx
> +; X86-NEXT: leal (%ecx,%ecx,4), %eax
> +; X86-NEXT: shll $2, %eax
> +; X86-NEXT: subl %ecx, %eax
> ; X86-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X86-NEXT: retl
> ;
> ; X64-LABEL: test_mul_by_19:
> ; X64: # BB#0:
> -; X64-NEXT: imull $19, %edi, %eax
> +; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-NEXT: leal (%rdi,%rdi,4), %eax
> +; X64-NEXT: shll $2, %eax
> +; X64-NEXT: subl %edi, %eax
> ; X64-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X64-NEXT: retq
> %mul = mul nsw i16 %x, 19
> @@ -375,13 +391,16 @@ define i16 @test_mul_by_21(i16 %x) {
> ; X86-LABEL: test_mul_by_21:
> ; X86: # BB#0:
> ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
> -; X86-NEXT: imull $21, %eax, %eax
> +; X86-NEXT: leal (%eax,%eax,4), %ecx
> +; X86-NEXT: leal (%eax,%ecx,4), %eax
> ; X86-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X86-NEXT: retl
> ;
> ; X64-LABEL: test_mul_by_21:
> ; X64: # BB#0:
> -; X64-NEXT: imull $21, %edi, %eax
> +; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-NEXT: leal (%rdi,%rdi,4), %eax
> +; X64-NEXT: leal (%rdi,%rax,4), %eax
> ; X64-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X64-NEXT: retq
> %mul = mul nsw i16 %x, 21
> @@ -391,14 +410,19 @@ define i16 @test_mul_by_21(i16 %x) {
> define i16 @test_mul_by_22(i16 %x) {
> ; X86-LABEL: test_mul_by_22:
> ; X86: # BB#0:
> -; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
> -; X86-NEXT: imull $22, %eax, %eax
> +; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx
> +; X86-NEXT: leal (%ecx,%ecx,4), %eax
> +; X86-NEXT: leal (%ecx,%eax,4), %eax
> +; X86-NEXT: addl %ecx, %eax
> ; X86-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X86-NEXT: retl
> ;
> ; X64-LABEL: test_mul_by_22:
> ; X64: # BB#0:
> -; X64-NEXT: imull $22, %edi, %eax
> +; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-NEXT: leal (%rdi,%rdi,4), %eax
> +; X64-NEXT: leal (%rdi,%rax,4), %eax
> +; X64-NEXT: addl %edi, %eax
> ; X64-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X64-NEXT: retq
> %mul = mul nsw i16 %x, 22
> @@ -408,14 +432,19 @@ define i16 @test_mul_by_22(i16 %x) {
> define i16 @test_mul_by_23(i16 %x) {
> ; X86-LABEL: test_mul_by_23:
> ; X86: # BB#0:
> -; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
> -; X86-NEXT: imull $23, %eax, %eax
> +; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx
> +; X86-NEXT: leal (%ecx,%ecx,2), %eax
> +; X86-NEXT: shll $3, %eax
> +; X86-NEXT: subl %ecx, %eax
> ; X86-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X86-NEXT: retl
> ;
> ; X64-LABEL: test_mul_by_23:
> ; X64: # BB#0:
> -; X64-NEXT: imull $23, %edi, %eax
> +; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-NEXT: leal (%rdi,%rdi,2), %eax
> +; X64-NEXT: shll $3, %eax
> +; X64-NEXT: subl %edi, %eax
> ; X64-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X64-NEXT: retq
> %mul = mul nsw i16 %x, 23
> @@ -465,14 +494,19 @@ define i16 @test_mul_by_25(i16 %x) {
> define i16 @test_mul_by_26(i16 %x) {
> ; X86-LABEL: test_mul_by_26:
> ; X86: # BB#0:
> -; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
> -; X86-NEXT: imull $26, %eax, %eax
> +; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx
> +; X86-NEXT: leal (%ecx,%ecx,8), %eax
> +; X86-NEXT: leal (%eax,%eax,2), %eax
> +; X86-NEXT: subl %ecx, %eax
> ; X86-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X86-NEXT: retl
> ;
> ; X64-LABEL: test_mul_by_26:
> ; X64: # BB#0:
> -; X64-NEXT: imull $26, %edi, %eax
> +; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-NEXT: leal (%rdi,%rdi,8), %eax
> +; X64-NEXT: leal (%rax,%rax,2), %eax
> +; X64-NEXT: subl %edi, %eax
> ; X64-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X64-NEXT: retq
> %mul = mul nsw i16 %x, 26
> @@ -502,14 +536,19 @@ define i16 @test_mul_by_27(i16 %x) {
> define i16 @test_mul_by_28(i16 %x) {
> ; X86-LABEL: test_mul_by_28:
> ; X86: # BB#0:
> -; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
> -; X86-NEXT: imull $28, %eax, %eax
> +; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx
> +; X86-NEXT: leal (%ecx,%ecx,8), %eax
> +; X86-NEXT: leal (%eax,%eax,2), %eax
> +; X86-NEXT: addl %ecx, %eax
> ; X86-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X86-NEXT: retl
> ;
> ; X64-LABEL: test_mul_by_28:
> ; X64: # BB#0:
> -; X64-NEXT: imull $28, %edi, %eax
> +; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-NEXT: leal (%rdi,%rdi,8), %eax
> +; X64-NEXT: leal (%rax,%rax,2), %eax
> +; X64-NEXT: addl %edi, %eax
> ; X64-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X64-NEXT: retq
> %mul = mul nsw i16 %x, 28
> @@ -519,14 +558,21 @@ define i16 @test_mul_by_28(i16 %x) {
> define i16 @test_mul_by_29(i16 %x) {
> ; X86-LABEL: test_mul_by_29:
> ; X86: # BB#0:
> -; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
> -; X86-NEXT: imull $29, %eax, %eax
> +; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx
> +; X86-NEXT: leal (%ecx,%ecx,8), %eax
> +; X86-NEXT: leal (%eax,%eax,2), %eax
> +; X86-NEXT: addl %ecx, %eax
> +; X86-NEXT: addl %ecx, %eax
> ; X86-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X86-NEXT: retl
> ;
> ; X64-LABEL: test_mul_by_29:
> ; X64: # BB#0:
> -; X64-NEXT: imull $29, %edi, %eax
> +; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-NEXT: leal (%rdi,%rdi,8), %eax
> +; X64-NEXT: leal (%rax,%rax,2), %eax
> +; X64-NEXT: addl %edi, %eax
> +; X64-NEXT: addl %edi, %eax
> ; X64-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X64-NEXT: retq
> %mul = mul nsw i16 %x, 29
> @@ -536,14 +582,20 @@ define i16 @test_mul_by_29(i16 %x) {
> define i16 @test_mul_by_30(i16 %x) {
> ; X86-LABEL: test_mul_by_30:
> ; X86: # BB#0:
> -; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
> -; X86-NEXT: imull $30, %eax, %eax
> +; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx
> +; X86-NEXT: movl %ecx, %eax
> +; X86-NEXT: shll $5, %eax
> +; X86-NEXT: subl %ecx, %eax
> +; X86-NEXT: subl %ecx, %eax
> ; X86-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X86-NEXT: retl
> ;
> ; X64-LABEL: test_mul_by_30:
> ; X64: # BB#0:
> -; X64-NEXT: imull $30, %edi, %eax
> +; X64-NEXT: movl %edi, %eax
> +; X64-NEXT: shll $5, %eax
> +; X64-NEXT: subl %edi, %eax
> +; X64-NEXT: subl %edi, %eax
> ; X64-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> ; X64-NEXT: retq
> %mul = mul nsw i16 %x, 30
> @@ -587,3 +639,30 @@ define i16 @test_mul_by_32(i16 %x) {
> %mul = mul nsw i16 %x, 32
> ret i16 %mul
> }
> +
> +; (x*9+42)*(x*5+2)
> +define i16 @test_mul_spec(i16 %x) nounwind {
> +; X86-LABEL: test_mul_spec:
> +; X86: # BB#0:
> +; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
> +; X86-NEXT: leal 42(%eax,%eax,8), %ecx
> +; X86-NEXT: leal 2(%eax,%eax,4), %eax
> +; X86-NEXT: imull %ecx, %eax
> +; X86-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> +; X86-NEXT: retl
> +;
> +; X64-LABEL: test_mul_spec:
> +; X64: # BB#0:
> +; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-NEXT: leal 42(%rdi,%rdi,8), %ecx
> +; X64-NEXT: leal 2(%rdi,%rdi,4), %eax
> +; X64-NEXT: imull %ecx, %eax
> +; X64-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
> +; X64-NEXT: retq
> + %mul = mul nsw i16 %x, 9
> + %add = add nsw i16 %mul, 42
> + %mul2 = mul nsw i16 %x, 5
> + %add2 = add nsw i16 %mul2, 2
> + %mul3 = mul nsw i16 %add, %add2
> + ret i16 %mul3
> +}
>
> Modified: llvm/trunk/test/CodeGen/X86/mul-constant-i32.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/mul-constant-i32.ll?rev=304972&r1=304971&r2=304972&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/mul-constant-i32.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/mul-constant-i32.ll Thu Jun 8 05:20:13
> 2017
> @@ -1,6 +1,12 @@
> ; NOTE: Assertions have been autogenerated by
> utils/update_llc_test_checks.py
> ; RUN: llc < %s -mtriple=i686-unknown | FileCheck %s --check-prefix=X86
> -; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s --check-prefix=X64
> +; RUN: llc < %s -mtriple=x86_64-unknown -print-schedule=true
> -mcpu=haswell| FileCheck %s --check-prefix=X64-HSW
> +; RUN: llc < %s -mtriple=x86_64-unknown -print-schedule=true
> -mcpu=btver2| FileCheck %s --check-prefix=X64-JAG
> +; RUN: llc < %s -mtriple=i686-unknown -mul-constant-optimization=false |
> FileCheck %s --check-prefix=X86-NOOPT
> +; RUN: llc < %s -mtriple=x86_64-unknown -mul-constant-optimization=false
> -print-schedule=true -mcpu=haswell| FileCheck %s --check-prefix=HSW-NOOPT
> +; RUN: llc < %s -mtriple=x86_64-unknown -mul-constant-optimization=false
> -print-schedule=true -mcpu=btver2| FileCheck %s --check-prefix=JAG-NOOPT
> +; RUN: llc < %s -mtriple=x86_64-unknown -print-schedule=true -mcpu=slm|
> FileCheck %s --check-prefix=X64-SLM
> +; RUN: llc < %s -mtriple=x86_64-unknown -mul-constant-optimization=false
> -print-schedule=true -mcpu=slm| FileCheck %s --check-prefix=SLM-NOOPT
>
> define i32 @test_mul_by_1(i32 %x) {
> ; X86-LABEL: test_mul_by_1:
> @@ -8,10 +14,40 @@ define i32 @test_mul_by_1(i32 %x) {
> ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_1:
> -; X64: # BB#0:
> -; X64-NEXT: movl %edi, %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_1:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: movl %edi, %eax # sched: [1:0.25]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_1:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: movl %edi, %eax # sched: [1:0.17]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_1:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: movl {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_1:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: movl %edi, %eax # sched: [1:0.25]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_1:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: movl %edi, %eax # sched: [1:0.17]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_1:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: movl %edi, %eax # sched: [1:0.50]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_1:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: movl %edi, %eax # sched: [1:0.50]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 1
> ret i32 %mul
> }
> @@ -23,11 +59,47 @@ define i32 @test_mul_by_2(i32 %x) {
> ; X86-NEXT: addl %eax, %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_2:
> -; X64: # BB#0:
> -; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> -; X64-NEXT: leal (%rdi,%rdi), %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_2:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (%rdi,%rdi), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_2:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (%rdi,%rdi), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_2:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: movl {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: addl %eax, %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_2:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; HSW-NOOPT-NEXT: leal (%rdi,%rdi), %eax # sched: [1:0.50]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_2:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; JAG-NOOPT-NEXT: leal (%rdi,%rdi), %eax # sched: [1:0.50]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_2:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-SLM-NEXT: leal (%rdi,%rdi), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_2:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; SLM-NOOPT-NEXT: leal (%rdi,%rdi), %eax # sched: [1:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 2
> ret i32 %mul
> }
> @@ -38,11 +110,46 @@ define i32 @test_mul_by_3(i32 %x) {
> ; X86-NEXT: imull $3, {{[0-9]+}}(%esp), %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_3:
> -; X64: # BB#0:
> -; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> -; X64-NEXT: leal (%rdi,%rdi,2), %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_3:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_3:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_3:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $3, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_3:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; HSW-NOOPT-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:0.50]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_3:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; JAG-NOOPT-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:0.50]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_3:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-SLM-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_3:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; SLM-NOOPT-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 3
> ret i32 %mul
> }
> @@ -54,11 +161,47 @@ define i32 @test_mul_by_4(i32 %x) {
> ; X86-NEXT: shll $2, %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_4:
> -; X64: # BB#0:
> -; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> -; X64-NEXT: leal (,%rdi,4), %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_4:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (,%rdi,4), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_4:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (,%rdi,4), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_4:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: movl {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: shll $2, %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_4:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; HSW-NOOPT-NEXT: leal (,%rdi,4), %eax # sched: [1:0.50]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_4:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; JAG-NOOPT-NEXT: leal (,%rdi,4), %eax # sched: [1:0.50]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_4:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-SLM-NEXT: leal (,%rdi,4), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_4:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; SLM-NOOPT-NEXT: leal (,%rdi,4), %eax # sched: [1:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 4
> ret i32 %mul
> }
> @@ -69,11 +212,46 @@ define i32 @test_mul_by_5(i32 %x) {
> ; X86-NEXT: imull $5, {{[0-9]+}}(%esp), %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_5:
> -; X64: # BB#0:
> -; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> -; X64-NEXT: leal (%rdi,%rdi,4), %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_5:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_5:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_5:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $5, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_5:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; HSW-NOOPT-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_5:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; JAG-NOOPT-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_5:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-SLM-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_5:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; SLM-NOOPT-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 5
> ret i32 %mul
> }
> @@ -86,12 +264,46 @@ define i32 @test_mul_by_6(i32 %x) {
> ; X86-NEXT: leal (%eax,%eax,2), %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_6:
> -; X64: # BB#0:
> -; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> -; X64-NEXT: addl %edi, %edi
> -; X64-NEXT: leal (%rdi,%rdi,2), %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_6:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: addl %edi, %edi # sched: [1:0.25]
> +; X64-HSW-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_6:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: addl %edi, %edi # sched: [1:0.50]
> +; X64-JAG-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_6:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $6, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_6:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $6, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_6:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $6, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_6:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-SLM-NEXT: addl %edi, %edi # sched: [1:0.50]
> +; X64-SLM-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_6:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $6, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 6
> ret i32 %mul
> }
> @@ -104,12 +316,46 @@ define i32 @test_mul_by_7(i32 %x) {
> ; X86-NEXT: subl %ecx, %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_7:
> -; X64: # BB#0:
> -; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> -; X64-NEXT: leal (,%rdi,8), %eax
> -; X64-NEXT: subl %edi, %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_7:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (,%rdi,8), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: subl %edi, %eax # sched: [1:0.25]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_7:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (,%rdi,8), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: subl %edi, %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_7:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $7, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_7:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $7, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_7:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $7, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_7:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-SLM-NEXT: leal (,%rdi,8), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: subl %edi, %eax # sched: [1:0.50]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_7:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $7, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 7
> ret i32 %mul
> }
> @@ -121,11 +367,47 @@ define i32 @test_mul_by_8(i32 %x) {
> ; X86-NEXT: shll $3, %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_8:
> -; X64: # BB#0:
> -; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> -; X64-NEXT: leal (,%rdi,8), %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_8:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (,%rdi,8), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_8:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (,%rdi,8), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_8:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: movl {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: shll $3, %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_8:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; HSW-NOOPT-NEXT: leal (,%rdi,8), %eax # sched: [1:0.50]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_8:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; JAG-NOOPT-NEXT: leal (,%rdi,8), %eax # sched: [1:0.50]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_8:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-SLM-NEXT: leal (,%rdi,8), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_8:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; SLM-NOOPT-NEXT: leal (,%rdi,8), %eax # sched: [1:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 8
> ret i32 %mul
> }
> @@ -136,11 +418,46 @@ define i32 @test_mul_by_9(i32 %x) {
> ; X86-NEXT: imull $9, {{[0-9]+}}(%esp), %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_9:
> -; X64: # BB#0:
> -; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> -; X64-NEXT: leal (%rdi,%rdi,8), %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_9:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (%rdi,%rdi,8), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_9:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (%rdi,%rdi,8), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_9:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $9, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_9:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; HSW-NOOPT-NEXT: leal (%rdi,%rdi,8), %eax # sched: [1:0.50]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_9:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; JAG-NOOPT-NEXT: leal (%rdi,%rdi,8), %eax # sched: [1:0.50]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_9:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-SLM-NEXT: leal (%rdi,%rdi,8), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_9:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; SLM-NOOPT-NEXT: leal (%rdi,%rdi,8), %eax # sched: [1:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 9
> ret i32 %mul
> }
> @@ -153,12 +470,46 @@ define i32 @test_mul_by_10(i32 %x) {
> ; X86-NEXT: leal (%eax,%eax,4), %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_10:
> -; X64: # BB#0:
> -; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> -; X64-NEXT: addl %edi, %edi
> -; X64-NEXT: leal (%rdi,%rdi,4), %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_10:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: addl %edi, %edi # sched: [1:0.25]
> +; X64-HSW-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_10:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: addl %edi, %edi # sched: [1:0.50]
> +; X64-JAG-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_10:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $10, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_10:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $10, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_10:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $10, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_10:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-SLM-NEXT: addl %edi, %edi # sched: [1:0.50]
> +; X64-SLM-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_10:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $10, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 10
> ret i32 %mul
> }
> @@ -166,13 +517,49 @@ define i32 @test_mul_by_10(i32 %x) {
> define i32 @test_mul_by_11(i32 %x) {
> ; X86-LABEL: test_mul_by_11:
> ; X86: # BB#0:
> -; X86-NEXT: imull $11, {{[0-9]+}}(%esp), %eax
> +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
> +; X86-NEXT: leal (%eax,%eax,4), %ecx
> +; X86-NEXT: leal (%eax,%ecx,2), %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_11:
> -; X64: # BB#0:
> -; X64-NEXT: imull $11, %edi, %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_11:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: leal (%rdi,%rax,2), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_11:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: leal (%rdi,%rax,2), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_11:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $11, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_11:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $11, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_11:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $11, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_11:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: imull $11, %edi, %eax # sched: [3:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_11:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $11, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 11
> ret i32 %mul
> }
> @@ -185,12 +572,46 @@ define i32 @test_mul_by_12(i32 %x) {
> ; X86-NEXT: leal (%eax,%eax,2), %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_12:
> -; X64: # BB#0:
> -; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> -; X64-NEXT: shll $2, %edi
> -; X64-NEXT: leal (%rdi,%rdi,2), %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_12:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: shll $2, %edi # sched: [1:0.50]
> +; X64-HSW-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_12:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: shll $2, %edi # sched: [1:0.50]
> +; X64-JAG-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_12:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $12, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_12:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $12, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_12:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $12, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_12:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-SLM-NEXT: shll $2, %edi # sched: [1:1.00]
> +; X64-SLM-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_12:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $12, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 12
> ret i32 %mul
> }
> @@ -198,13 +619,49 @@ define i32 @test_mul_by_12(i32 %x) {
> define i32 @test_mul_by_13(i32 %x) {
> ; X86-LABEL: test_mul_by_13:
> ; X86: # BB#0:
> -; X86-NEXT: imull $13, {{[0-9]+}}(%esp), %eax
> +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
> +; X86-NEXT: leal (%eax,%eax,2), %ecx
> +; X86-NEXT: leal (%eax,%ecx,4), %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_13:
> -; X64: # BB#0:
> -; X64-NEXT: imull $13, %edi, %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_13:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: leal (%rdi,%rax,4), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_13:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: leal (%rdi,%rax,4), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_13:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $13, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_13:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $13, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_13:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $13, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_13:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: imull $13, %edi, %eax # sched: [3:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_13:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $13, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 13
> ret i32 %mul
> }
> @@ -212,13 +669,52 @@ define i32 @test_mul_by_13(i32 %x) {
> define i32 @test_mul_by_14(i32 %x) {
> ; X86-LABEL: test_mul_by_14:
> ; X86: # BB#0:
> -; X86-NEXT: imull $14, {{[0-9]+}}(%esp), %eax
> +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
> +; X86-NEXT: leal (%ecx,%ecx,2), %eax
> +; X86-NEXT: leal (%ecx,%eax,4), %eax
> +; X86-NEXT: addl %ecx, %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_14:
> -; X64: # BB#0:
> -; X64-NEXT: imull $14, %edi, %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_14:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: leal (%rdi,%rax,4), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: addl %edi, %eax # sched: [1:0.25]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_14:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: leal (%rdi,%rax,4), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: addl %edi, %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_14:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $14, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_14:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $14, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_14:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $14, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_14:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: imull $14, %edi, %eax # sched: [3:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_14:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $14, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 14
> ret i32 %mul
> }
> @@ -231,12 +727,46 @@ define i32 @test_mul_by_15(i32 %x) {
> ; X86-NEXT: leal (%eax,%eax,2), %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_15:
> -; X64: # BB#0:
> -; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> -; X64-NEXT: leal (%rdi,%rdi,4), %eax
> -; X64-NEXT: leal (%rax,%rax,2), %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_15:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: leal (%rax,%rax,2), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_15:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: leal (%rax,%rax,2), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_15:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $15, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_15:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $15, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_15:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $15, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_15:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-SLM-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: leal (%rax,%rax,2), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_15:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $15, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 15
> ret i32 %mul
> }
> @@ -248,11 +778,47 @@ define i32 @test_mul_by_16(i32 %x) {
> ; X86-NEXT: shll $4, %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_16:
> -; X64: # BB#0:
> -; X64-NEXT: shll $4, %edi
> -; X64-NEXT: movl %edi, %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_16:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: shll $4, %edi # sched: [1:0.50]
> +; X64-HSW-NEXT: movl %edi, %eax # sched: [1:0.25]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_16:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: shll $4, %edi # sched: [1:0.50]
> +; X64-JAG-NEXT: movl %edi, %eax # sched: [1:0.17]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_16:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: movl {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: shll $4, %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_16:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: shll $4, %edi # sched: [1:0.50]
> +; HSW-NOOPT-NEXT: movl %edi, %eax # sched: [1:0.25]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_16:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: shll $4, %edi # sched: [1:0.50]
> +; JAG-NOOPT-NEXT: movl %edi, %eax # sched: [1:0.17]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_16:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: shll $4, %edi # sched: [1:1.00]
> +; X64-SLM-NEXT: movl %edi, %eax # sched: [1:0.50]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_16:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: shll $4, %edi # sched: [1:1.00]
> +; SLM-NOOPT-NEXT: movl %edi, %eax # sched: [1:0.50]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 16
> ret i32 %mul
> }
> @@ -266,13 +832,49 @@ define i32 @test_mul_by_17(i32 %x) {
> ; X86-NEXT: addl %ecx, %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_17:
> -; X64: # BB#0:
> -; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> -; X64-NEXT: movl %edi, %eax
> -; X64-NEXT: shll $4, %eax
> -; X64-NEXT: leal (%rax,%rdi), %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_17:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: movl %edi, %eax # sched: [1:0.25]
> +; X64-HSW-NEXT: shll $4, %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: leal (%rax,%rdi), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_17:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: movl %edi, %eax # sched: [1:0.17]
> +; X64-JAG-NEXT: shll $4, %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: leal (%rax,%rdi), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_17:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $17, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_17:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $17, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_17:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $17, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_17:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-SLM-NEXT: movl %edi, %eax # sched: [1:0.50]
> +; X64-SLM-NEXT: shll $4, %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: leal (%rax,%rdi), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_17:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $17, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 17
> ret i32 %mul
> }
> @@ -285,12 +887,46 @@ define i32 @test_mul_by_18(i32 %x) {
> ; X86-NEXT: leal (%eax,%eax,8), %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_18:
> -; X64: # BB#0:
> -; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> -; X64-NEXT: addl %edi, %edi
> -; X64-NEXT: leal (%rdi,%rdi,8), %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_18:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: addl %edi, %edi # sched: [1:0.25]
> +; X64-HSW-NEXT: leal (%rdi,%rdi,8), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_18:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: addl %edi, %edi # sched: [1:0.50]
> +; X64-JAG-NEXT: leal (%rdi,%rdi,8), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_18:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $18, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_18:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $18, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_18:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $18, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_18:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-SLM-NEXT: addl %edi, %edi # sched: [1:0.50]
> +; X64-SLM-NEXT: leal (%rdi,%rdi,8), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_18:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $18, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 18
> ret i32 %mul
> }
> @@ -298,13 +934,52 @@ define i32 @test_mul_by_18(i32 %x) {
> define i32 @test_mul_by_19(i32 %x) {
> ; X86-LABEL: test_mul_by_19:
> ; X86: # BB#0:
> -; X86-NEXT: imull $19, {{[0-9]+}}(%esp), %eax
> +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
> +; X86-NEXT: leal (%ecx,%ecx,4), %eax
> +; X86-NEXT: shll $2, %eax
> +; X86-NEXT: subl %ecx, %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_19:
> -; X64: # BB#0:
> -; X64-NEXT: imull $19, %edi, %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_19:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: shll $2, %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: subl %edi, %eax # sched: [1:0.25]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_19:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: shll $2, %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: subl %edi, %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_19:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $19, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_19:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $19, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_19:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $19, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_19:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: imull $19, %edi, %eax # sched: [3:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_19:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $19, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 19
> ret i32 %mul
> }
> @@ -317,12 +992,46 @@ define i32 @test_mul_by_20(i32 %x) {
> ; X86-NEXT: leal (%eax,%eax,4), %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_20:
> -; X64: # BB#0:
> -; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> -; X64-NEXT: shll $2, %edi
> -; X64-NEXT: leal (%rdi,%rdi,4), %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_20:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: shll $2, %edi # sched: [1:0.50]
> +; X64-HSW-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_20:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: shll $2, %edi # sched: [1:0.50]
> +; X64-JAG-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_20:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $20, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_20:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $20, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_20:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $20, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_20:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-SLM-NEXT: shll $2, %edi # sched: [1:1.00]
> +; X64-SLM-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_20:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $20, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 20
> ret i32 %mul
> }
> @@ -330,13 +1039,49 @@ define i32 @test_mul_by_20(i32 %x) {
> define i32 @test_mul_by_21(i32 %x) {
> ; X86-LABEL: test_mul_by_21:
> ; X86: # BB#0:
> -; X86-NEXT: imull $21, {{[0-9]+}}(%esp), %eax
> +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
> +; X86-NEXT: leal (%eax,%eax,4), %ecx
> +; X86-NEXT: leal (%eax,%ecx,4), %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_21:
> -; X64: # BB#0:
> -; X64-NEXT: imull $21, %edi, %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_21:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: leal (%rdi,%rax,4), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_21:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: leal (%rdi,%rax,4), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_21:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $21, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_21:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $21, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_21:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $21, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_21:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: imull $21, %edi, %eax # sched: [3:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_21:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $21, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 21
> ret i32 %mul
> }
> @@ -344,13 +1089,52 @@ define i32 @test_mul_by_21(i32 %x) {
> define i32 @test_mul_by_22(i32 %x) {
> ; X86-LABEL: test_mul_by_22:
> ; X86: # BB#0:
> -; X86-NEXT: imull $22, {{[0-9]+}}(%esp), %eax
> +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
> +; X86-NEXT: leal (%ecx,%ecx,4), %eax
> +; X86-NEXT: leal (%ecx,%eax,4), %eax
> +; X86-NEXT: addl %ecx, %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_22:
> -; X64: # BB#0:
> -; X64-NEXT: imull $22, %edi, %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_22:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: leal (%rdi,%rax,4), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: addl %edi, %eax # sched: [1:0.25]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_22:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: leal (%rdi,%rax,4), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: addl %edi, %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_22:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $22, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_22:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $22, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_22:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $22, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_22:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: imull $22, %edi, %eax # sched: [3:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_22:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $22, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 22
> ret i32 %mul
> }
> @@ -358,13 +1142,52 @@ define i32 @test_mul_by_22(i32 %x) {
> define i32 @test_mul_by_23(i32 %x) {
> ; X86-LABEL: test_mul_by_23:
> ; X86: # BB#0:
> -; X86-NEXT: imull $23, {{[0-9]+}}(%esp), %eax
> +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
> +; X86-NEXT: leal (%ecx,%ecx,2), %eax
> +; X86-NEXT: shll $3, %eax
> +; X86-NEXT: subl %ecx, %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_23:
> -; X64: # BB#0:
> -; X64-NEXT: imull $23, %edi, %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_23:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: shll $3, %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: subl %edi, %eax # sched: [1:0.25]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_23:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: shll $3, %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: subl %edi, %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_23:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $23, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_23:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $23, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_23:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $23, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_23:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: imull $23, %edi, %eax # sched: [3:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_23:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $23, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 23
> ret i32 %mul
> }
> @@ -377,12 +1200,46 @@ define i32 @test_mul_by_24(i32 %x) {
> ; X86-NEXT: leal (%eax,%eax,2), %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_24:
> -; X64: # BB#0:
> -; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> -; X64-NEXT: shll $3, %edi
> -; X64-NEXT: leal (%rdi,%rdi,2), %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_24:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: shll $3, %edi # sched: [1:0.50]
> +; X64-HSW-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_24:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: shll $3, %edi # sched: [1:0.50]
> +; X64-JAG-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_24:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $24, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_24:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $24, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_24:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $24, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_24:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-SLM-NEXT: shll $3, %edi # sched: [1:1.00]
> +; X64-SLM-NEXT: leal (%rdi,%rdi,2), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_24:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $24, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 24
> ret i32 %mul
> }
> @@ -395,12 +1252,46 @@ define i32 @test_mul_by_25(i32 %x) {
> ; X86-NEXT: leal (%eax,%eax,4), %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_25:
> -; X64: # BB#0:
> -; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> -; X64-NEXT: leal (%rdi,%rdi,4), %eax
> -; X64-NEXT: leal (%rax,%rax,4), %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_25:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: leal (%rax,%rax,4), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_25:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: leal (%rax,%rax,4), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_25:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $25, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_25:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $25, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_25:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $25, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_25:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-SLM-NEXT: leal (%rdi,%rdi,4), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: leal (%rax,%rax,4), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_25:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $25, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 25
> ret i32 %mul
> }
> @@ -408,13 +1299,52 @@ define i32 @test_mul_by_25(i32 %x) {
> define i32 @test_mul_by_26(i32 %x) {
> ; X86-LABEL: test_mul_by_26:
> ; X86: # BB#0:
> -; X86-NEXT: imull $26, {{[0-9]+}}(%esp), %eax
> +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
> +; X86-NEXT: leal (%ecx,%ecx,8), %eax
> +; X86-NEXT: leal (%eax,%eax,2), %eax
> +; X86-NEXT: subl %ecx, %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_26:
> -; X64: # BB#0:
> -; X64-NEXT: imull $26, %edi, %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_26:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (%rdi,%rdi,8), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: leal (%rax,%rax,2), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: subl %edi, %eax # sched: [1:0.25]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_26:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (%rdi,%rdi,8), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: leal (%rax,%rax,2), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: subl %edi, %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_26:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $26, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_26:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $26, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_26:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $26, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_26:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: imull $26, %edi, %eax # sched: [3:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_26:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $26, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 26
> ret i32 %mul
> }
> @@ -427,12 +1357,46 @@ define i32 @test_mul_by_27(i32 %x) {
> ; X86-NEXT: leal (%eax,%eax,2), %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_27:
> -; X64: # BB#0:
> -; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> -; X64-NEXT: leal (%rdi,%rdi,8), %eax
> -; X64-NEXT: leal (%rax,%rax,2), %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_27:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (%rdi,%rdi,8), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: leal (%rax,%rax,2), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_27:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (%rdi,%rdi,8), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: leal (%rax,%rax,2), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: retq # sched: [4:1.00]
> +;
> +; X86-NOOPT-LABEL: test_mul_by_27:
> +; X86-NOOPT: # BB#0:
> +; X86-NOOPT-NEXT: imull $27, {{[0-9]+}}(%esp), %eax
> +; X86-NOOPT-NEXT: retl
> +;
> +; HSW-NOOPT-LABEL: test_mul_by_27:
> +; HSW-NOOPT: # BB#0:
> +; HSW-NOOPT-NEXT: imull $27, %edi, %eax # sched: [4:1.00]
> +; HSW-NOOPT-NEXT: retq # sched: [1:1.00]
> +;
> +; JAG-NOOPT-LABEL: test_mul_by_27:
> +; JAG-NOOPT: # BB#0:
> +; JAG-NOOPT-NEXT: imull $27, %edi, %eax # sched: [3:1.00]
> +; JAG-NOOPT-NEXT: retq # sched: [4:1.00]
> +;
> +; X64-SLM-LABEL: test_mul_by_27:
> +; X64-SLM: # BB#0:
> +; X64-SLM-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-SLM-NEXT: leal (%rdi,%rdi,8), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: leal (%rax,%rax,2), %eax # sched: [1:1.00]
> +; X64-SLM-NEXT: retq # sched: [4:1.00]
> +;
> +; SLM-NOOPT-LABEL: test_mul_by_27:
> +; SLM-NOOPT: # BB#0:
> +; SLM-NOOPT-NEXT: imull $27, %edi, %eax # sched: [3:1.00]
> +; SLM-NOOPT-NEXT: retq # sched: [4:1.00]
> %mul = mul nsw i32 %x, 27
> ret i32 %mul
> }
> @@ -440,13 +1404,52 @@ define i32 @test_mul_by_27(i32 %x) {
> define i32 @test_mul_by_28(i32 %x) {
> ; X86-LABEL: test_mul_by_28:
> ; X86: # BB#0:
> -; X86-NEXT: imull $28, {{[0-9]+}}(%esp), %eax
> +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
> +; X86-NEXT: leal (%ecx,%ecx,8), %eax
> +; X86-NEXT: leal (%eax,%eax,2), %eax
> +; X86-NEXT: addl %ecx, %eax
> ; X86-NEXT: retl
> ;
> -; X64-LABEL: test_mul_by_28:
> -; X64: # BB#0:
> -; X64-NEXT: imull $28, %edi, %eax
> -; X64-NEXT: retq
> +; X64-HSW-LABEL: test_mul_by_28:
> +; X64-HSW: # BB#0:
> +; X64-HSW-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-HSW-NEXT: leal (%rdi,%rdi,8), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: leal (%rax,%rax,2), %eax # sched: [1:0.50]
> +; X64-HSW-NEXT: addl %edi, %eax # sched: [1:0.25]
> +; X64-HSW-NEXT: retq # sched: [1:1.00]
> +;
> +; X64-JAG-LABEL: test_mul_by_28:
> +; X64-JAG: # BB#0:
> +; X64-JAG-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
> +; X64-JAG-NEXT: leal (%rdi,%rdi,8), %eax # sched: [1:0.50]
> +; X64-JAG-NEXT: leal (%rax,%rax,2), %eax # sched: [1:0.50]
> +; X64-JAG-NE
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170616/65f7343f/attachment-0001.html>
More information about the llvm-commits
mailing list