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

            Bug ID: 128551
           Summary: wrong code with sign-extended loads
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: yuki.tanaka at defaultcase dot de
  Target Milestone: ---

#include <stdint.h>

int64_t g;

__attribute__((noipa)) int64_t a(int32_t x, int64_t *d)
{
  int64_t c;

  *d = 0;

  if (x)
    c = (int32_t)*(int64_t *)&g;
  else
    c = (int32_t)*(long long *)&g;

  *d = 1;
  return c;
}

int main(void)
{
  g = -1;

  if (a(1, &g) != 0)
    __builtin_abort();

  return 0;
}

a(1, &g) must return 0: *d = 0 sets g to 0 before it is read. Instead a returns
-1 and main aborts. GCC removes *d = 0 and reads the initial value of g. This
happens on current trunk with -O2 -fdisable-tree-phiopt1 -fdisable-tree-phiopt2
-fdisable-tree-phiopt3 -fdisable-tree-phiopt4.

This variant adds an (int32_t) cast to both branches and still fails after the
fix for PR125683.

Compiler Explorer:
https://godbolt.org/z/z643TqvK3

Reply via email to