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

            Bug ID: 128265
           Summary: wrong code at -O1 and above: a conditionally read bool
                    union member is loaded while the union holds another
                    member
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: kyuwoncho18 at gmail dot com
  Target Milestone: ---
            Target: x86_64-pc-linux-gnu

#include <stdbool.h>
struct Value { int type; union { bool boolean; long long t; }; };
static struct Value s_item_mem;
static volatile int selector = 1;
static bool truthy(void) __attribute__((noipa));
static bool truthy(void)
{
  bool other = false;
  bool *p;
  if (selector)
    p = &s_item_mem.boolean;
  else
    p = &other;
  bool tt = false;
  for (int i = 0; i < 10; i++) {
    if (s_item_mem.type == 0)
      tt = tt | 0;
    else if (s_item_mem.type == 1)
      tt = tt | *p;
    else
      tt = tt | 1;
  }
  return tt;
}
int main(void)
{
  s_item_mem.type = 2;
  s_item_mem.t = -1;
  bool b1 = !truthy();
  s_item_mem.type = 1;
  s_item_mem.boolean = b1;
  bool b = truthy();
  if (b1 != b) __builtin_abort();
  if (b) __builtin_abort();
}

godbolt: https://godbolt.org/z/scEPvvGqf

The first call takes the tt | 1 arm and never reads s_item_mem.boolean, so it
returns true; the second call reads boolean == false and returns false, so the
program must exit normally, as it does at -O0 and with -O1 -fno-tree-phiprop.
At -O1, -O2, -O3 and -Os it aborts.

Reply via email to