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

            Bug ID: 88129
           Summary: Two blockage insns are emited in the function epilogue
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ubizjak at gmail dot com
  Target Milestone: ---

The blockage instruction is generated as a kludge in expand_function_end to
prevent instructions that may trap to be scheduled into the function epilogue.
However, the same blockage is generated under exactly the same conditions
earlier in the expand_function_end. The first blockage should not be necessary,
as the second already prevents unwanted scheduling into the epilogue.

An example:

int test (void) { return 0; }

./cc1 -O2 -fnon-call-exceptions empty.c

(insn 5 2 9 2 (set (reg:SI 82 [ <retval> ])
        (const_int 0 [0])) "empty.c":1:26 -1
     (nil))
(insn 9 5 10 2 (unspec_volatile [
            (const_int 0 [0])
        ] UNSPECV_BLOCKAGE) "empty.c":1:1 -1
     (nil))
(insn 10 9 11 2 (set (reg/i:SI 0 ax)
        (reg:SI 82 [ <retval> ])) "empty.c":1:1 -1
     (nil))
(insn 11 10 12 2 (unspec_volatile [
            (const_int 0 [0])
        ] UNSPECV_BLOCKAGE) "empty.c":1:1 -1
     (nil))
(insn 12 11 0 2 (use (reg/i:SI 0 ax)) "empty.c":1:1 -1
     (nil))

Please note (insn 9) and (insn 11).

Some software archaeology:

The blockage was introduced as a fix for PR14381 [1] in r79265 [2].
Later, the blockage was moved after return label as a fix for PR25176
[3] in r107871 [4].

After that, r122626 [5] moves the blockage after the label for the
naked return from the function. Relevant posts from gcc-patches@ ML
are at [6], [7].

The extra blockage (the first one) was reintroduced by the merge of dataflow
branch [8] that copies back the hunk, moved in r122626 [5] to its original
position. From this revision onwards, we emit two blockage instructions.

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=14381
[2] https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=79265
[3] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25176
[4] https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=107871
[5] https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=122626
[6] https://gcc.gnu.org/ml/gcc-patches/2007-02/msg01143.html
[7] https://gcc.gnu.org/ml/gcc-patches/2007-02/msg01623.html
[8]
https://gcc.gnu.org/viewcvs/gcc/trunk/gcc/function.c?limit_changes=0&r1=125624&r2=125623&pathrev=125624

Looking at the kludge, which say:

  /* @@@ This is a kludge.  We want to ensure that instructions that
     may trap are not moved into the epilogue by scheduling, because
     we don't always emit unwind information for the epilogue.  */

do we need the blockage at all for targets that emit unwind information in the
epilogue?

Reply via email to