public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/110743] New: Unexpected -ftrivial-auto-var-init=pattern behavior with partial bitfields
@ 2023-07-19 15:59 arnd at linaro dot org
  2023-07-20  9:57 ` [Bug tree-optimization/110743] " rguenth at gcc dot gnu.org
  0 siblings, 1 reply; 2+ messages in thread
From: arnd at linaro dot org @ 2023-07-19 15:59 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 110743
           Summary: Unexpected -ftrivial-auto-var-init=pattern behavior
                    with partial bitfields
           Product: gcc
           Version: 13.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: arnd at linaro dot org
  Target Milestone: ---

A warning showed up in Linux kernel builds with code that has a data structure
with sub-byte holes in it, making it appear as though the structure was
uninitialized even though there is no user before the intialization:

struct spi_mem_op {
  struct {
    int a : 1;
  };
  struct {
    char b : 1;
    long c;
  };
};
void spi_nor_read_any_reg(struct spi_mem_op *);
void s25fs256t_post_bfpt_fixup_nor(void) {
  struct spi_mem_op op;
  spi_nor_read_any_reg(&op);
}

$ x86_64-linux-gnu-gcc-12 -O2 -ftrivial-auto-var-init=pattern -Wuninitialized
     x86-64 gcc 12.3 (Editor #1)
x86-64 gcc 12.3 - 905ms (5966B) ~392 lines filtered

    Output of x86-64 gcc 12.3 (Compiler #1)

<source>: In function 's25fs256t_post_bfpt_fixup_nor':
<source>:12:21: warning: 'op' is used uninitialized [-Wuninitialized]
   12 |   struct spi_mem_op op;
      |                     ^~
<source>:12:21: note: 'op' declared here
   12 |   struct spi_mem_op op;
      |                     ^~

See also https://godbolt.org/z/o96GfTaaT

gcc-11 and earlier don't show this behavior because they do not support
-ftrivial-auto-var-init=pattern. I notice that in the example above, the first
16 bytes of the structure are intialized to zero with an x86 SSE instruction
since they do not contain any actual data bytes, just single bits.

This seems to be the same underlying problem as in bug #104550, but that one is
marked fixed and I cannot reproduce it on gcc-12 or gcc-13.

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [Bug tree-optimization/110743] Unexpected -ftrivial-auto-var-init=pattern behavior with partial bitfields
  2023-07-19 15:59 [Bug c/110743] New: Unexpected -ftrivial-auto-var-init=pattern behavior with partial bitfields arnd at linaro dot org
@ 2023-07-20  9:57 ` rguenth at gcc dot gnu.org
  0 siblings, 0 replies; 2+ messages in thread
From: rguenth at gcc dot gnu.org @ 2023-07-20  9:57 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
                 CC|                            |jakub at gcc dot gnu.org,
                   |                            |rguenth at gcc dot gnu.org
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2023-07-20
             Blocks|                            |24639

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
We interestingly see

  <bb 2> :
  op = .DEFERRED_INIT (24, 1, &"op"[0]);
  _1 = MEM <long int> [(struct spi_mem_op *)&op];
  _2 = _1 & 1;
  MEM <long int> [(struct spi_mem_op *)&op] = _2;
  _3 = MEM <long int> [(struct spi_mem_op *)&op + 8B];
  _4 = _3 & 1;
  MEM <long int> [(struct spi_mem_op *)&op + 8B] = _4;
  spi_nor_read_any_reg (&op);
  op ={v} {CLOBBER(eol)};
  return;

which is done by __builtin_clear_padding which we insert during gimplification:

void s25fs256t_post_bfpt_fixup_nor ()
{
  struct spi_mem_op op;

  try
    {
      op = .DEFERRED_INIT (24, 1, &"op"[0]);
      __builtin_clear_padding (&op, 1B);
      spi_nor_read_any_reg (&op);
    }
  finally
    {
      op = {CLOBBER(eol)};
    }
}

I'm not sure why we do it this way.  I wonder why we don't diagnose this at
-O0.

Note RTL expansion of .DEFERRED_INIT _does_ write to the bitfield padding
so maybe we can avoid doing that in __builtin_clear_padding (with an extra
op?).  Confirmed.

A workaround is to explicitely name the padding thus add int padding : 31, etc.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24639
[Bug 24639] [meta-bug] bug to track all Wuninitialized issues

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-07-20  9:57 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-19 15:59 [Bug c/110743] New: Unexpected -ftrivial-auto-var-init=pattern behavior with partial bitfields arnd at linaro dot org
2023-07-20  9:57 ` [Bug tree-optimization/110743] " rguenth at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).