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