<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - llvm should not emit any compiler-rt calls for division/modulo involving quotients that are powers of two"
   href="https://llvm.org/bugs/show_bug.cgi?id=26049">26049</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>llvm should not emit any compiler-rt calls for division/modulo involving quotients that are powers of two
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Scalar Optimizations
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>mgottesman@apple.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>This is an old bug by majnemer. I am just moving it upstream since I am not
going to have time to look at it.

Consider:

unsigned long long howmany(unsigned long long x, unsigned y) {
    return (x % y == 0) ? (x / y) : ((x / y) + 1);
}
unsigned long long howmany2(unsigned long long x, unsigned r) {
    return howmany(x, (1U << r));
}

llvm generates:
_howmany2:
@ BB#0:                                 @ %entry
    push    {r4, r5, r6, r7, lr}
    add    r7, sp, #12
    push.w    {r8, r10}
    movs    r3, #1
    mov    r5, r0
    lsl.w    r6, r3, r2
    mov    r0, r5
    mov    r2, r6
    movs    r3, #0
    mov    r4, r1
    blx    ___udivdi3
    mov    r8, r0
    mov    r10, r1
    mov    r0, r5
    mov    r1, r4
    mov    r2, r6
    movs    r3, #0
    blx    ___umoddi3
    orrs    r0, r1
    it    ne
    movne    r0, #1
    adds.w    r0, r0, r8
    adc    r1, r10, #0
    pop.w    {r8, r10}
    pop    {r4, r5, r6, r7, pc}

all we need is:
unsigned long long howmany3(unsigned long long x, unsigned r) {
    unsigned rem = (unsigned)(x & ((1U << r) - 1U));
    unsigned long long quot = x >> r;
    return quot + !!rem;
}

which llvm turns into the more reasonable:
    rsb.w    r3, r2, #32
    sub.w    r12, r2, #32
    lsr.w    r9, r0, r2
    cmp.w    r12, #0
    lsl.w    r3, r1, r3
    orr.w    r9, r9, r3
    lsr.w    r3, r1, r12
    mov.w    r12, #1
    it    lt
    movlt    r3, r9
    lsr.w    r9, r1, r2
    lsl.w    r1, r12, r2
    subs    r1, #1
    ands    r0, r1
    it    ne
    movne    r0, #1
    adds    r0, r0, r3
    adc    r1, r9, #0
    bx    lr

----

This was the proposed patch:

----
Index: lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineMulDivRem.cpp    (revision 159020)
+++ lib/Transforms/InstCombine/InstCombineMulDivRem.cpp    (working copy)
@@ -630,9 +630,18 @@
   }

   // Turn A % (C << N), where C is 2^k, into A & ((C << N)-1)  
-  if (match(Op1, m_Shl(m_Power2(), m_Value()))) {
-    Constant *N1 = Constant::getAllOnesValue(I.getType());
-    Value *Add = Builder->CreateAdd(Op1, N1);
+  if (match(Op1, m_Shl(m_Power2(), m_Value())) ||
+      match(Op1, m_ZExt(m_Shl(m_Power2(), m_Value())))) {
+    Value *Shr;
+    ZExtInst *Z = dyn_cast<ZExtInst>(Op1);
+    if (Z)
+      Shr = Z->getOperand(0);
+    else
+      Shr = Op1;
+    Constant *N1 = Constant::getAllOnesValue(Shr->getType());
+    Value *Add = Builder->CreateAdd(Shr, N1);
+    if (Z)
+      Add = Builder->CreateZExt(Add, Z->getDestTy());
     return BinaryOperator::CreateAnd(Op0, Add);
   }
----</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>