<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </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 - Rematerialized LEApcrel can address a different literal pool from the original"
   href="https://bugs.llvm.org/show_bug.cgi?id=33074">33074</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Rematerialized LEApcrel can address a different literal pool from the original
          </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: ARM
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>john.brawn.123@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>When we have an LEApcrel instruction that gets rematerialized, if the
rematerialization point is far enough away from the original then the literal
pool for the first LEApcrel will be emitted before we get to the second
LEApcrel causing the second LEApcrel to be redirected to a new literal pool
which will be emitted later. This means the two LEApcrel instructions give
different values, which can lead to incorrect program behaviour in some cases.

An example:

file1.c:
  #include <stdio.h>
  static const char *staticstr = 0;
  void otherfn1(const char *p, const char *q)
  {
    if (p != staticstr) printf("p != staticstr\n");
    if (q != staticstr+8) printf("q != staticstr+8\n");
  }
  void otherfn2(const char *p)
  {
    staticstr = p;
  }
  void filler(void)
  {

  }

file2.c:
  void otherfn1(const char *p, const char *q);
  void otherfn2(const char *p);
  void filler(void);
  void fn(int *p)
  {
    const char *str = "expected";
    otherfn2(str);

    // Use up a load of registers, causing str to spill
    int arr[8];
    arr[0] = p[0];
    arr[1] = p[10];
    arr[2] = p[20];
    arr[3] = p[30];
    arr[4] = p[40];
    arr[5] = p[50];
    arr[6] = p[60];
    arr[7] = p[70];
    filler();
    p[0] = arr[0];
    p[10] = arr[1];
    p[20] = arr[2];
    p[30] = arr[3];
    p[40] = arr[4];
    p[50] = arr[5];
    p[60] = arr[6];
    p[70] = arr[7];

    // Add a load of filler to make the literal pool out of range
  #define FILLER8 filler(); filler(); filler(); filler(); filler(); filler();
filler(); filler();
  #define FILLER64 FILLER8; FILLER8; FILLER8; FILLER8; FILLER8; FILLER8;
FILLER8; FILLER8;
  #define FILLER512 FILLER64; FILLER64; FILLER64; FILLER64; FILLER64; FILLER64;
FILLER64; FILLER64;
    FILLER512;
    FILLER512;

    otherfn1(str, str+8);
  }
  int main()
  {
    int arr[80];
    fn(arr);
    return 0;
  }

Compiled with -mcpu=cortex-a15 -mthumb -O2 we get the output
  p != staticstr
  q != staticstr+8
because for the call to otherfn1 the LEApcrel of "expected" has been
rematerialized, causing the address to be different to the call to otherfn2.</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>