This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/70672] New: [5] Wrong code for little endian bitfield modification
- From: "wschmidt at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 14 Apr 2016 20:27:21 +0000
- Subject: [Bug target/70672] New: [5] Wrong code for little endian bitfield modification
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70672
Bug ID: 70672
Summary: [5] Wrong code for little endian bitfield modification
Product: gcc
Version: 5.3.1
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: wschmidt at gcc dot gnu.org
CC: dje at gcc dot gnu.org, segher at gcc dot gnu.org
Target Milestone: ---
Target: powerpc64le-unknown-linux-gnu
The following code compiled with -O2 with GCC 5.3 produces incorrect code.
Correct code is generated for current trunk.
typedef unsigned long long CoreUInt64;
typedef unsigned int CoreUInt32;
CoreUInt64 shift4BtUp(CoreUInt64 a)
{
struct Int32S
{
CoreUInt32 highTop;
CoreUInt32 lowTop;
};
union
{
struct Int32S _32store;
CoreUInt64 _64store;
} x;
x._64store = a;
x._32store.lowTop = x._32store.highTop;
x._32store.highTop = 0;
return x._64store;
}
The correct code is a 32-bit left shift on little endian, and indeed trunk
produces sldi 3,3,32 as expected. But on 5.3 we get rldicr 3,3,0,31.
After expand:
;; x._64store = a_2(D);
(insn 6 5 0 (set (reg/v:DI 125 [ x ])
(reg/v:DI 127 [ a ])) sap.c:19 -1
(nil))
;; x._32store.lowTop = _4;
(insn 7 6 0 (set (zero_extract:DI (reg/v:DI 125 [ x ])
(const_int 32 [0x20])
(const_int 0 [0]))
(reg/v:DI 125 [ x ])) sap.c:21 -1
(nil))
;; x._32store.highTop = 0;
(insn 8 7 9 (set (reg:DI 128)
(const_int 0 [0])) sap.c:22 -1
(nil))
(insn 9 8 0 (set (zero_extract:DI (reg/v:DI 125 [ x ])
(const_int 32 [0x20])
(const_int 32 [0x20]))
(reg:DI 128)) sap.c:22 -1
(nil))
;; _7 = x._64store;
(insn 10 9 0 (set (reg:DI 124 [ D.2241 ])
(reg/v:DI 125 [ x ])) sap.c:24 -1
(nil))
This is correct. But then, following the first jump optimization pass, insn 7
is incorrectly removed.
I bisected the fix on trunk to r226005, in which Segher did a complete rewrite
of much of the rotate code. Unfortunately this is a relatively large patch, so
it isn't immediately obvious where the original problem was. There must have
been a hidden endianness assumption in there somewhere.
If it's acceptable, it would be nice to backport the whole patch, but I am not
sure whether there were follow-on patches to deal with any fallout. Certainly
this has had a lot of burn-in time by now.
Segher, can you please advise? Do you recall seeing a bug like this when you
were working on this last year?