<div dir="ltr">Hi all,<div><br></div><div>Let's see an example (from Alexandre Isoard) first:</div><div>****************************************************************************************</div><div><font face="monospace" color="#666666">; RUN: opt -ipsccp -deadargelim -licm -O2 -S < %s<br><br></font><div style="color:rgb(0,0,0);background-color:rgb(255,255,254)"><div style=""><font face="monospace"><span style="color:rgb(0,17,136)">@g</span> = <span style="color:rgb(0,0,255)">internal</span> <span style="color:rgb(0,0,255)">global</span> <span style="color:rgb(0,128,128)">i32</span> <span style="color:rgb(9,134,88)">0</span></font></div><font face="monospace"><br></font><div style=""><span style="color:rgb(0,128,0)"><font face="monospace">; Function Attrs: argmemonly</font></span></div><div style=""><font face="monospace"><span style="color:rgb(0,0,255)">define</span> <span style="color:rgb(0,0,255)">internal</span> <span style="color:rgb(0,128,128)">void</span> <span style="color:rgb(0,17,136)">@foo</span>(<span style="color:rgb(0,128,128)">i32*</span> <span style="color:rgb(0,0,255)">nonnull</span> <span style="color:rgb(0,0,255)">dereferenceable</span>(<span style="color:rgb(9,134,88)">4</span>) <span style="color:rgb(0,17,136)">%arg</span>, <span style="color:rgb(0,128,128)">i32</span> <span style="color:rgb(0,17,136)">%val</span>) #<span style="color:rgb(9,134,88)">0</span> {</font></div><div style=""><span style="color:rgb(128,0,0)"><font face="monospace">entry:</font></span></div><div style=""><font face="monospace">  store <span style="color:rgb(0,128,128)">i32</span> <span style="color:rgb(0,17,136)">%val</span>, <span style="color:rgb(0,128,128)">i32*</span> <span style="color:rgb(0,17,136)">%arg</span></font></div><div style=""><font face="monospace">  ret <span style="color:rgb(0,128,128)">void</span></font></div><div style=""><font face="monospace">}</font></div><font face="monospace"><br></font><div style=""><font face="monospace"><span style="color:rgb(0,0,255)">define</span> <span style="color:rgb(0,128,128)">i32</span> <span style="color:rgb(0,17,136)">@bar</span>(<span style="color:rgb(0,128,128)">i32</span> <span style="color:rgb(0,17,136)">%n</span>) {</font></div><div style=""><span style="color:rgb(128,0,0)"><font face="monospace">entry:</font></span></div><div style=""><font face="monospace">  store <span style="color:rgb(0,128,128)">i32</span> <span style="color:rgb(9,134,88)">1</span>, <span style="color:rgb(0,128,128)">i32*</span> <span style="color:rgb(0,17,136)">@g</span></font></div><div style=""><font face="monospace">  br <span style="color:rgb(0,128,128)">label</span> <span style="color:rgb(0,17,136)">%loop</span></font></div><font face="monospace"><br></font><div style=""><font face="monospace"><span style="color:rgb(128,0,0)">loop:</span>                                              <span style="color:rgb(0,128,0)">; preds = %bb1, %bb</span></font></div><div style=""><font face="monospace">  <span style="color:rgb(0,17,136)">%i</span> = phi <span style="color:rgb(0,128,128)">i32</span> [ <span style="color:rgb(0,17,136)">%i.inc</span>, <span style="color:rgb(0,17,136)">%loop</span> ], [ <span style="color:rgb(9,134,88)">0</span>, <span style="color:rgb(0,17,136)">%entry</span> ]</font></div><div style=""><font face="monospace">  <span style="color:rgb(0,17,136)">%g.val</span> = load <span style="color:rgb(0,128,128)">i32</span>, <span style="color:rgb(0,128,128)">i32*</span> <span style="color:rgb(0,17,136)">@g</span></font></div><div style=""><font face="monospace">  <span style="color:rgb(0,17,136)">%g.inc</span> = add nuw <span style="color:rgb(0,128,128)">i32</span> <span style="color:rgb(0,17,136)">%g.val</span>, <span style="color:rgb(9,134,88)">1</span></font></div><div style=""><font face="monospace">  <span style="color:rgb(0,0,255)">tail</span> call <span style="color:rgb(0,128,128)">void</span> <span style="color:rgb(0,17,136)">@foo</span>(<span style="color:rgb(0,128,128)">i32*</span> <span style="color:rgb(0,17,136)">@g</span>, <span style="color:rgb(0,128,128)">i32</span> <span style="color:rgb(0,17,136)">%g.inc</span>)</font></div><div style=""><font face="monospace">  <span style="color:rgb(0,17,136)">%i.inc</span> = add nuw <span style="color:rgb(0,128,128)">i32</span> <span style="color:rgb(0,17,136)">%i</span>, <span style="color:rgb(9,134,88)">1</span></font></div><div style=""><font face="monospace">  <span style="color:rgb(0,17,136)">%cond</span> = icmp eq <span style="color:rgb(0,128,128)">i32</span> <span style="color:rgb(0,17,136)">%i.inc</span>, <span style="color:rgb(0,17,136)">%n</span></font></div><div style=""><font face="monospace">  br <span style="color:rgb(0,128,128)">i1</span> <span style="color:rgb(0,17,136)">%cond</span>, <span style="color:rgb(0,128,128)">label</span> <span style="color:rgb(0,17,136)">%exit</span>, <span style="color:rgb(0,128,128)">label</span> <span style="color:rgb(0,17,136)">%loop</span></font></div><font face="monospace"><br></font><div style=""><font face="monospace"><span style="color:rgb(128,0,0)">exit:</span>                                              <span style="color:rgb(0,128,0)">; preds = %bb1</span></font></div><div style=""><font face="monospace">  ret <span style="color:rgb(0,128,128)">i32</span> <span style="color:rgb(0,17,136)">%g.val</span></font></div><div style=""><font face="monospace">}</font></div><font face="monospace"><br></font><div style=""><font face="monospace"><span style="color:rgb(0,0,255)">declare</span> <span style="color:rgb(0,128,128)">void</span> <span style="color:rgb(0,17,136)">@llvm.assume</span>(<span style="color:rgb(0,128,128)">i1</span>)</font></div><font face="monospace"><br></font><div style=""><font face="monospace">attributes #<span style="color:rgb(9,134,88)">0</span> = { <span style="color:rgb(0,0,255)">argmemonly</span> }</font></div></div></div><div>****************************************************************************************  <br></div><div>With opt cmd '-ipsccp -deadargelim -licm -O2', function @bar will return constant value 1, instead of correct value %n. This is crazy, right?</div><div>Let's see what happens here.</div><div>Due to pass 'ipsccp' replaced the argument of function '@foo' with global variable '@g', but keeps attr 'argmemonly' there, so pass 'licm' will hoist the load of '@g' before the loop (as the value of @g isn't changed, but it is changed), and will cause function return wrong constant value '1', instead of '%n' (the correct value) , like following:<br></div><div>****************************************************************************************    <br></div><div><div style="color:rgb(0,0,0);background-color:rgb(255,255,254)"><div style=""><span style="color:rgb(0,128,0)"><font face="monospace">; Function Attrs: nofree norecurse nounwind writeonly</font></span></div><div style=""><font face="monospace"><span style="color:rgb(0,0,255)">define</span> <span style="color:rgb(0,128,128)">i32</span> <span style="color:rgb(0,128,128)">@bar</span>(<span style="color:rgb(0,128,128)">i32</span> <span style="color:rgb(0,128,128)">%n</span>) <span style="color:rgb(0,128,128)">local_unnamed_addr</span> <span style="color:rgb(9,134,88)">#0</span> {</font></div><div style=""><span style="color:rgb(0,128,128)"><font face="monospace">entry:</font></span></div><div style=""><font face="monospace">  <span style="color:rgb(0,0,255)">ret</span> <span style="color:rgb(0,128,128)">i32</span> <span style="color:rgb(9,134,88)">1</span></font></div><div style=""><font face="monospace">}</font></div><font face="monospace"><br></font><div style=""><font face="monospace"><span style="color:rgb(0,128,128)">attributes #0 =</span> { <span style="color:rgb(0,128,128)">nofree</span> <span style="color:rgb(0,128,128)">norecurse</span> <span style="color:rgb(0,128,128)">nounwind</span> <span style="color:rgb(0,128,128)">writeonly</span> }</font></div></div></div><div>****************************************************************************************    <br></div><div><br></div><div>And if remove the 'argmemonly' attribute, function @bar will return the correct value:</div><div><div>****************************************************************************************    <br></div><div><div style="color:rgb(0,0,0);background-color:rgb(255,255,254)"><div style=""><div style=""><span style="color:rgb(0,128,0)"><font face="monospace">; Function Attrs: nofree norecurse nounwind</font></span></div><div style=""><font face="monospace"><span style="color:rgb(0,0,255)">define</span> <span style="color:rgb(0,128,128)">i32</span> <span style="color:rgb(0,128,128)">@bar</span>(<span style="color:rgb(0,128,128)">i32</span> <span style="color:rgb(0,128,128)">%n</span>) <span style="color:rgb(0,128,128)">local_unnamed_addr</span> <span style="color:rgb(9,134,88)">#0</span> {</font></div><div style=""><span style="color:rgb(0,128,128)"><font face="monospace">entry:</font></span></div><div style=""><font face="monospace">  <span style="color:rgb(0,0,255)">ret</span> <span style="color:rgb(0,128,128)">i32</span> <span style="color:rgb(0,128,128)">%n</span></font></div><div style=""><font face="monospace">}</font></div></div></div></div><div>****************************************************************************************    </div></div><div><br></div><div>So if function attribute 'argmemonly' on function @foo is correct, then there's a bug in pass 'ipsccp'. When it replaces the function local value with global variable, then it shoud remember to remove this function attribute.</div><div><br></div><div>Thanks,</div><div>Fangqing</div></div>