Hi László,
> (Sorry I clicked reply instead of reply to all)
> I'm fighting with my email client, I hope the quoted text contains
> what I want it to contain.
>
> From: László Radnai <radlaci97@gmail.com>
> Date: Fri, 14 Aug 2020 00:11:35 +0200
> Subject: Re: [llvm-dev] Deterministic function return attribute
> To: Johannes Doerfert <johannesdoerfert@gmail.com>
>
> Johannes,
>
> Thanks for clarifying. Your answer was really useful for me!
Glad to help, let's try to figure this one out too 
> I think I've mixed these up (and that explains why I haven't been able
> to find some things on the docs I've remembered...)
Yeah, the docs,.. feel free to propose patches to improve them and put
me as a reviewer 
> Though one question interests me: what attributes can be given to a
> lazy-init singleton or memoized function (which do access memory, but
> does not change output and has no visible side-effects)?
Short answer: None (right now).
Long answer:
There are optimizations that exploit such behavior (or at least similar
behavior) already. IPSCCP and there is an Attributor patch that I lost
track of a while ago. However, that does not mean we couldn't create an
attribute for this. I'm confident there is a reasonable way to define
it, the question is how we would use it. I guess we can teach
inst combine and such passes about it, but then the question is: is it
worth it? There are two cases two consider, and so far I'm unsure if
either justifies this:
1) The function is a definition, so we analyze it, deduce the
attribute, and passes simplify calls to it. So far, so good.
Though, in this scenario it is likely that we inline the function.
The attribute would be gone, but we can still optimize subsequent
"bodies" as we basically see the assignment and the subsequent load
+ compare.
2) The function is a declaration, so no deduction is possible and we
require the attribute to be provided in the input. Usefulness is
given in this case but it is unclear to me if we can expect people
to annotate their code. That said, I'm still hoping this will soon
become a viable alternative to LTO:
https://www.youtube.com/watch?v=elmio6AoyK0&list=PL_R5A0lGi1AAxLTNN21BA0w8CA_xDR0F8&index=14&t=6s
> Examples:
>
> ```
> static Type* data;
>
> Type* getXInstance(){
> if (data==nullptr)
> data = new Type();
> return data;
> }
> ```
>
> or with `static Type* data` inside the function (I don't know whether
> LLVM makes a distinction, haven't had the time to check.)
>
> For the memoized function, an example:
>
> static int memo[100];
>
> int fib(int n){
> llvm.assume(0 <= n && n<=100);
> if (memo[n] != 0) {
> return memo[n];
> }
> if (n == 0) {
> return memo[n] = 1;
> }
> return memo[n] = fib(n-1) + fib(n-2);
> }
>
> My goal would be the same: instruction combining. There are memory
> accesses, but considering(assuming) only this function accessey the
> memory and the output is deterministic (for both cases).
>
> Whether the optimization kicks in (as I will check later), the
> question is either (i) what attributes can communicate this property,
> or (ii) how can I achieve such optimizations? Is there some previous
> work on this? Is this available in gcc?
I don't know much about gcc, sorry 
> I'm not even sure what would be needed for this property to hold, but
> memory access is too strong property.
>
> If it only accesses function-internal (does not alias with anything
> from any other function) memory...? Well, it could store state, not
> cache results... So it does not guarantee deterministic outputs...
First thing is to define what uses cases should be addressed. The above
are two but we need to be precise about the surrounding code. Let's
assume no other uses of the memory exist, then we derive nice properties
for the functions. Though, it might be worth to consider defining
properties for such kind of memory instead 
I have ideas but I'll think about this first and let you know. Feel free
to brainstorm ideas (on the list or just via email to me if you prefer).
> My motive (maybe clarifying this helps a bit): I'm interested in the
> internal workings of a compiler and how smart can a compiler can be,
> for fun. Secondarily, tocommunicate with the optimizer when writing in
> C.
I would also like to improve the communication/interface, believe me...
In addition to talk above, I'd also recommend to look at
http://lists.llvm.org/pipermail/llvm-dev/2019-December/137632.html
and the `assume` directive we added to OpenMP 5.1:
https://www.openmp.org/wp-content/uploads/openmp-TR8.pdf
~ Johannes
> Thanks, László
>
>>
>> Hi László,
>>
>> > 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