[HN Gopher] LLVM internals, part 4: attributes and attribute groups
       ___________________________________________________________________
        
       LLVM internals, part 4: attributes and attribute groups
        
       Author : lukastyrychtr
       Score  : 91 points
       Date   : 2021-12-04 15:25 UTC (7 hours ago)
        
 (HTM) web link (blog.yossarian.net)
 (TXT) w3m dump (blog.yossarian.net)
        
       | woodruffw wrote:
       | Author here; happy to answer any questions.
        
         | lelouch11 wrote:
         | Hi, I had a general question regarding intrinsics which you
         | might be able to answer. `llvm.stacksave` and
         | `llvm.stackrestore` are used for implementing VLAs in C (to my
         | knowledge). Is it required to emit those for variable size
         | allocas, or could you skip them? If skipping is possible, how
         | is the case handled when the basic block does not post-dominate
         | an exit block?
        
           | woodruffw wrote:
           | AFAIK, LLVM doesn't actually require those intrinsics for
           | VLAs -- the `alloca` instruction can take a non-immediate for
           | the stack object size. I can't remember off the top of my
           | head whether I've seen LLVM consistently include the
           | intrinsics as well.
           | 
           | As for the dominator case: it's possible that it _does_ need
           | them then. But for a really trivial VLA (like at the level of
           | the function's frame) it shouldn't.
        
             | jcranmer wrote:
             | The only case I recall seeing
             | @llvm.{stacksave,stackrestore} use was when LLVM inlined a
             | function with a non-entry-block-alloca into another
             | function, where the intrinsics got added immediately
             | before/after what used to be the function call.
        
         | CalChris wrote:
         | _clang -S -emit-llvm xyz.cpp_ generates an _optnone_ attribute.
         | attributes #0 = { noinline norecurse nounwind optnone ssp
         | uwtable "darwin-stkchk-strong-link" "disable-tail-
         | calls"="false" "frame-pointer"="all" "less-precise-
         | fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-
         | math"="false" "no-jump-tables"="false" "no-nans-fp-
         | math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-
         | math"="true" "probe-stack"="___chkstk_darwin" "stack-protector-
         | buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16
         | ,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87"
         | "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-
         | float"="false" }
         | 
         | This means you can't then run it through _opt_ and watch it
         | pass by pass get optimized with _opt --print-after-all -O3
         | xyz.ll -S -o abc.ll_. Clang doesn 't take the --print-after-all
         | flag.
         | 
         | What is the purpose of the _optnone_ attribute? Why is Clang
         | preventing later optimization?
        
           | woodruffw wrote:
           | I'm not sure about the _why_ , but it's been that way for
           | quite a while (since at least LLVM 5). You can explicitly
           | override the optnone by passing `-disable-O0-optnone` to the
           | underlying driver (i.e., you might need to pass `-Xclang`
           | first.)
           | 
           | Edit: if I had to wager a guess, it's because someone
           | generated an IR module at some point with -O0 and then re-ran
           | opt to perform a specific non-destructive analysis, at which
           | point LLVM happily ran all of its default passes. So someone
           | decided that initially building with -O0 is equivalent to
           | saying "my code should never be optimized, even in subsequent
           | invocations of the compiler."
        
           | jcranmer wrote:
           | The purpose is to keep optimization flags around if you're,
           | say, compiling with LTO or PGO--cases where the regular
           | compilation process will keep bitcode files around.
           | 
           | The usual trick I do is clang -S -emit-llvm -O2 -Xclang
           | --disable-llvm-passes.
           | 
           | > Clang doesn't take the --print-after-all flag.
           | 
           | You have to prefix it with -mllvm, e.g., clang -mllvm -print-
           | after-all -O2 foo.cpp.
        
       ___________________________________________________________________
       (page generated 2021-12-04 23:01 UTC)