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.,
__attribute__((noinline))
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 ... }