This is an archive of the discontinued LLVM Phabricator instance.

[RISCV] Disable callee-saved register when the register is written by llvm.write_register intrinsic
Needs ReviewPublic

Authored by zixuan-wu on Dec 13 2022, 11:19 PM.

Details

Summary

Store of global named registers are always calls to llvm.write_register intrinsic. Normally, it is like in following C code.

register struct global_data *gd asm ("gp");

void arch_setup_gd(struct global_data *gd_ptr)
{
        gd = gd_ptr;

}

This patch is to avoid to save/restore those global named registers which are callee-saved registers.

Diff Detail

Event Timeline

zixuan-wu created this revision.Dec 13 2022, 11:19 PM
zixuan-wu requested review of this revision.Dec 13 2022, 11:19 PM
lenary resigned from this revision.Dec 14 2022, 3:10 AM

AArch64 forbids it unless the register is marked reserved, which makes sense to me. I don't think this change is right.

(If the register is marked reserved with -ffixed-xN then you won't get the save/restore code here)

arsenm added a subscriber: arsenm.Dec 15 2022, 6:28 PM

If you're touching registers this way they should be reserved

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
1859

This is also one of those not-actually serialized in MIR fields

(If the register is marked reserved with -ffixed-xN then you won't get the save/restore code here)

Nope, it's not enough. Before this patch, for example

struct global_data {};
register struct global_data *x9 asm ("x9");

void arch_setup_gd(struct global_data *gd_ptr)
{
        x9 = gd_ptr;

}

clang register.c -O2 -ffixed-x9 -S -o -

arch_setup_gd:                          # @arch_setup_gd
# %bb.0:                                # %entry
	addi	sp, sp, -16
	sd	s1, 8(sp)                       # 8-byte Folded Spill
	mv	s1, a0
	ld	s1, 8(sp)                       # 8-byte Folded Reload
	addi	sp, sp, 16
	ret

Nope, it's not enough. Before this patch, for example

Handling this at the level of llvm.write_register seems like attacking the symptom rather than the root cause issue.
Aren't we just missing the logic to not spill the reserved register?