[RISC-V] Jump tables with small offsets use full word sized offsets
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
I noticed a significant code size expansion when compiling https://github.com/zephyrproject-rtos/hal_nxp/blob/master/mcux/mcux-sdk-ng/drivers/iee_apc/fsl_iee_apc.c for RISC-V (rv32imb_zec) compared to armv8-m.main.
The main source of code size expansion is this function: https://github.com/zephyrproject-rtos/hal_nxp/blob/8c43cb9d24036c3f9e41aae3da5984dd60e035bf/mcux/mcux-sdk-ng/drivers/iee_apc/fsl_iee_apc.c#L79
It contains a switch-case like if structure.
For Arm thumb, this makes efficient use of tbb (Table Branch Byte) Instruction.
RISC-V does not have that so it cannot match that.
Moreover, while for Arm, a jump table containing bytes is created, it is a table of words for RISC-V.
Goldbolt reproducer:
https://godbolt.org/z/d8bfhKqx3
I do not have the M-profile on godbolt, but also for ARM mode, byte tables are used.
I do not see an ISA reason why this should not work on RISC-V.
Note that for this particular function, there would be an even faster and smaller version possible, that calculates the jump target instead of loading it from a table, as the targets are evenly spaced, 6B apart. I understand, if that is an optimization, the compiler is not able to perform.
Contributor guide
Research direction
Start with the switch-like function at line 79 of mcux/mcux-sdk-ng/drivers/iee_apc/fsl_iee_apc.c and compare its rv32imb_zec output with the Arm output in the linked Compiler Explorer reproducer. Inspect how LLVM forms the RISC-V jump table and its offsets. Done means confirming compact offsets are generated where valid, with the resulting code size and behavior checked against the reproducer.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100