https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128027
Bug ID: 128027
Summary: [DebugInfo] i386 CONCAT locations emit oversized x87
register pieces
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: debug
Assignee: unassigned at gcc dot gnu.org
Reporter: wujielun402 at gmail dot com
Target Milestone: ---
GCC emits an invalid DWARF 5 location for a local complex long double with
-m32 -m128bit-long-double. The type has DW_AT_byte_size 32. GCC describes the
value using two 16-byte pieces from the 80-bit x87 stack registers st1 and
st0:
DW_OP_reg12 (st1); DW_OP_piece 16
DW_OP_reg11 (st0); DW_OP_piece 16
Each x87 register contains an 80-bit value (10 bytes), so neither register
can supply the 16-byte piece requested by DW_OP_piece. DWARF 5 section
2.6.1.2 defines the operand as the byte size of the corresponding object
piece.
Each long double occupies 16 bytes in memory: 10 bytes for the floating-point
value and 6 bytes of padding. One suitable location description is:
DW_OP_reg12 (st1); DW_OP_piece 10
DW_OP_piece 6
DW_OP_reg11 (st0); DW_OP_piece 10
DW_OP_piece 6
Each standalone DW_OP_piece 6 marks the corresponding padding bytes as
unavailable. This preserves the imaginary component's offset of 16 bytes
and the total object size of 32 bytes, without requesting more than 10 bytes
from either x87 register.
Reproducer source (repro.c):
typedef __complex__ long double complex_long_double;
extern void consume_complex (complex_long_double);
__attribute__ ((noinline, noclone)) complex_long_double
keep_complex_in_x87 (complex_long_double input)
{
complex_long_double value = input;
consume_complex (value);
return value;
}
Compile to an object:
gcc -m32 -m128bit-long-double -mfpmath=387 -O2 -g -gdwarf-5 \
-c repro.c -o repro.o
Compiler Explorer example: https://godbolt.org/z/q89qc7G8a
The producer is concat_loc_descriptor in gcc/dwarf2out.cc. It uses each
CONCAT child's 16-byte XFmode storage size as the piece size even when the
child location is a single 80-bit x87 register.