riscv-non-isa/riscv-toolchain-conventions

Duduce default march and mabi

benshi001 opened this issue · 3 comments

I suggestion the march can be deduced via mabi if march is not specified explicitly. And also the mabi can be duduced via march if mabi is not specified explicitly.

For example, my employer's chip has the F extension but has not the D extension, each time I have to specify -march=rv32imacf -mabi=ilp32f, I suggestion the mabi can be default to ilp32f if the march has F but not D. And I have created a patch for that,

https://reviews.llvm.org/D103878

Also, march can be deduced via mabi. Current clang's implementation is

// 3. Choose a default based on -mabi=
//
// ilp32e -> rv32e
// ilp32 | ilp32f | ilp32d -> rv32imafdc
// lp64 | lp64f | lp64d -> rv64imafdc

I suggest change it to

// ilp32e -> rv32e
// ilp32 -> rv32imac
// ilp32f -> rv32imacf
// ilp32d -> rv32 imacfd
// lp64 -> rv64imac
// lp64f -> rv64imacf
// lp64d -> rv64imacfd

Currently soft-float and double-float are the two prevailing floating-point ABIs. The advantage of the current approach is that -march=rv32imafc code is ABI-compatible with -march=rv32imac code. Your first proposal would make ilp32f and lp64f more prevalent, which may or may not be a good thing overall, but does certainly increase the likelihood of getting an error due to linking incompatible code.

I think I agree with your second proposal. Currently clang -target riscv32-unknown-elf gets you rv32imac/ilp32, but clang -target riscv32-unknown-elf -mabi=ilp32 gets you rv32imafdc/ilp32, which is just silly.

With gcc, configuring with --target=riscv32-unknown-elf defaults to rv32gc/ilp32d, assuming no --with-arch or --with-abi configure options. Adding -mabi=ilp32 doesn't change the arch. Similarly, configuring with --target=riscv64-unknown-elf gives rv64gc/lp64d and adding -mabi=lp64 won't change the arch.

If -march is specified and -mabi is not, and march contains F but not D, then we choose a soft-float ABI. So -march=rv32imafc will default to mabi=ilp32.

If mabi is specified and march is not, then we always choose rv{32,64}gc, excluding ilp32e of course.

So it sounds like gcc and llvm are the same except for the --target=riscv32-unknown-elf default with no --with-arch, --with-abi, -march, or -mabi.

In general, I'd suggest that people should get in the habit of specifying both --with-arch= and --with-abi= when configuring gcc, and if they want a different arch or abi, they should specify both -march= and -mabi=. Relying on defaults is risky, as they can and will change over time. We may want to add B, or some subset like zbb_zba to the default arch in a few years for instance. And eventually there may be an embedded ABI (EABI) which is different from the Unix ABI (UABI), and we may want embedded elf targets to default to the EABI instead of the UABI. If you want to avoid trouble in the future, use explicit arch and abi.

I'm OK with changing the defaults if it is necessary. We should not change the defaults too often though.

Thanks. I also think it is safe to use both -mabi and -march. And the default guess is something about fault tolerance, which should not be changed too often.

So we keep current implicit default mabi for explicit march, but change the implicit default march for explicit mabi to

// ilp32e -> rv32e
// ilp32 -> rv32imac
// ilp32f -> rv32imacf
// ilp32d -> rv32 imacfd
// lp64 -> rv64imac
// lp64f -> rv64imacf
// lp64d -> rv64imacfd

Hope more people can agree with me.