<html>
    <head>
      <base href="http://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 --- - Good codegen for bitwise rotate requires code that is technically undefined behavior"
   href="http://llvm.org/bugs/show_bug.cgi?id=20750">20750</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Good codegen for bitwise rotate requires code that is technically undefined behavior
          </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>Common Code Generator Code
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>oneill+llvmbugs@cs.hmc.edu
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=12935" name="attach_12935" title="Five implementations of rotate32.">attachment 12935</a> <a href="attachment.cgi?id=12935&action=edit" title="Five implementations of rotate32.">[details]</a></span>
Five implementations of rotate32.

LLVM lacks an intrinsic for performing bitwise rotation, relying instead on
spotting the classic C idioms for specifying rotation using two shifts. 
Unfortunately, when the rotation is defined by variable, its ability to spot
rotation code is poor.

Code that supports a variable rotation also needs to handle rotation-by-zero,
which the underlying instruction has no problem with, but when translated into
the classic C idiom, results in an undefined shift (because shifting a 32-bit
integer by 32 bits isn't allowed).

In the enclosed code, only rotate32_undefined2 compiles to a simple rotate
instruction.   rotate32_zerocheck also compiles to a rotate, but it contains a
redundant test for zero -- a test that is necessary in the C code but not
necessary for the rotate.

Swapping a zero test for an and operation causes codegen to miss the idiom.

(Compiled with -O3 -fomit-frame-pointer to reduce clutter.)

_rotate32_undefined1:                   ## @rotate32_undefined1
    .cfi_startproc
## BB#0:                                ## %entry
    movb    %sil, %al
    andb    $31, %al
    movzbl    %al, %eax
    movl    %edi, %edx
    movb    %sil, %cl
    shll    %cl, %edx
    movl    $32, %ecx
    subl    %eax, %ecx
                                        ## kill: CL<def> CL<kill> ECX<kill>
    shrl    %cl, %edi
    orl    %edx, %edi
    movl    %edi, %eax
    retq
    .cfi_endproc

    .globl    _rotate32_undefined2
    .align    4, 0x90
_rotate32_undefined2:                   ## @rotate32_undefined2
    .cfi_startproc
## BB#0:                                ## %entry
    movb    %sil, %cl
    roll    %cl, %edi
    movl    %edi, %eax
    retq
    .cfi_endproc

    .globl    _rotate32_zerocheck
    .align    4, 0x90
_rotate32_zerocheck:                    ## @rotate32_zerocheck
    .cfi_startproc
## BB#0:                                ## %entry
    testb    $31, %sil
    je    LBB2_2
## BB#1:                                ## %cond.true
    andl    $31, %esi
    movb    %sil, %cl
    roll    %cl, %edi
LBB2_2:                                 ## %cond.end
    movl    %edi, %eax
    retq
    .cfi_endproc

    .globl    _rotate32_doubleand1
    .align    4, 0x90
_rotate32_doubleand1:                   ## @rotate32_doubleand1
    .cfi_startproc
## BB#0:                                ## %entry
    testb    $31, %sil
    je    LBB3_2
## BB#1:                                ## %cond.true
    andl    $31, %esi
    movl    %edi, %eax
    movb    %sil, %cl
    shll    %cl, %eax
    movl    $32, %ecx
    subl    %esi, %ecx
                                        ## kill: CL<def> CL<kill> ECX<kill>
    shrl    %cl, %edi
    andl    $31, %edi
    orl    %eax, %edi
LBB3_2:                                 ## %cond.end
    movl    %edi, %eax
    retq
    .cfi_endproc

    .globl    _rotate32_doubleand2
    .align    4, 0x90
_rotate32_doubleand2:                   ## @rotate32_doubleand2
    .cfi_startproc
## BB#0:                                ## %entry
    testb    %sil, %sil
    je    LBB4_2
## BB#1:                                ## %cond.true
    movzbl    %sil, %ecx
    andl    $31, %ecx
    movl    %edi, %edx
    shll    %cl, %edx
    movl    $32, %eax
    subl    %ecx, %eax
    movb    %al, %cl
    shrl    %cl, %edi
    andl    $31, %edi
    orl    %edx, %edi
LBB4_2:                                 ## %cond.end
    movl    %edi, %eax
    retq
    .cfi_endproc</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>