The assembly code in libgcc/config/riscv/div.S does not handle the division by zero as specified in the riscv-spec v2.2 chapter 6.2 in case of signed division:
"The quotient of division by zero has all bits set, i.e. 2XLEN−1 for unsigned division or−1 for signed division." When a negative number is divided by zero in the __divdi3 function, the result is 1 instead of -1. As soon as there exists a specific implementation for the software division for the RISC-V and although that the C language allows unspecified result in case of division by zero, it would be worth aligning the software RISC-V division with the hardware implementation so that the compliance tests could pass whatever the -mno-div or -mdiv flag value. Especially in the case where the patch is simple, does not add additional code size nor execution time. The patch proposes that when the dividend is negative, a zero divisor is considered as negative so that the result of the unsigned division will not be inverted. This consists of exchanging a "branch greater or equal zero (bgez)" with a "branch greater than zero (bgtz)". Virginie ------------------------------------------- ChangeLog *libgcc/config/riscv/div.S: Change handling of signed division by zero in case of negative dividend to align with RISC-V specification for hardware division. -------------------------------------------- diff --git a/libgcc/config/riscv/div.S b/libgcc/config/riscv/div.S index 922a4338042..57f5856e11d 100644 --- a/libgcc/config/riscv/div.S +++ b/libgcc/config/riscv/div.S @@ -107,7 +107,8 @@ FUNC_END (__umoddi3) /* Handle negative arguments to __divdi3. */ .L10: neg a0, a0 - bgez a1, .L12 /* Compute __udivdi3(-a0, a1), then negate the result. */ + bgtz a1, .L12 /* Compute __udivdi3(-a0, a1), then negate the result. */ + /* Zero is handled as a negative so that the result will not be inverted */ neg a1, a1 j __udivdi3 /* Compute __udivdi3(-a0, -a1). */