[Bug gdb/34571] New: gcc/testsuite/gcc.dg/guality/pr45882.c failure on s390x

jakub at redhat dot com via Gdb-prs <[email protected]>
Newsgroups gmane.comp.gdb.bugs.discuss
Message-ID <[email protected]/bugzilla/>
https://sourceware.org/bugzilla/show_bug.cgi?id=34571

            Bug ID: 34571
           Summary: gcc/testsuite/gcc.dg/guality/pr45882.c failure on
                    s390x
           Product: gdb
           Version: 17.1
            Status: NEW
          Severity: normal
          Priority: P2
         Component: gdb
          Assignee: unassigned at sourceware dot org
          Reporter: jakub at redhat dot com
  Target Milestone: ---

The gcc pr45882.c test FAILs on s390x at -O1 and higher and it looks to me like
a gdb bug.
The test itself is:
/* PR debug/45882 */
/* { dg-do run } */
/* { dg-options "-g" } */



extern void abort (void);
int a[1024];
volatile short int v;

__attribute__((noinline,noclone,used)) int
foo (int i, int j)
{
  int b = i;            /* { dg-final { gdb-test .+4 "b" "7" } } */
  int c = i + 4;        /* { dg-final { gdb-test .+3 "c" "11" } } */
  int d = a[i];         /* { dg-final { gdb-test .+2 "d" "112" } } */
  int e = a[i + 6];     /* { dg-final { gdb-test .+1 "e" "142" } } */
  ++v;
  return ++j;
}

int
main (void)
{
  int l;
  asm ("" : "=r" (l) : "0" (7));
  a[7] = 112;
  a[7 + 6] = 142;
  if (foo (l, 7) != 8)
    abort ();
  return l - 7;
}
When compiled with various recent gcc versions (e.g. gcc 14/15/16) with -g -O2
-march=z14 -mtune=z16 (but various other -march/-mtune option trigger it too),
put a breakpoint on the ++v; line and print b; print c; print d;
then the printed b and d values are correct (7 and 112) while printed c is 6
rather than expeccted 11.
Dump of assembler code for function foo:
=> 0x0000000001000660 <+0>:     lhrl    %r1,0x1002028 <v>
   0x0000000001000666 <+6>:     ahik    %r2,%r3,1
   0x000000000100066c <+12>:    ahi     %r1,1
   0x0000000001000670 <+16>:    lgfr    %r2,%r2
   0x0000000001000674 <+20>:    sthrl   %r1,0x1002028 <v>
   0x000000000100067a <+26>:    br      %r14

so first insn in there, caller is

   0x0000000001000508 <+40>:    lghi    %r3,7
   0x000000000100050c <+44>:    lgfr    %r2,%r12
   0x0000000001000510 <+48>:    brasl   %r14,0x1000660 <foo>
=> 0x0000000001000516 <+54>:    cijne   %r2,8,0x100052e <main+78>
   0x000000000100051c <+60>:    ahik    %r0,%r12,-7
   0x0000000001000522 <+66>:    lmg     %r12,%r15,256(%r15)

The i argument is passed in %r2 and saved in the caller in %r12 register.

Corresponding call site info is:

 <3><cb>: Abbrev Number: 4 (DW_TAG_call_site_parameter)
    <cc>   DW_AT_location    : 1 byte block: 52         (DW_OP_reg2 (r2))
    <ce>   DW_AT_call_value  : 2 byte block: 7c 0       (DW_OP_breg12 (r12): 0)
 <3><d1>: Abbrev Number: 4 (DW_TAG_call_site_parameter)
    <d2>   DW_AT_location    : 1 byte block: 53         (DW_OP_reg3 (r3))
    <d4>   DW_AT_call_value  : 1 byte block: 37         (DW_OP_lit7)

so, %r2 is saved in callee save %r12 (as can be seen in code), and %r3 is
constant 7, where

(gdb) p/x $r2
$4 = 0x7
(gdb) p/x $r12
$5 = 0x3ff00000007

 <2><123>: Abbrev Number: 1 (DW_TAG_variable)
    <124>   DW_AT_name        : b
    <126>   DW_AT_decl_file   : 1
    <126>   DW_AT_decl_line   : 14
    <127>   DW_AT_decl_column : 7
    <127>   DW_AT_type        : <0x47>
    <12b>   DW_AT_location    : 0x69 (location list)
    <12f>   DW_AT_GNU_locviews: 0x65
 <2><133>: Abbrev Number: 1 (DW_TAG_variable)
    <134>   DW_AT_name        : c
    <136>   DW_AT_decl_file   : 1
    <136>   DW_AT_decl_line   : 15
    <137>   DW_AT_decl_column : 7
    <137>   DW_AT_type        : <0x47>
    <13b>   DW_AT_location    : 0x82 (location list)
    <13f>   DW_AT_GNU_locviews: 0x80

is what we emit for b and c variable, with
00000069 0000000001000660 (base address)
00000072 v000000000000002 v000000000000000 views at 00000065 for:
         0000000001000660 000000000100066c (DW_OP_reg2 (r2))
00000077 v000000000000000 v000000000000000 views at 00000067 for:
         000000000100066c 000000000100067c (DW_OP_entry_value: (DW_OP_reg2
(r2)); DW_OP_stack_value)
0000007f <End of list>

00000080 v000000000000003 v000000000000000 location view pair

00000082 v000000000000003 v000000000000000 views at 00000080 for:
         0000000001000660 000000000100067c (DW_OP_entry_value: (DW_OP_reg2
(r2)); DW_OP_plus_uconst: 4; DW_OP_stack_value)
00000093 <End of list>

GDB prints

Breakpoint 1, foo (i=i@entry=7, j=j@entry=7) at pr45882.c:18
18        ++v;
(gdb) p b
$1 = 7
(gdb) p c
$2 = 6

where 7 is correct (but we are on 1000660, so it uses DW_OP_reg2 in that case),
but the 6 is just weird.

DW_OP_entry_value DW_OP_reg2 should be %r12 in the caller, so 0x3ff00000007
value plus 4, so 0x3ff0000000b, but as the variable is only 32-bit, gdb should
print the low 32 bits from that, i.e. 11.  Where it came up with 6 is a
mystery.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.