[Bug middle-end/71700] New: [4.9/5/6/7 Regression] wrong code with struct assignment with sub-word signed bitfields
ktkachov at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Jun 29 15:26:00 GMT 2016
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71700
Bug ID: 71700
Summary: [4.9/5/6/7 Regression] wrong code with struct
assignment with sub-word signed bitfields
Product: gcc
Version: 7.0
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: ktkachov at gcc dot gnu.org
Target Milestone: ---
Target: arm
The testcase below fails:
struct S {
signed f0 : 16;
unsigned f1 : 1;
};
int b;
static struct S c[] = { { -1, 0 }, { -1, 0 } };
struct S d;
int main() {
struct S e = c[0];
d = e;
if (d.f1 != 0)
__builtin_abort ();
return 0;
}
on arm targets with optimisation. At -O0 it doesn't abort.
The wrong code is at statement:
struct S e = c[0];
The constructor initialisation RTL emitted is:
;; e = c[0];
(insn 5 4 6 (set (reg/v:SI 112 [ e ])
(const_int 0 [0]))
(nil))
(insn 6 5 7 (set (reg/v:SI 112 [ e ])
(const_int -1 [0xffffffffffffffff]))
(nil))
The second SET clobbers the whole word rather than just the 16 bits it was
supposed to. The problem is in store_constructor in expr.c where it widens the
first store to word mode by sign-extending the value but then tries to avoid
storing the zero bitfield because it had initially cleared out the word (the
first set).
This testcase works for me for GCC 4.8.5 but fails on 4.9 and later
More information about the Gcc-bugs
mailing list