<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 - LICM does not strip parameter attributes when hoisting calls"
   href="https://bugs.llvm.org/show_bug.cgi?id=50744">50744</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>LICM does not strip parameter attributes when hoisting calls
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>tools
          </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>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>opt
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>anna@azul.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>While we strip metadata as we hoist instructions in LICM, we do not strip
attributes that may no longer be valid to the context the call is hoisted to.

Given this IR: 
cat input.ll
```
declare i32 @cc(i32* %p) argmemonly readonly nounwind

declare i32 @spec(i32* %p) readonly argmemonly nounwind speculatable

define void @test_load(i32* noalias %loc, i32* noalias %sink, i32* %q) {
entry:
  br label %loop

loop:
  %iv = phi i32 [0, %entry], [%iv.next, %isnull ]
  %ret = call i32 @cc(i32* %loc)
  %nullchk = icmp eq i32* %q, null
  br i1 %nullchk, label %isnull, label %nonnullbb

nonnullbb:  
  %ret2 = call i32 @spec(i32* nonnull %q) 
  br label %isnull

isnull:  
  store volatile i32 %ret, i32* %sink
  %iv.next = add i32 %iv, 1
  %cmp = icmp slt i32 %iv, 200 
  br i1 %cmp, label %loop, label %exit

exit:
  ret void
}
```


We hoist the @spec call into preheader. However, the `nonnull` attribute on the
parameter is no longer valid at the location it is hoisted to.


Reproducer:
 opt -aa-pipeline=basic-aa
-passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)'
< input.ll -S

output:
```
define void @test_load(i32* noalias %loc, i32* noalias %sink, i32* %q) {
entry:
  %ret = call i32 @load(i32* %loc)
  %nullchk = icmp eq i32* %q, null
  %ret2 = call i32 @spec(i32* nonnull %q)
  br label %loop

loop:                                             ; preds = %isnull, %entry
  %iv = phi i32 [ 0, %entry ], [ %iv.next, %isnull ]
  br i1 %nullchk, label %isnull, label %nonnullbb

nonnullbb:                                        ; preds = %loop
  br label %isnull

isnull:                                           ; preds = %nonnullbb, %loop
  store volatile i32 %ret, i32* %sink, align 4
  %iv.next = add i32 %iv, 1
  %cmp = icmp slt i32 %iv, 200
  br i1 %cmp, label %loop, label %exit

exit:                                             ; preds = %isnull
  ret void
}
```


Note that since `@spec` call is speculatable, we can speculatively run it in
preheader. However, we should strip such attributes which are present only at
callsite. One way to do this is to whitelist attributes that should be stripped
when hoisting such calls.</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>