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

            Bug ID: 128520
           Summary: wrong code at -O2: fwprop and late-combine propagate a
                    pseudo across setjmp; stores lost in a loop over
                    _BitInt(129) since r17-3330
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jeffchen006 at gmail dot com
  Target Milestone: ---
            Target: x86_64-pc-linux-gnu

#include <setjmp.h>

int printf(const char *, ...);

jmp_buf jb;
int g;
_BitInt(129) a[4];

int main(void)
{
  for (int i = 0; i < 4; i++) {
    g |= a[i];
    if (setjmp(jb) == 0)
      if (a[(i + 1) % 4] < 1)
        longjmp(jb, 1);
    a[(i + 1) % 4] = 5;
  }
  setjmp(jb);
  printf("%d %d %d %d\n", (int)a[0], (int)a[1], (int)a[2], (int)a[3]);
  return 0;
}

$ gcc -O0 t.c && ./a.out
5 5 5 5
$ gcc -O2 t.c && ./a.out
5 0 5 0

Expected 5 5 5 5: each iteration stores 5 in the next element. setjmp is the
whole controlling expression, and i does not change between setjmp and longjmp.

Cause: the RTL CFG has no abnormal edges for setjmp. fwprop (and late-combine,
if fwprop is off) replaces one pseudo with another pseudo that has several
definitions, across the _setjmp call. That pseudo changes before the longjmp,
so after setjmp returns the second time, the loop index has gone up by 2. cse
and cselib already stop at setjmp, and cprop and gcse do not run in such
functions. The two RTL-SSA passes have no check.

First bad commit: r17-3330-g4fe2072d5d1 (backward threading to a loop exit). It
only makes the RTL that shows the problem; all tree dumps are correct.
Correct on 16.2. Wrong on trunk.
Avoided by: -fno-thread-jumps, or -fno-forward-propagate
-fno-late-combine-instructions together

UBSan and ASan are clean at -O0.
gcc version 17.0.0 20261029 (experimental), r17-5747-g85867b0c935,
x86_64-pc-linux-gnu

Reply via email to