arm-linux-gnueabihf-gcc 4.8.2 produces wrong code when optimizing a function-pointer tail call when calling from softfp to hard fp ABI
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
gcc-4.8-armhf-cross (Ubuntu) |
Confirmed
|
Undecided
|
Unassigned |
Bug Description
Hi,
gcc used to perform the appropriate conversions for software using softfp that linked against software using hard fp ABI in ARM, using version 4.6.3 (the one found in precise), but version 4.8.2 (trusty) yields weird results from indirect functions that return a floating-point value.
Calling the function directly, yields the expected result.
As an example (complete code attached), these functions would stand for the hard fp ABI:
---------
struct Test {
__attribute_
};
__attribute_
const struct Test* GetTest();
---------
Using these wrappers for the softfp:
---------
float wrapper() {
return GetTest()->f();
}
float wrapper_correct() {
return f();
}
---------
The first one, that calls the function indirectly, yields incorrect assembler (dissasembly from wrapper.a):
00000000 <_Z7wrapperv>:
0: e52d4008 str r4, [sp, #-8]!
4: e58de004 str lr, [sp, #4]
8: ebfffffe bl 0 <GetTest>
c: e5903000 ldr r3, [r0]
10: e59d4000 ldr r4, [sp]
14: e59de004 ldr lr, [sp, #4]
18: e28dd008 add sp, sp, #8
1c: e12fff13 bx r3 // not populating r0
While the second one yields correct assembler:
00000020 <_Z15wrapper_
20: e52d4008 str r4, [sp, #-8]!
24: e58de004 str lr, [sp, #4]
28: ebfffffe bl 0 <f>
2c: e59d4000 ldr r4, [sp]
30: e28dd004 add sp, sp, #4
34: ee100a10 vmov r0, s0 // populating r0
38: e49df004 pop {pc} ; (ldr pc, [sp], #4)
For comparison, these are the dissasemblies of both functions when compiled with 4.6.3 (precise):
00000000 <_Z7wrapperv>:
0: e92d4008 push {r3, lr}
4: ebfffffe bl 0 <GetTest>
8: e5903000 ldr r3, [r0]
c: e12fff33 blx r3
10: ee100a10 vmov r0, s0
14: e8bd8008 pop {r3, pc}
00000018 <_Z15wrapper_
18: e92d4008 push {r3, lr}
1c: ebfffffe bl 0 <f>
20: ee100a10 vmov r0, s0
24: e8bd8008 pop {r3, pc}
Status changed to 'Confirmed' because the bug affects multiple users.