public inbox for gcc-bugs@sourceware.org help / color / mirror / Atom feed
* [Bug c/110772] New: strange code generated for bit-field access @ 2023-07-21 23:26 roland.illig at gmx dot de 2023-07-21 23:27 ` [Bug c/110772] " roland.illig at gmx dot de ` (7 more replies) 0 siblings, 8 replies; 9+ messages in thread From: roland.illig at gmx dot de @ 2023-07-21 23:26 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110772 Bug ID: 110772 Summary: strange code generated for bit-field access Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: roland.illig at gmx dot de Target Milestone: --- Target: arm Created attachment 55598 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55598&action=edit precompiled code that generates unrelated diagnostics In NetBSD's lint, I changed 'struct type_qualifier' from an enum to a set of bit-fields. It worked well on x86_64 but not on arm and powerpc. https://github.com/NetBSD/src/commit/35c652085d26b93b94f55312f715361ee0cd2043 On these two 32-bit platforms, lint generated some unrelated and wrong diagnostics. I tracked the difference down to a single line of code, and changing that line changes unrelated code. In the attached p5.i, applying the following diff changes not only the code in cgram.y:529, but also in cgram.y:489. $ diff -u p5.i p3.i --- p5.i 2023-07-22 00:22:30.748103516 +0200 +++ p3.i 2023-07-22 00:22:05.448298739 +0200 @@ -6424,7 +6424,7 @@ case 68: # 528 "cgram.y" { - if (!yystack.l_mark[0].y_type_qualifiers.tq_const) + if (!yystack.l_mark[0].y_seen_statement) yyerror("Bad attribute"); } # 1 "" $ gcc --version gcc (nb2 20230710) 10.5.0 $ uname -mp evbarm earmv7hfeb $ gcc -O2 -S p5.i -fverbose-asm $ gcc -O2 -S p3.i -fverbose-asm $ gcc -O2 -c p5.i $ gcc -O2 -c p3.i $ objdump -dr p5.o > p5.dis $ objdump -dr p3.o > p3.dis $ diff -u p5.dis p3.dis ... - ba8: e1b033a3 lsrs r3, r3, #7 + ba8: e3530000 cmp r3, #0 ... - 1010: e1b033a3 lsrs r3, r3, #7 + 1010: e3530000 cmp r3, #0 The code has changed in two places. Searching for the text "#7" in the p5.s file shows that the two places where the code has changed are in cgram.y:529 and cgram.y:489. I doubt that the code invokes undefined behavior, as it is fairly standard yacc code. Therefore I suspect a compiler error. Compiling the code with -Os or -O1 instead of -O2 does not show this behavior. Removing the ':1' from the members in struct type_qualifier does not show this behavior. Compiling the code on x86_64 or i386 does not show this behavior. ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c/110772] strange code generated for bit-field access 2023-07-21 23:26 [Bug c/110772] New: strange code generated for bit-field access roland.illig at gmx dot de @ 2023-07-21 23:27 ` roland.illig at gmx dot de 2023-07-21 23:53 ` [Bug target/110772] " pinskia at gcc dot gnu.org ` (6 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: roland.illig at gmx dot de @ 2023-07-21 23:27 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110772 --- Comment #1 from Roland Illig <roland.illig at gmx dot de> --- Created attachment 55599 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55599&action=edit precompiled code that works as intended ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug target/110772] strange code generated for bit-field access 2023-07-21 23:26 [Bug c/110772] New: strange code generated for bit-field access 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 ` pinskia at gcc dot gnu.org 2023-07-22 0:08 ` pinskia at gcc dot gnu.org ` (5 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: pinskia at gcc dot gnu.org @ 2023-07-21 23:53 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110772 --- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> --- I am trying to understand what you think is wrong here? lsrs r3, r3, #7 means logical shift right by 7 and compare against 0. Also this is big-endian arm so the order of bit fields will be different than little-endian. This is extracting one bit from the whole byte. x86 has an instruction (testb) which does the testing that way. arm does not. powerpc does not either. aarch64 has an instruction too. I don't see anything wrong with the code generation here at all. Take: ``` struct t { _Bool a0:1; _Bool a1:1; _Bool a2:1; _Bool a3:1; _Bool a4:1; _Bool a5:1; _Bool a6:1; _Bool a7:1; }; int g(); int h(); int f(struct t *a) { if(a->a0) return g(); return h(); } int f1(struct t *a) { if(a->a7) return g(); return h(); } int f2(_Bool *a) { if(*a) return g(); return h(); } ``` I don't see anything wrong with the above code generation for either arm or x86_64 (or powerpc). ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug target/110772] strange code generated for bit-field access 2023-07-21 23:26 [Bug c/110772] New: strange code generated for bit-field access 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 ` (4 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: pinskia at gcc dot gnu.org @ 2023-07-22 0:08 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110772 Andrew Pinski <pinskia at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- See Also| |https://gcc.gnu.org/bugzill | |a/show_bug.cgi?id=108498 --- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> --- Maybe PR 108498 .... ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug target/110772] strange code generated for bit-field access 2023-07-21 23:26 [Bug c/110772] New: strange code generated for bit-field access roland.illig at gmx dot de ` (2 preceding siblings ...) 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 ` (3 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: pinskia at gcc dot gnu.org @ 2023-07-22 0:11 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110772 --- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> --- Note 10.5.0 was the last release in the GCC 10.x series, can you test out GCC 11.4.0 out? ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug target/110772] strange code generated for bit-field access 2023-07-21 23:26 [Bug c/110772] New: strange code generated for bit-field access roland.illig at gmx dot de ` (3 preceding siblings ...) 2023-07-22 0:11 ` pinskia at gcc dot gnu.org @ 2023-07-22 15:21 ` roland.illig at gmx dot de 2023-07-22 15:23 ` roland.illig at gmx dot de ` (2 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: roland.illig at gmx dot de @ 2023-07-22 15:21 UTC (permalink / raw) To: gcc-bugs 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. ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug target/110772] strange code generated for bit-field access 2023-07-21 23:26 [Bug c/110772] New: strange code generated for bit-field access roland.illig at gmx dot de ` (4 preceding siblings ...) 2023-07-22 15:21 ` roland.illig at gmx dot de @ 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 7 siblings, 0 replies; 9+ messages in thread From: roland.illig at gmx dot de @ 2023-07-22 15:23 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110772 Roland Illig <roland.illig at gmx dot de> changed: What |Removed |Added ---------------------------------------------------------------------------- Attachment #55598|0 |1 is obsolete| | Attachment #55599|0 |1 is obsolete| | --- Comment #6 from Roland Illig <roland.illig at gmx dot de> --- Created attachment 55611 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55611&action=edit Precompiled source from comment 5 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug target/110772] strange code generated for bit-field access 2023-07-21 23:26 [Bug c/110772] New: strange code generated for bit-field access roland.illig at gmx dot de ` (5 preceding siblings ...) 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 7 siblings, 0 replies; 9+ messages in thread From: roland.illig at gmx dot de @ 2023-07-22 15:29 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110772 --- Comment #7 from Roland Illig <roland.illig at gmx dot de> --- Created attachment 55612 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55612&action=edit Preprocessed source from comment 5 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug target/110772] strange code generated for bit-field access 2023-07-21 23:26 [Bug c/110772] New: strange code generated for bit-field access roland.illig at gmx dot de ` (6 preceding siblings ...) 2023-07-22 15:29 ` roland.illig at gmx dot de @ 2023-07-22 15:50 ` roland.illig at gmx dot de 7 siblings, 0 replies; 9+ messages in thread From: roland.illig at gmx dot de @ 2023-07-22 15:50 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110772 --- Comment #8 from Roland Illig <roland.illig at gmx dot de> --- When I compile the attached code with "ARM GCC 10.5.0" and "-O2 -fPIE -ftrapv" on godbolt.org, the generated code is correct (you can search for "#327" in the output and then go back one branch). The code generated by godbolt.org "ARM GCC 11.4.0" with "-O2 -fPIE -ftrapv" looks good as well. So it could also be that the NetBSD version of GCC is missing a bug-fix or two. ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2023-07-22 15:50 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-07-21 23:26 [Bug c/110772] New: strange code generated for bit-field access 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 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
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).