https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64923
Bug ID: 64923 Summary: [s390] Generated code uses struct padding instead of just the bitfield Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: siddhesh at redhat dot com Reproducer: struct obstack { unsigned use_extra_arg:1; unsigned extra_bitfield:1; }; void myfree (void *f) { } void (*freefun) (void *) = myfree; void obstack_free (struct obstack *h, void *obj) { if (h->use_extra_arg) freefun ((void *) 0x42); else freefun ((void *) 0x0); } int main (int argc, char **argv) { struct obstack ob; ob.use_extra_arg = 0; obstack_free (&ob, (void *) 0); return 0; } Build with: gcc -g -O2 -o obs{,.c} $ valgrind ./obs ==20292== Memcheck, a memory error detector ==20292== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==20292== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==20292== Command: ./obs ==20292== ==20292== Conditional jump or move depends on uninitialised value(s) ==20292== at 0x800005B4: obstack_free (obs.min.c:17) ==20292== by 0x80000455: main (obs.min.c:30) ==20292== ==20292== ==20292== HEAP SUMMARY: ==20292== in use at exit: 0 bytes in 0 blocks ==20292== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==20292== ==20292== All heap blocks were freed -- no leaks are possible ==20292== ==20292== For counts of detected and suppressed errors, rerun with: -v ==20292== Use --track-origins=yes to see where uninitialised values come from ==20292== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) This works correctly on x86 since the generated code explicitly selects the relevant bit in the bitfield to test. s390x on the other hand doesn't when built with -O2. It looks like the instruction combiner pass removes the AND operation that selects the bit and instead tests the entire word.