[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
attributes?
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