https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128019
Bug ID: 128019
Summary: [DebugInfo] AArch64: wrong GDB values for signed
_BitInt remainders at -O2
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: MrEven132 at outlook dot com
Target Milestone: ---
With GCC 17.0.0 20261003 (experimental) and GDB 17.2 on AArch64, GDB reports 0
for signed _BitInt(7) and _BitInt(8) remainders whose value is -1 when the
examples below are compiled at -O2. The same breakpoints show -1 at -O0.
Test case 1 (_BitInt(7), case.c):
volatile int sink_bitint;
__attribute__((noinline)) int test_bitint_signed (_BitInt(7) a, _BitInt(7)
b)
{
_BitInt(7) quotient = a / b;
_BitInt(7) remainder = a % b;
sink_bitint += a + b;
return quotient + remainder;
}
__attribute__((noinline)) int test_bitint_unsigned (unsigned _BitInt(9) a,
unsigned _BitInt(9) b)
{
unsigned _BitInt(9) remainder = a % b;
sink_bitint += a + b;
return remainder;
}
int main (void)
{
return test_bitint_signed (-55, 3) + test_bitint_unsigned (400, 9);
}
Build on AArch64 with `gcc -O0 -g case.c -o case-O0` and `gcc -O2 -g case.c -o
case-O2`. In separate GDB sessions, break on the `sink_bitint += a + b;` line
in `test_bitint_signed`, run, and print `remainder`. The expected value is -55
% 3 = -1; GDB prints -1 at -O0 and 0 at -O2.
Test case 2 (_BitInt(8), case.c):
volatile int sink_bitint_width;
__attribute__((noinline)) int test_bitint8 (_BitInt(8) a, _BitInt(8) b)
{
_BitInt(8) quotient = a / b;
_BitInt(8) remainder = a % b;
sink_bitint_width += a + b;
return quotient + remainder;
}
__attribute__((noinline)) int test_bitint9 (_BitInt(9) a, _BitInt(9) b)
{
_BitInt(9) quotient = a / b;
_BitInt(9) remainder = a % b;
sink_bitint_width += a + b;
return quotient + remainder;
}
__attribute__((noinline)) int test_bitint16 (_BitInt(16) a, _BitInt(16) b)
{
_BitInt(16) quotient = a / b;
_BitInt(16) remainder = a % b;
sink_bitint_width += a + b;
return quotient + remainder;
}
int main (void)
{
return test_bitint8 (-55, 3) + test_bitint9 (-251, 7) + test_bitint16
(-30001, 7);
}
Use the same two build commands. Break on the `sink_bitint_width += a + b;`
line in `test_bitint8` and print `remainder`. The expected value is -1; GDB
prints -1 at -O0 and 0 at -O2.
At the optimized breakpoints, the DWARF location expression for each signed
`remainder` begins with:
DW_OP_breg0 W0+0, DW_OP_breg1 W1+0, DW_OP_over, DW_OP_over, DW_OP_div,
DW_OP_mul, DW_OP_minus, DW_OP_stack_value
With `a = -55` and `b = 3`, register W0 contains 0xffffffc9 and W1 contains 3.
The generated expression appears to perform the division at the DWARF stack
width without restoring the signed width of the source operands, yielding a
remainder of 0 instead of -1. These _BitInt remainders appear to be additional
reproductions of the narrow signed-expression debug-info issue, rather than a
separate AArch64 defect.