<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 does not split alloca into more fine-graied allocas iff index into it is variable"
   href="https://bugs.llvm.org/show_bug.cgi?id=51807">51807</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>SROA does not split alloca into more fine-graied allocas iff index into it is variable
          </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>Let's suppose we have the following:
```
struct Outer {
    int pre[4];
    int array[4];
    int post[4];
};

int src(int value, int idx0, int idx1) {
    Outer storage;
    storage.array[idx0] = value;
    return storage.array[idx1];
}
```
So only the `Outer::array` is only ever used.
You'd think we'd be able to chop up the `storage` allocation,
and only allocate the `array` itself.

Alive doesn't like that because iff idx1 is not in [0, 4), 
we'll now have poison instead of reading from `Outer::post[0]`.
But it seems like alive2 doesn't complain iff we make the index in-bounds:

int tgt(int value, int idx0, int idx1) {
    int array[4];
    array[idx0] = value;
    return array[idx1 & 3];
}



$ ./alive-tv /tmp/test.ll --smt-to=60000

----------------------------------------
define i32 @src(i32 %value, i32 %idx0, i32 %idx1) noread nowrite nofree
willreturn {
%entry:
  %storage = alloca i64 48, align 4, dead
  %0 = bitcast * %storage to *
  start_lifetime * %0
  %idxprom = sext i32 %idx0 to i64
  %arrayidx = gep inbounds * %storage, 48 x i64 0, 1 x i64 16, 4 x i64 %idxprom
  store i32 %value, * %arrayidx, align 4
  %idxprom2 = sext i32 %idx1 to i64
  %arrayidx3 = gep inbounds * %storage, 48 x i64 0, 1 x i64 16, 4 x i64
%idxprom2
  %1 = load i32, * %arrayidx3, align 4
  free * %0 unconstrained
  ret i32 %1
}
=>
define i32 @tgt(i32 %value, i32 %idx0, i32 %idx1) noread nowrite nofree
willreturn {
%entry:
  %array = alloca i64 16, align 16, dead
  %0 = bitcast * %array to *
  start_lifetime * %0
  %idxprom = sext i32 %idx0 to i64
  %arrayidx = gep inbounds * %array, 16 x i64 0, 4 x i64 %idxprom
  store i32 %value, * %arrayidx, align 4
  %and = and i32 %idx1, 3
  %1 = zext i32 %and to i64
  %arrayidx2 = gep inbounds * %array, 16 x i64 0, 4 x i64 %1
  %2 = load i32, * %arrayidx2, align 4
  free * %0 unconstrained
  ret i32 %2
}
ERROR: Timeout


Can we do this, or is this also illegal?</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>