[LLVMdev] readonly and infinite loops
Hal Finkel
hfinkel at anl.gov
Sun Jun 28 06:27:56 PDT 2015
----- Original Message -----
> From: "Nuno Lopes" <nunoplopes at sapo.pt>
> To: "Sanjoy Das" <sanjoy at playingwithpointers.com>, "Jeremy Lakeman" <Jeremy.Lakeman at gmail.com>, nlewycky at google.com
> Cc: "LLVM Developers Mailing List" <llvmdev at cs.uiuc.edu>
> Sent: Sunday, June 28, 2015 6:08:52 AM
> Subject: Re: [LLVMdev] readonly and infinite loops
>
> People have been aware of this issue for a long time (as you can see
> by
> Nick's 2010 patch). I guess it was not pushed further because of
> lack of
> practical interest.
I can't comment about the rationale in 2010, but this came up again when I was originally working on heap-to-stack conversion. Being able to mark functions as halting is essential for doing heap-to-stack conversion. This was put on hold, however, essentially awaiting the new pass manager. The issue is that you'd like to be able to use SCEV in a module/CGSCC-level pass to infer the attribute on functions with loops, and this cannot be done directly until we have the new pass manager.
On the other hand, maybe we don't need to wait for that now. We now also have a scheme for tagging loops with metadata, and we could use that to add metadata to loops known to have a finite trip count, and then use that metadata in a pass that infers the attribute (FunctionAttrs presumably).
-Hal
> Maybe Nick remembers more about the issue and why the patch was
> dropped.
>
> Sanjoy: do you have a practical concern about this issue? I mean, of
> course
> this can be "fixed", but it will require some work, and even a
> termination
> checker for -functionattrs for the non-C/C++ frontends.
>
> Nuno
>
> -----Original Message-----
> From: Sanjoy Das
> Sent: Sunday, June 28, 2015 7:50 AM
> Subject: Re: [LLVMdev] readonly and infinite loops
>
> > You dropped some context...
>
> > A daemon program wouldn't be readonly. An infinite loop can be.
>
> Right.
>
> To prevent miscommunication, here is a quick analysis of a
> problematic
> (IMO) example:
>
> We start with
>
> ```
> define void @infloop(i1 %c) {
> entry:
> br i1 %c, label %l, label %e
>
> l:
> br label %l
>
> e:
> ret void
> }
>
> define void @main_func() {
> entry:
> call void @infloop(i1 1)
> ret void
> }
> ```
>
> In this program `@main_func`, when called, will loop infinitely.
>
> If we run this program through `opt -functionattrs -prune-eh
> -early-cse`, we get
>
> ```
> ; Function Attrs: nounwind readnone
> define void @infloop(i1 %c) #0 {
> entry:
> br i1 %c, label %l, label %e
>
> l: ; preds = %l,
> %entry
> br label %l
>
> e: ; preds = %entry
> ret void
> }
>
> ; Function Attrs: nounwind
> define void @main_func() #1 {
> entry:
> ret void
> }
>
> attributes #0 = { nounwind readnone }
> attributes #1 = { nounwind }
> ```
>
> LLVM has optimized `@main_func` to return immediately.
> `-functionattrs` and `-prune-eh` infer `nounwind readnone` for
> `@infloop` and `-early-cse` delets such calls that are dead.
>
> There are three ways to justify what happened:
>
> 1. The optimization was correct. Infinite loops [1] in LLVM IR are
> UB and since the original program had UB, it can be optimized to
> anything. This is problematic since if this were true, we would
> have trouble writing frontends for programming languages that
> actually have a well defined `while(1);`.
>
> 2. The bug is in `-early-cse`: a `readnone nounwind` function can
> loop infinitely, so it is not correct to remove a dead call to
> such a function.
>
> 3. The bug is in `-functionattrs`: a function cannot be marked as
> `readonly` if it may loop infinitely.
>
>
> Needless to say, both (2) and (3) are "easy to fix"; the question is
> really about the deeper semantic issue about how LLVM treats
> `while(1);`.
>
> There are interesting related questions on the semantics of the
> equivalent C/C++ programs, but I personally am interested
> only in "pure" LLVM IR semantics.
>
> -- Sanjoy
>
> [1]: We could make the distinction between infinite loops that are
> empty vs. infinite loops that are non-empty but that's tricky -- if
> only empty infinite loops were UB then e.g. LICM gets harder, since
> sinking the store out of loops like `while(1) *addr = 42;` now
> introduces UB.
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
--
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory
More information about the llvm-dev
mailing list