public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug debug/105249] New: schedule-insns2 makes a variable not available and associates the code that assigns it to a different function frame
@ 2022-04-12 18:51 assaiante at diag dot uniroma1.it
  2022-04-12 18:54 ` [Bug debug/105249] " assaiante at diag dot uniroma1.it
  2022-11-07 23:13 ` [Bug rtl-optimization/105249] " pinskia at gcc dot gnu.org
  0 siblings, 2 replies; 3+ messages in thread
From: assaiante at diag dot uniroma1.it @ 2022-04-12 18:51 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105249

            Bug ID: 105249
           Summary: schedule-insns2 makes a variable not available and
                    associates the code that assigns it to a different
                    function frame
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: debug
          Assignee: unassigned at gcc dot gnu.org
          Reporter: assaiante at diag dot uniroma1.it
  Target Milestone: ---

In this minimized C example, induction variable i is not available when
stepping on line 9. At -Os we note that the address of the instruction that
assigns to variable a is associated in DWARF with locations from c(), thus
leading to a wrong current function frame when debugging. At -Og/-O1 the
behavior is instead correct. Apparently, schedule-insns2 is responsible for
generating overlapping locations for function c and induction variable i.

At -Oz/-O2/-O3, if we place a breakpoint on line 9 the line is never stepped,
but instead the program breaks inside the body of function c. For this scenario
too, the issue disappears with -fno-schedule-insns2.

Please find below a detailed analysis for -Os on x64 and a quick assessment on
past gcc versions where the issue is sometimes not present.

$ cat a.c
volatile int a;
int b[2];
static void c(int d3) { printf("%d", d3); }
int main() {
  int i;
  b[0] = 0;
  i = 0;
  for (; i < 2; i++)
    a = b[i];
  c(0);
}

GCC and GDB version:
- gcc (GCC) 12.0.0 20211227 (experimental) - commit id: 500d3f0a302
- GNU gdb (GDB) 11.2

GDB trace:
$ gcc -Os -g a.c -o opt
$ gdb -q opt
Reading symbols from opt...
(gdb) b 9
Breakpoint 1 at 0x400421: file a.c, line 9.
(gdb) r
Starting program: /tmp/opt 

Breakpoint 1, c (d3=<optimized out>) at a.c:9
9           a = b[i];
(gdb) info loc
No locals.


ASM at -Os:
0000000000400410 <main>:
  400410:       50                      push   %rax
  400411:       8b 05 25 0c 20 00       mov    0x200c25(%rip),%eax        #
60103c <b+0x4>
  400417:       31 d2                   xor    %edx,%edx
  400419:       31 f6                   xor    %esi,%esi
  40041b:       89 15 1f 0c 20 00       mov    %edx,0x200c1f(%rip)        #
601040 <a>
  400421:       bf b4 05 40 00          mov    $0x4005b4,%edi
  400426:       89 05 14 0c 20 00       mov    %eax,0x200c14(%rip)        #
601040 <a>
  40042c:       31 c0                   xor    %eax,%eax
  40042e:       89 15 04 0c 20 00       mov    %edx,0x200c04(%rip)        #
601038 <b>
  400434:       e8 c7 ff ff ff          callq  400400 <printf@plt>
  400439:       31 c0                   xor    %eax,%eax
  40043b:       59                      pop    %rcx
  40043c:       c3                      retq

DWARF at -Os:
[ function c DIE ]
0x000000a7:     DW_TAG_inlined_subroutine
                  DW_AT_abstract_origin (0x000000f1 "c")
                  DW_AT_entry_pc        (0x000000000040042c)
                  DW_AT_unknown_2138    (0x03)
                  DW_AT_ranges  (0x0000000c
                     [0x0000000000400419, 0x000000000040041b)
                     [0x0000000000400421, 0x0000000000400426)
                     [0x000000000040042c, 0x000000000040042e)
                     [0x0000000000400434, 0x0000000000400439))
                  DW_AT_call_file       ("/tmp/a.c")
                  DW_AT_call_line       (10)
                  DW_AT_call_column     (0x03)

[ variable i DIE ]
0x00000095:     DW_TAG_variable
                  DW_AT_name    ("i")
                  DW_AT_decl_file       ("/tmp/a.c")
                  DW_AT_decl_line       (5)
                  DW_AT_decl_column     (0x07)
                  DW_AT_type    (0x0000003d "int")
                  DW_AT_location        (0x00000010: 
                     [0x0000000000400421, 0x000000000040042c): DW_OP_lit1,
DW_OP_stack_value
                     [0x000000000040042c, 0x000000000040043d): DW_OP_lit2,
DW_OP_stack_value)
                  DW_AT_GNU_locviews    (0x0000000c)


DEBUG line info at -Os:
Address            Line   Column File   ISA Discriminator Flags
------------------ ------ ------ ------ --- ------------- -------------
0x0000000000400421      9      5      1   0             0  is_stmt

In the DWARF info function c is defined in the range [0x0000000000400421,
0x0000000000400426) and from the line info we can see how the begin address of
the range is associated with line 9. This causes the variable i to not be
available when debugging even if its location is correctly defined.

Through some testing we found out that the optimization that makes the variable
not available and introduces the location overlapping is -fschedule-insns2. If
we add -fno-schedule-insns2 to the previous compilation command line, the issue
is not present anymore since the DWARF location and line number association are
correctly computed. The option would also solve the correctness problem pointed
out for -Oz/-O2/-O3.

ASM at -Os with -fno-schedule-insns2:
0000000000400410 <main>:
  400410:       50                      push   %rax
  400411:       31 d2                   xor    %edx,%edx
  400413:       89 15 1f 0c 20 00       mov    %edx,0x200c1f(%rip)        #
601038 <b>
  400419:       89 15 21 0c 20 00       mov    %edx,0x200c21(%rip)        #
601040 <a>
  40041f:       8b 05 17 0c 20 00       mov    0x200c17(%rip),%eax        #
60103c <b+0x4>
  400425:       89 05 15 0c 20 00       mov    %eax,0x200c15(%rip)        #
601040 <a>
  40042b:       31 f6                   xor    %esi,%esi
  40042d:       bf b4 05 40 00          mov    $0x4005b4,%edi
  400432:       31 c0                   xor    %eax,%eax
  400434:       e8 c7 ff ff ff          callq  400400 <printf@plt>
  400439:       31 c0                   xor    %eax,%eax
  40043b:       59                      pop    %rcx
  40043c:       c3                      retq 


DWARF info at -Os with -fno-schedule-insns2:
[ function c DIE ]
0x000000a7:     DW_TAG_inlined_subroutine
                  DW_AT_abstract_origin (0x000000f7 "c")
                  DW_AT_entry_pc        (0x000000000040042b)
                  DW_AT_unknown_2138    (0x03)
                  DW_AT_low_pc  (0x000000000040042b)
                  DW_AT_high_pc (0x0000000000400439)
                  DW_AT_call_file       ("/tmp/a.c")
                  DW_AT_call_line       (10)
                  DW_AT_call_column     (0x03)

[ variable i DIE ]
0x00000095:     DW_TAG_variable
                  DW_AT_name    ("i")
                  DW_AT_decl_file       ("/tmp/a.c")
                  DW_AT_decl_line       (5)
                  DW_AT_decl_column     (0x07)
                  DW_AT_type    (0x0000003d "int")
                  DW_AT_location        (0x00000010: 
                     [0x000000000040041f, 0x000000000040042b): DW_OP_lit1,
DW_OP_stack_value
                     [0x000000000040042b, 0x000000000040043d): DW_OP_lit2,
DW_OP_stack_value)
                  DW_AT_GNU_locviews    (0x0000000c)


DEBUG line info at -Os with -fno-schedule-insns2:
Address            Line   Column File   ISA Discriminator Flags
------------------ ------ ------ ------ --- ------------- -------------
0x000000000040041f      9      5      1   0             0  is_stmt

We have also tested older gcc versions (6.4, 7.5, 8.4, 9.3, 10.3, 11.1) and the
results are identical to the git version starting from gcc-9. Instead, on
previous versions the variable is correctly shown.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug debug/105249] schedule-insns2 makes a variable not available and associates the code that assigns it to a different function frame
  2022-04-12 18:51 [Bug debug/105249] New: schedule-insns2 makes a variable not available and associates the code that assigns it to a different function frame assaiante at diag dot uniroma1.it
@ 2022-04-12 18:54 ` assaiante at diag dot uniroma1.it
  2022-11-07 23:13 ` [Bug rtl-optimization/105249] " pinskia at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: assaiante at diag dot uniroma1.it @ 2022-04-12 18:54 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105249

--- Comment #1 from Cristian Assaiante <assaiante at diag dot uniroma1.it> ---
This issue is similar to bug 105036 but it appears on different optimization
levels and, differently from the previously reported issue, it has a much
simpler code structure since we have only a call to a printf in the body of the
inlined routine.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug rtl-optimization/105249] schedule-insns2 makes a variable not available and associates the code that assigns it to a different function frame
  2022-04-12 18:51 [Bug debug/105249] New: schedule-insns2 makes a variable not available and associates the code that assigns it to a different function frame assaiante at diag dot uniroma1.it
  2022-04-12 18:54 ` [Bug debug/105249] " assaiante at diag dot uniroma1.it
@ 2022-11-07 23:13 ` pinskia at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-11-07 23:13 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105249

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-debug
          Component|debug                       |rtl-optimization

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
One of the biggest issue with the current design of the scheduler with respect
to debug info is how it decides to "schedule" debug instructions. I don't know
if there is anything that can be done about this exactly. Plus having overlap
ranges of live variables is going to happen with instruction scheduling.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-11-07 23:13 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-12 18:51 [Bug debug/105249] New: schedule-insns2 makes a variable not available and associates the code that assigns it to a different function frame assaiante at diag dot uniroma1.it
2022-04-12 18:54 ` [Bug debug/105249] " assaiante at diag dot uniroma1.it
2022-11-07 23:13 ` [Bug rtl-optimization/105249] " pinskia at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).