The motivated test case is:
struct S {
long l; char c; short s; int i;
};
void foo(struct S *p) {
p->l = 0; p->c = 0; p->s = 0; p->i = 0;
}
It is very common in constructors, llvm generates:
li 4, 0 li 5, 0 <=== this is not necessary, we could use r4 instead. stb 4, 0(3) sth 4, 2(3) stw 4, 4(3) std 5, 8(3) blr
It is because 8bit and 16bit types are not legal, they are promoted to 32bit, so all 8b/16b/32b stores reference Constant:i32<0>, constants are shared in LLVM IR, so they are naturally CSEd. 64bit store references Constant:i64<0>, it is of different type, so it is represented by a different constant node, and generate another constant construction instruction.
This patch changes all i32 constant in store instruction to i64 with truncation, to increase the chance that the referenced constant can be shared with other i64 constant.
I think this line might be too long.