<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 - SROA introduces inttoptr"
   href="https://bugs.llvm.org/show_bug.cgi?id=47592">47592</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>SROA introduces inttoptr
          </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>enhancement
          </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>lebedev.ri@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>This is reduced from real-world code.

<a href="https://godbolt.org/z/sxj4oz">https://godbolt.org/z/sxj4oz</a>

struct S {
    int* data;
    int x, y, z;
};

S gen(S a) {
    S b;
    b.data = a.data;
    return b;
}

void escape(S);

int* entry(S a) {
    S b = gen(a);
    escape(b);
    return b.data;
}


or  


struct S {
    int* data;
    int x, y, z;
};

S gen(S a) {
    S b;
    b.data = a.data;
    return b;
}

int cond();
void sync0();
void sync1();
void escape0(int*);
void escape1(int*);

int* entry(S a) {
    S b = gen(a);
    if(cond()) {
        sync0();
        escape0(b.data);
    } else {
        sync1();
        escape1(b.data);
    }
    return b.data;
}


The story is as follows:
* Originally, there was no inttoptr's
* Then InstCombine`s `combineLoadToOperationType()` came, and changed `gen()`
to operate on integers
  As per
<a href="http://llvm.1065342.n5.nabble.com/RFC-Missing-canonicalization-in-LLVM-td76650.html#none">http://llvm.1065342.n5.nabble.com/RFC-Missing-canonicalization-in-LLVM-td76650.html#none</a>,
  i suppose it's it whole purpose..
* Then, SROA sees accesses with non-identical types to that alloca slice - with
i64 and i32*,
  and decides to fall-back to largest integer-sized type, so it creates more
load/stores of i64,
  that then need to be inttoptr'd.
* We clearly fail to recover from that - no pass manages to cleanup those
inttoptr's.
  I have previously proposed <a href="https://reviews.llvm.org/D75505">https://reviews.llvm.org/D75505</a>, but indeed,
  it has some compile-time impact:
 
<a href="https://llvm-compile-time-tracker.com/compare.php?from=871d03a6751e0f82e210c80a881ef357c5633a26&to=782be5b99377b62e998e4157ddede0fa296664b5&stat=instructions">https://llvm-compile-time-tracker.com/compare.php?from=871d03a6751e0f82e210c80a881ef357c5633a26&to=782be5b99377b62e998e4157ddede0fa296664b5&stat=instructions</a>

I think we can agree that this situation isn't great.
inttoptr are (nowadays) treated as pretty opaque, so e.g. SCEV will fail to see
that both the %7 and %9 in second example are actually the same pointer..

I'm open to suggestions as to how we can resolve this.
IMHO, `combineLoadToOperationType()` shouldn't exist, but then the RFC didn't
come with an end-to-end test, so it isn't clear what larger problem it is
fixing.</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>