[Bug c++/23539] New: C & C++ compiler generating misaligned references regardless of compiler flags
mcvick_e at iname dot com
gcc-bugzilla@gcc.gnu.org
Tue Aug 23 21:23:00 GMT 2005
This issue was uncovered in porting our existing software to the GNU tool-
chain. We have a number of structures that contain 3 individual bytes of
data. When the GNU tool-chain compiles the source code, it creates a
load/store byte instruction followed by a load/store half-word instruction with
an odd (1,3,5,7,9,11,etc) memory offset. This causes a data alignment
exception to occur.
We have tried all combinations of the compiler flags for structure packing,
alignment (natural, power), and anything else that we have been able to uncover
in the GCC documentation.
This behavior exists at optimization levels, 0,1 and 2. We haven't tried any
other levels as of yet.
There should be a means of having the compiler override mis-aligned address
references. This is supported at a software level (if the authors of the OS or
software handle this exception). However, the authors of this component did
not, and it would cause far too much of a runtime hit to implement this. A
code sample is included below that will re-create this problem.
---- File test.cc -----
struct foo {
char bar1;
char bar2;
char bar3;
};
int foobarStruct(foo fubarStruct) {
if(fubarStruct.bar1 == 'A' &&
fubarStruct.bar2 == 'B' &&
fubarStruct.bar3 == 'C')
{
return 1;
}
else {
return 0;
}
}
int main(int argc, char **argv) {
int rVal1;
int rVal2;
foo barStruct;
barStruct.bar1 = 'A';
barStruct.bar2 = 'B';
barStruct.bar3 = 'C';
rVal1 = foobarStruct(barStruct);
barStruct.bar1 = 'A';
barStruct.bar2 = 'C';
barStruct.bar3 = 'B';
rVal1 = foobarStruct(barStruct);
return (rVal1 || rVal2);
}
------------- End of file ---------------------
Again using any combinations of compiler flags -malign-natural, -malign-power, -
fpack-struct=2, -fno-pack-struct, etc have not given us the desired behavior.
Here's the assembly output from the command(s):
(1)> g++ test.cc -o test
(2)> ppcobjdump -C -S test.o
test.o: file format elf32-powerpc
Disassembly of section .text:
00000000 <foobarStruct(foo)>:
0: 94 21 ff e8 stwu r1,-24(r1)
4: 93 e1 00 14 stw r31,20(r1)
8: 7c 3f 0b 78 mr r31,r1
c: 90 7f 00 0c stw r3,12(r31)
10: 81 3f 00 0c lwz r9,12(r31)
14: 88 09 00 00 lbz r0,0(r9)
18: 54 00 06 3e clrlwi r0,r0,24
1c: 2f 80 00 41 cmpwi cr7,r0,65
20: 40 9e 00 38 bne- cr7,58 <foobarStruct(foo)+0x58>
24: 81 3f 00 0c lwz r9,12(r31)
28: 88 09 00 01 lbz r0,1(r9)
2c: 54 00 06 3e clrlwi r0,r0,24
30: 2f 80 00 42 cmpwi cr7,r0,66
34: 40 9e 00 24 bne- cr7,58 <foobarStruct(foo)+0x58>
38: 81 3f 00 0c lwz r9,12(r31)
3c: 88 09 00 02 lbz r0,2(r9)
40: 54 00 06 3e clrlwi r0,r0,24
44: 2f 80 00 43 cmpwi cr7,r0,67
48: 40 9e 00 10 bne- cr7,58 <foobarStruct(foo)+0x58>
4c: 38 00 00 01 li r0,1
50: 90 1f 00 08 stw r0,8(r31)
54: 48 00 00 0c b 60 <foobarStruct(foo)+0x60>
58: 39 20 00 00 li r9,0
5c: 91 3f 00 08 stw r9,8(r31)
60: 80 1f 00 08 lwz r0,8(r31)
64: 7c 03 03 78 mr r3,r0
68: 81 61 00 00 lwz r11,0(r1)
6c: 83 eb ff fc lwz r31,-4(r11)
70: 7d 61 5b 78 mr r1,r11
74: 4e 80 00 20 blr
00000078 <main>:
78: 94 21 ff a8 stwu r1,-88(r1)
7c: 7c 08 02 a6 mflr r0
80: 93 e1 00 54 stw r31,84(r1)
84: 90 01 00 5c stw r0,92(r1)
88: 7c 3f 0b 78 mr r31,r1
8c: 90 7f 00 28 stw r3,40(r31)
90: 90 9f 00 2c stw r4,44(r31)
94: 48 00 00 01 bl 94 <main+0x1c>
98: 38 00 00 41 li r0,65
9c: 98 1f 00 16 stb r0,22(r31)
a0: 38 00 00 42 li r0,66
a4: 98 1f 00 17 stb r0,23(r31)
a8: 38 00 00 43 li r0,67
ac: 98 1f 00 18 stb r0,24(r31)
b0: 88 1f 00 16 lbz r0,22(r31)
b4: a1 3f 00 17 lhz r9,23(r31) <-- Notice the odd offset
b8: 98 1f 00 13 stb r0,19(r31)
bc: b1 3f 00 14 sth r9,20(r31)
c0: 88 1f 00 13 lbz r0,19(r31)
c4: a1 3f 00 14 lhz r9,20(r31)
c8: 98 1f 00 30 stb r0,48(r31)
cc: b1 3f 00 31 sth r9,49(r31) <-- Notice the off offset
d0: 38 1f 00 30 addi r0,r31,48
d4: 7c 03 03 78 mr r3,r0
d8: 48 00 00 01 bl d8 <main+0x60>
dc: 7c 60 1b 78 mr r0,r3
e0: 90 1f 00 0c stw r0,12(r31)
e4: 38 00 00 41 li r0,65
e8: 98 1f 00 16 stb r0,22(r31)
ec: 38 00 00 43 li r0,67
f0: 98 1f 00 17 stb r0,23(r31)
f4: 38 00 00 42 li r0,66
f8: 98 1f 00 18 stb r0,24(r31)
fc: 88 1f 00 16 lbz r0,22(r31)
100: a1 3f 00 17 lhz r9,23(r31) <-- Again odd offsets
104: 98 1f 00 10 stb r0,16(r31)
108: b1 3f 00 11 sth r9,17(r31) <-- Again odd offsets
10c: 88 1f 00 10 lbz r0,16(r31)
110: a1 3f 00 11 lhz r9,17(r31)
114: 98 1f 00 30 stb r0,48(r31)
118: b1 3f 00 31 sth r9,49(r31)
11c: 38 1f 00 30 addi r0,r31,48
120: 7c 03 03 78 mr r3,r0
124: 48 00 00 01 bl 124 <main+0xac>
128: 7c 60 1b 78 mr r0,r3
12c: 90 1f 00 0c stw r0,12(r31)
130: 80 1f 00 0c lwz r0,12(r31)
134: 2f 80 00 00 cmpwi cr7,r0,0
138: 40 9e 00 10 bne- cr7,148 <main+0xd0>
13c: 80 1f 00 08 lwz r0,8(r31)
140: 2f 80 00 00 cmpwi cr7,r0,0
144: 41 9e 00 10 beq- cr7,154 <main+0xdc>
148: 38 00 00 01 li r0,1
14c: 90 1f 00 40 stw r0,64(r31)
150: 48 00 00 0c b 15c <main+0xe4>
154: 38 00 00 00 li r0,0
158: 90 1f 00 40 stw r0,64(r31)
15c: 80 1f 00 40 lwz r0,64(r31)
160: 7c 03 03 78 mr r3,r0
164: 81 61 00 00 lwz r11,0(r1)
168: 80 0b 00 04 lwz r0,4(r11)
16c: 7c 08 03 a6 mtlr r0
170: 83 eb ff fc lwz r31,-4(r11)
174: 7d 61 5b 78 mr r1,r11
178: 4e 80 00 20 blr
>From Section 3.3.1 Alignment and Misaligned Accesses
The operand of a single-register memory access instruction has a natural
alignment boundary equal to the operand length. The "natural" address of an
operand is an integral multiple of the operand length, ......
I can understand what the compiler is trying to achieve here in the sense of
doing two loads/stores versus three, however it is performing misaligned
loads/stores as a result. This optimization actually becomes a performance hit
if the underlying system is forced to perform the exception handling and piece
the parts together.
Perhaps it's not a "real" bug, however not being able to override this behavior
probably is.
This behavior has been observed in 4.0.1, 4.0.0, 3.4.4 and 3.3.1
--
Summary: C & C++ compiler generating misaligned references
regardless of compiler flags
Product: gcc
Version: 4.0.1
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: mcvick_e at iname dot com
CC: gcc-bugs at gcc dot gnu dot org
GCC build triplet: i686-pc-linux-gnu
GCC host triplet: i686-pc-linux-gnu
GCC target triplet: powerpc-eabi
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23539
More information about the Gcc-bugs
mailing list