public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "roland.illig at gmx dot de" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug target/110772] strange code generated for bit-field access
Date: Sat, 22 Jul 2023 15:21:30 +0000	[thread overview]
Message-ID: <bug-110772-4-z2pSrku3oh@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-110772-4@http.gcc.gnu.org/bugzilla/>

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

--- Comment #5 from Roland Illig <roland.illig at gmx dot de> ---
Sorry for the confusing description. Let me try again.

NetBSD lint includes a yacc parser for C code. This parser contains the rules
'block_item_list' and 'block_item':

https://github.com/NetBSD/src/blob/7ebcd1679b455e619909ec9c128e8ad7f103ded9/usr.bin/xlint/lint1/cgram.y#L1804
> block_item_list: /* C99 6.8.2 */
>   block_item
> | block_item_list block_item {
>     if ($1 && !$2)
>       /* declarations after statements is a C99 feature */
>       c99ism(327);
>     $$ = $1 || $2;
>   }


The rule 'block_item' remembers in 'y_seen_statement' whether the item was a
statement, so that the parser rule 'block_item_list' can warn in C90 mode.

In another part of the parser, the rule 'gcc_attribute' handles the keyword
'const', by accessing 'y_type_qualifiers.tq_const', which on 2023-07-15 was a
_Bool bit-field member in 'struct type_qualifiers'.

https://github.com/NetBSD/src/blob/7ebcd1679b455e619909ec9c128e8ad7f103ded9/usr.bin/xlint/lint1/cgram.y#L2197
> gcc_attribute:
> | type_qualifier {
>     if (!$1.tq_const)
>       yyerror("Bad attribute");
>   }

On big-endian arm and powerpc, the code that GCC 10.5.0 generates for the
'block_item_list' parser rule depends on whether the 'gcc_attribute' parser
rule accesses a bit-field member or not. This does not make sense to me, as I
expect the parser rules to be independent.

When I compile this parser on arm with -O2 and run lint in C90 mode, it not
only warns about declarations after statements, but also about statements after
statements.

$ gcc -O2 -ftrapv -fPIE -std=gnu99 -S cgram.c -o cgram.casmv -fverbose-asm

The code that is generated for the condition '$1 && !$2' is:

> @ cgram.y:1802:                 if ($1 && !$2)
>         ldr     r6, .L580+796
>         add     r6, pc, r6
>         ldr     r4, [r6, #20]
>         ldrb    r3, [r4, #-8]   @ $1.y_seen_statement
>         cmp     r3, #0
>         beq     .L368
> @ cgram.y:550:          $$ = build_unary($2 == INC ? INCAFT : DECAFT, $3, $1);
>         ldrb    r3, [r4]
> @ cgram.y:1802:
>         lsrs    r3, r3, #7      @ $2.y_type_qualifiers.tq_const
>         beq     .L562

(Annotations hand-edited by me.)

Two strange things happen here:

1. The code from cgram.y:550 is completely unrelated, so it should not have
been mentioned here. The 'ldrb' is correct, so maybe it's just the attribution
that is wrong.

2. The expressions '$1' and '$2' both have type _Bool. Nevertheless, the second
bool is accessed as if it were a bit-field. Due to this access, no matter
whether '$2 as bool' is 1 or 0, the the expression '($2 as bit-field) >> 7'
always evaluates to 0, so the condition '$1 && !$2' evaluates to true, which
results in the additional warnings from lint.

Instead of lsrs, GCC should have generated a cmp instruction.

I don't have any other GCC version installed on the machine, so I cannot test
whether GCC 11.4.0 behaves differently.

  parent reply	other threads:[~2023-07-22 15:21 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-21 23:26 [Bug c/110772] New: " roland.illig at gmx dot de
2023-07-21 23:27 ` [Bug c/110772] " roland.illig at gmx dot de
2023-07-21 23:53 ` [Bug target/110772] " pinskia at gcc dot gnu.org
2023-07-22  0:08 ` pinskia at gcc dot gnu.org
2023-07-22  0:11 ` pinskia at gcc dot gnu.org
2023-07-22 15:21 ` roland.illig at gmx dot de [this message]
2023-07-22 15:23 ` roland.illig at gmx dot de
2023-07-22 15:29 ` roland.illig at gmx dot de
2023-07-22 15:50 ` roland.illig at gmx dot de

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-110772-4-z2pSrku3oh@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).