<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>