<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 --- - PowerPC: and (or x, c1), c2) to rlwimi conversion is buggy"
   href="https://llvm.org/bugs/show_bug.cgi?id=24704">24704</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>PowerPC: and (or x, c1), c2) to rlwimi conversion is buggy
          </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>Linux
          </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>Backend: PowerPC
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>anton@samba.org
          </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>I'm tracking down a compile issue that looks to be this optimisation:

    // (and (or x, c1), c2) where isRunOfOnes(~(c1^c2)) is a bitfield insert

This is the testcase:

#include <stdio.h>

int m = 1, s, g = 1;
int i;

signed char foo(int p1, int p2)
{
        return p1 - p2;
}

int main(void)
{
        for (i = 0; i < 2; i++) {
                s = 94967289;
                m |= 250;
                printf("%d\n", foo(m & s, g));
        }

        return 0;
}

Building at -O1, I see the output consistent across both iterations as
expected:

-8
-8

Building at -O2, I see it change:

-8
-6

The code produced is:

    10000680:   10 7f 7a 80     lwz     r3,32528(r26)
    10000684:   14 7f 98 80     lwz     r4,32532(r24)
    10000688:   00 00 7c 93     stw     r27,0(r28)
    1000068c:   fa 00 65 60     ori     r5,r3,250
    10000690:   3a 00 23 53     rlwimi  r3,r25,0,0,29
    10000694:   50 18 64 7c     subf    r3,r4,r3
    10000698:   10 7f ba 90     stw     r5,32528(r26)
    1000069c:   74 07 63 7c     extsb   r3,r3
    100006a0:   b4 07 64 7c     extsw   r4,r3
    100006a4:   78 f3 c3 7f     mr      r3,r30
    100006a8:   39 fd ff 4b     bl      100003e0 <00000017.plt_call.printf>
    100006ac:   18 00 41 e8     ld      r2,24(r1)
    100006b0:   00 00 7d 80     lwz     r3,0(r29)
    100006b4:   01 00 63 38     addi    r3,r3,1
    100006b8:   00 00 7d 90     stw     r3,0(r29)
    100006bc:   02 00 03 2c     cmpwi   r3,2
    100006c0:   c0 ff 80 41     blt     10000680

If I remove the rlwimi optimisation, the program gets the correct result. The
only real change is the rlwimi is replaced with an andi.</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>