[llvm-dev] Deterministic function return attribute

Johannes Doerfert via llvm-dev llvm-dev at lists.llvm.org
Thu Aug 13 09:15:36 PDT 2020

Hi László,

On 8/13/20 6:23 AM, László Radnai via llvm-dev wrote:
 > Hi!
 > I'm interested in what attributes in LLVM mean, specifically how to
 > say that the result is always the same for the given input parameters.
 > The main thing would be to merge two calls with the same parameters
 > when the function is declared but not defined. (just like two stores).
 > I'll call this property mergability.
 > %1 := call @test(%0)
 > %2 := call @test(%0)
 > and the optimization would be something like (%2).replaceUsesWith((%1)).
 > I think it's related to speculatable & readnone in LLVM, (if I
 > understood well, it's the same as GCC's __attribute__((pure)), but I'm
 > not sure whether there are edgecases where the mergability is not
 > equivalent.
 > I've seen somewhere that maybe malloc has these attributes, but it
 > surely cannot be merged. This is because there is memory read/written
 > that cannot be seen by LLVM (which is accepted by readnone). This
 > would be a counter-example.
 > So my question is:
 > Is mergability equivalent to the readnone+speculatable attribute?
 > If not, is there some attribute that should help?
 > And also, does malloc have (or rather, could malloc have) these 

Some thoughts, you let me know if this is helpful:

same input -> same output; this is basically an implication of
`readnone`, or `readonly` without intermediate modifications.
It is already happening as you would expect it to, I think in inst
combine but I didn't check: https://godbolt.org/z/hnY71v

`speculatable` means it is `readnone` and doesn't cause UB. As a
consequence it is allowed to eagerly execute the function. `readnone`
(aka `__attribute__((const))`) is not sufficient because of things like
this: `int pure_div(int a, int b) { return a / b; }`
While there is certainly no memory access or anything else that would
make it not only depend on the arguments, you cannot hoist a call to
`pure_div` out of a conditional like `if (b != 0) r = pure_div(a, b);`.

`readnone` does *not* allow accesses to memory that "cannot be seen by
LLVM". We have `inaccessiblememonly` for that.

Please follow up with questions :)

~ Johannes

 > Thanks, László
 > _______________________________________________
 > LLVM Developers mailing list
 > llvm-dev at lists.llvm.org
 > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

More information about the llvm-dev mailing list