<div dir="ltr"><span style="font-size:12.8px">Hey all,</span><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">I was doing some investigation of LICM and I ran into something that seems a bit odd to me.</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Suppose I was looking at the following code snippet:</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><p class="m_7406282338804371347gmail-m_-1951342718563957521gmail-p1"><span class="m_7406282338804371347gmail-m_-1951342718563957521gmail-s1"><font face="monospace, monospace">#define N 1000</font></span></p><p class="m_7406282338804371347gmail-m_-1951342718563957521gmail-p1"><span class="m_7406282338804371347gmail-m_-1951342718563957521gmail-s1"><font face="monospace, monospace">int main() {</font></span></p><p class="m_7406282338804371347gmail-m_-1951342718563957521gmail-p1"><span class="m_7406282338804371347gmail-m_-1951342718563957521gmail-s1"><font face="monospace, monospace">  int B[N];</font></span></p><p class="m_7406282338804371347gmail-m_-1951342718563957521gmail-p1"><span class="m_7406282338804371347gmail-m_-1951342718563957521gmail-s1"><font face="monospace, monospace">  char A[N];</font></span></p><p class="m_7406282338804371347gmail-m_-1951342718563957521gmail-p1"><span class="m_7406282338804371347gmail-m_-1951342718563957521gmail-s1"><font face="monospace, monospace">  for(int i=0; i<N; i++) {</font></span></p><p class="m_7406282338804371347gmail-m_-1951342718563957521gmail-p1"><span class="m_7406282338804371347gmail-m_-1951342718563957521gmail-s1"><font face="monospace, monospace">    B[i] = strlen(A);</font></span></p><p class="m_7406282338804371347gmail-m_-1951342718563957521gmail-p1"><span class="m_7406282338804371347gmail-m_-1951342718563957521gmail-s1"><font face="monospace, monospace">  }</font></span></p><p class="m_7406282338804371347gmail-m_-1951342718563957521gmail-p1"><span class="m_7406282338804371347gmail-m_-1951342718563957521gmail-s1"><font face="monospace, monospace">  return B[0]+B[N-1];</font></span></p><p class="m_7406282338804371347gmail-m_-1951342718563957521gmail-p1"><span class="m_7406282338804371347gmail-m_-1951342718563957521gmail-s1"><font face="monospace, monospace">}</font></span></p></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Among other optimizations that I may want to happen, I'd hope that the call to strlen could be moved outside the loop via LICM. Unfortunately, this is not the case. Looking at the IR I found the following.</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">The function strlen is marked readonly and the argument is marked nocapture.</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><p class="m_7406282338804371347gmail-m_-1951342718563957521gmail-p1"><span class="m_7406282338804371347gmail-m_-1951342718563957521gmail-s1"><font face="monospace, monospace">; Function Attrs: nounwind readonly</font></span></p><p class="m_7406282338804371347gmail-m_-1951342718563957521gmail-p1"><font face="monospace, monospace">declare i64 @strlen(i8* nocapture) local_unnamed_addr #2</font></p><p class="m_7406282338804371347gmail-m_-1951342718563957521gmail-p1"><span class="m_7406282338804371347gmail-m_-1951342718563957521gmail-s1"><font face="monospace, monospace"></font></span></p><p class="m_7406282338804371347gmail-m_-1951342718563957521gmail-p1"><span class="m_7406282338804371347gmail-m_-1951342718563957521gmail-s1"><font face="monospace, monospace">attributes #2 = { nounwind readonly ... }</font></span></p><p class="m_7406282338804371347gmail-m_-1951342718563957521gmail-p1"><span class="m_7406282338804371347gmail-m_-1951342718563957521gmail-s1"><br></span></p></div><div style="font-size:12.8px">Presumably this should be enough to permit LICM to move it out of the loop. Upon a further investigation, the issue appeared to be that canSinkOrHoistInst didn't figure out that the call could be moved.</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Curious as to see what I might be able to do to be able to do to force it to happen, I declared my own version of the strlen as follows (which, though technically incorrect as it read memory, did confirm that LICM isn't being stopped for some other reason). In the IR, strlen was marked as readnone which presumably hit the "does not access memory" fast-exit case in canSinkOrHoistInst.</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><p class="m_7406282338804371347gmail-m_-1951342718563957521gmail-p1"><span class="m_7406282338804371347gmail-m_-1951342718563957521gmail-s1"><font face="monospace, monospace">__attribute__((const)) int strlen(char* A);</font></span></p></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Is there a reason why LICM isn't occurring here -- or is just that there's some more work to be done on alias analysis?</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Cheers,</div><div style="font-size:12.8px">Billy Moses</div><div><br></div></div><div hspace="streak-pt-mark" style="max-height:1px"><img alt="" style="width:0px;max-height:0px;overflow:hidden" src="https://mailfoogae.appspot.com/t?sender=adGFla3dvbmJpbGx5QGdtYWlsLmNvbQ%3D%3D&type=zerocontent&guid=11a51859-7ee2-4079-9496-fe55216b688d"><font color="#ffffff" size="1">ᐧ</font></div>