This is an archive of the discontinued LLVM Phabricator instance.

[LoongArch] Implement the TargetLowering::getRegisterByName hook
ClosedPublic

Authored by gonglingqin on Nov 6 2022, 11:35 PM.

Diff Detail

Event Timeline

gonglingqin created this revision.Nov 6 2022, 11:35 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 6 2022, 11:35 PM
gonglingqin requested review of this revision.Nov 6 2022, 11:35 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 6 2022, 11:35 PM
SixWeining added inline comments.Nov 11 2022, 11:10 PM
llvm/test/CodeGen/LoongArch/get-noreg.ll
2 ↗(On Diff #473576)

crash may slow down the test. Could we not add such tests?

llvm/test/CodeGen/LoongArch/get-reg-error.ll
2 ↗(On Diff #473576)

Ditto.

llvm/test/CodeGen/LoongArch/get-reg-reserve.ll
1 ↗(On Diff #473576)

I suggest to rename get-reg-reserve.ll to get-reg.ll since get-reg-reserve.ll may imply we support getting non-reserved registers.

gonglingqin added inline comments.Nov 11 2022, 11:30 PM
llvm/test/CodeGen/LoongArch/get-noreg.ll
2 ↗(On Diff #473576)

Thanks, I will remove this test.

llvm/test/CodeGen/LoongArch/get-reg-error.ll
2 ↗(On Diff #473576)

Thanks, I will remove this test.

llvm/test/CodeGen/LoongArch/get-reg-reserve.ll
1 ↗(On Diff #473576)

Thanks, I will rename this file.

Address @SixWeining's comments.

This revision is now accepted and ready to land.Nov 13 2022, 6:56 PM
xen0n added a comment.Nov 13 2022, 7:18 PM

I'm curious what usage case motivated the change? Not to say it's unnecessary but it's better to have people know a bit more background behind this work.

I'm curious what usage case motivated the change? Not to say it's unnecessary but it's better to have people know a bit more background behind this work.

This interface is required by the code in https://github.com/loongson/linux/blob/master/arch/loongarch/include/asm/percpu.h#L12-L18. This patch can avoid crashes when compiling the kernel with llvm in the future.

I'm curious what usage case motivated the change? Not to say it's unnecessary but it's better to have people know a bit more background behind this work.

This interface is required by the code in https://github.com/loongson/linux/blob/master/arch/loongarch/include/asm/percpu.h#L12-L18. This patch can avoid crashes when compiling the kernel with llvm in the future.

Very nice to know.

BTW, are the normal GPRs already supported like this too (things like global register long foo __asm__("$a0")), even without this change, or are such usages invalid in the first place? Memory is failing me.

I'm curious what usage case motivated the change? Not to say it's unnecessary but it's better to have people know a bit more background behind this work.

This interface is required by the code in https://github.com/loongson/linux/blob/master/arch/loongarch/include/asm/percpu.h#L12-L18. This patch can avoid crashes when compiling the kernel with llvm in the future.

Very nice to know.

BTW, are the normal GPRs already supported like this too (things like global register long foo __asm__("$a0")), even without this change, or are such usages invalid in the first place? Memory is failing me.

I've not built LLVM and Clang for LoongArch recently, but on gcc400.fsffrance.org (with Arch Linux for LoongArch installed) I got:

$ clang -v 2>&1 | head -n1
clang version 14.0.6
$ cat t.c
register int y __asm__("$s0");
int o() { register int x __asm__("$t0"); return y; }
$ clang t.c -S
fatal error: error in backend: Invalid register name global variable
... ... (stack trace)

But if we change it to return x;, the code will be compiled successfully. So it looks like local register variables with assigned GPR have been supported, but the global ones are not.

I'm curious what usage case motivated the change? Not to say it's unnecessary but it's better to have people know a bit more background behind this work.

This interface is required by the code in https://github.com/loongson/linux/blob/master/arch/loongarch/include/asm/percpu.h#L12-L18. This patch can avoid crashes when compiling the kernel with llvm in the future.

Very nice to know.

BTW, are the normal GPRs already supported like this too (things like global register long foo __asm__("$a0")), even without this change, or are such usages invalid in the first place? Memory is failing me.

As @xry111 said, any local register variables with assigned GPR can be read (the analysis process is completed by clang), but only reserved registers can be read when reading global registers.

thakis added a subscriber: thakis.Dec 3 2022, 4:27 AM
thakis added inline comments.
llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
2462

This is a bit strange to me from a dependency point of view. GenAsmMatcher conceptually belongs to LoongArchAsmParser, but LoongArchCodeGen doesn't depend on LoongArchAsmParser. I believe other targets don't include GenAsmMatcher.inc from their codegen libraries (except aarch64 and riscv, but it's strange there too -- see also https://reviews.llvm.org/D69130#inline-627969).

Any chance this could be layered nicer?

gonglingqin added inline comments.Dec 4 2022, 7:09 PM
llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
2462

Thanks for your advice. We considered using StringSwitch for matching, but we chose the current implementation because of code reuse. Do you think using stringswitch is a better way to do this, or do you have any suggestions?