[llvm-dev] Function LICM for readonly, nocapture functions

William Moses via llvm-dev llvm-dev at lists.llvm.org
Wed Apr 26 07:42:36 PDT 2017

Hey all,

I was doing some investigation of LICM and I ran into something that seems
a bit odd to me.

Suppose I was looking at the following code snippet:

#define N 1000

int main() {

  int B[N];

  char A[N];

  for(int i=0; i<N; i++) {

    B[i] = strlen(A);


  return B[0]+B[N-1];


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.

The function strlen is marked readonly and the argument is marked nocapture.

; Function Attrs: nounwind readonly

declare i64 @strlen(i8* nocapture) local_unnamed_addr #2

attributes #2 = { nounwind readonly ... }

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.

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.

__attribute__((const)) int strlen(char* A);

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?

Billy Moses

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170426/d004a5da/attachment.html>

More information about the llvm-dev mailing list