Question on eliminating calls w/o side effects but return value stored in pointer

I’m not sure if there’s similar discussion before, but I couldn’t find related things after googling (maybe my keywords were wrong).

I noticed that LLVM (and also GCC) failed to eliminate same calls w/o side effects if the return value was stored into a pointer, e.g.,

void bar(int a, int *b) {
    *b = a + 20;

int baz(int v) {
    int a, b;
    bar(v, &a);
    bar(v, &b);
    return a + b;

There were 2 calls to bar which could be unified to one, but llvm failed to do so.

I noticed the function bar has attributes indicating it has no side effects, including writeonly and argmemonly, and the parameter b has attributes writeonly and nocapture. So I’m wondering what’s blocking llvm eliminating the call?

define dso_local void @_Z3bariPi(i32 noundef %0, ptr nocapture noundef writeonly %1) #0
attributes #0 = { argmemonly mustprogress nofree noinline norecurse nosync nounwind willreturn writeonly uwtable ... }

Alive2 believes nothing: Compiler Explorer

Got it!

It seems that the optimization is just not that meaningful so llvm is missing such optimization.