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

            Bug ID: 108117
           Summary: Wrong instruction scheduling on value coming from
                    abnormal SSA
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: fxue at os dot amperecomputing.com
  Target Milestone: ---

Compile the following code with "-O2" on AArch64.

#include <stdio.h>
#include <setjmp.h>

jmp_buf ex_buf;

__attribute__((noinline)) int fn_throw(int x)
{
   if (x == 1)
      longjmp(ex_buf, 1);
   return 1;
}

int main(int argc, char** argv)
{
    int va = 0;
    int vb = 0;

    if (!setjmp(ex_buf)) {
        va = fn_throw(1); /* throw via longjmp */
        vb = 1;
    } else
        printf("Got exception, va = %d\n", va);

    if (vb)
        printf("Failed, vb should not = %d!\n", vb);

    return 0;
}

Since "fn_throw" involves abnormal control flow transferring, any statement
after "va = fn_throw(1)" should not be hoisted prior to the call. In this case,
"vb = 1" is moved before it by RTL inst sched, and leads to incorrect result.

Similar to C++ exception handling, setjmp/longjmp would generate SSA names
occurring in abnormal phi, these should be specially treated. Though, it looks
like that RTL passes do not respect this characteristics in any kind of code
motions. Now the issue is only exposed on AArch64, for while inst sched1 pass
is enabled, but it is also a potential one on other backends.

Reply via email to