public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug target/60580] New: aarch64 generates wrong code for __attribute__ ((optimize("no-omit-frame-pointer")))
@ 2014-03-19 8:37 chemobejk at gmail dot com
2014-03-19 12:41 ` [Bug target/60580] " jakub at gcc dot gnu.org
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: chemobejk at gmail dot com @ 2014-03-19 8:37 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60580
Bug ID: 60580
Summary: aarch64 generates wrong code for __attribute__
((optimize("no-omit-frame-pointer")))
Product: gcc
Version: 4.8.3
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: chemobejk at gmail dot com
Created attachment 32388
--> http://gcc.gnu.org/bugzilla/attachment.cgi?id=32388&action=edit
Example C code used i the command lines
We have a piece of code that we compile with -fomit-frame-pointer. The
exception is one low-level function that *MUST NOT* rely on the SP register,
i.e. that one function must be compiled with -fno-omit-frame-pointer. This
works fine with the GCC ARM backend, i.e. we have in the C code the following
function attribute:
/*
* This function calls XXX(), which modifies SP. This is incompatible to
* -fomit-frame-pointer generated code as SP is used to access the frame.
*/
__attribute__ ((optimize("no-omit-frame-pointer")))
void some_low_level_function(....)
We are now trying to compile that piece of code with the aarch64 backend and
get incorrect code that uses SP to access the frame. I tried with the following
pre-compiled aarch64 toolchains:
Linaro release 2014.02:
COLLECT_GCC=gcc-linaro-aarch64-linux-gnu-4.8-2014.02_linux/bin/aarch64-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/workarea/stefanb/playground/aarch64/gcc-linaro-aarch64-linux-gnu-4.8-2014.02_linux/bin/../libexec/gcc/aarch64-linux-gnu/4.8.3/lto-wrapper
Target: aarch64-linux-gnu
Configured with:
/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/.build/src/gcc-linaro-4.8-2014.02/configure
--build=i686-build_pc-linux-gnu --host=i686-build_pc-linux-gnu
--target=aarch64-linux-gnu
--prefix=/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/install
--with-sysroot=/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/install/aarch64-linux-gnu/libc
--enable-languages=c,c++,fortran --disable-multilib --enable-multiarch
--with-arch=armv8-a --with-pkgversion='crosstool-NG linaro-1.13.1-4.8-2014.02 -
Linaro GCC 2014.02' --with-bugurl=https://bugs.launchpad.net/gcc-linaro
--enable-__cxa_atexit --disable-libmudflap --enable-libgomp --disable-libssp
--with-gmp=/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/.build/aarch64-linux-gnu/build/static
--with-mpfr=/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/.build/aarch64-linux-gnu/build/static
--with-mpc=/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/.build/aarch64-linux-gnu/build/static
--with-isl=/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/.build/aarch64-linux-gnu/build/static
--with-cloog=/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/.build/aarch64-linux-gnu/build/static
--with-libelf=/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/.build/aarch64-linux-gnu/build/static
--enable-threads=posix --disable-libstdcxx-pch --enable-linker-build-id
--enable-plugin
--with-local-prefix=/cbuild/slaves/oorts/crosstool-ng/builds/aarch64-linux-gnu-linux/install/aarch64-linux-gnu/libc
--enable-c99 --enable-long-long
Thread model: posix
gcc version 4.8.3 20140203 (prerelease) (crosstool-NG linaro-1.13.1-4.8-2014.02
- Linaro GCC 2014.02)
Android AOSP:
COLLECT_GCC=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8/bin/aarch64-linux-android-gcc
COLLECT_LTO_WRAPPER=/workarea/stefanb/repos/tmake-only/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8/bin/../libexec/gcc/aarch64-linux-android/4.8/lto-wrapper
Target: aarch64-linux-android
Configured with: /tmp/AOSP-toolchain/build/../gcc/gcc-4.8/configure
--prefix=/tmp/toolchain-build-aarch64-linux-4.8/prefix
--target=aarch64-linux-android --host=x86_64-linux-gnu --build=x86_64-linux-gnu
--with-gnu-as --with-gnu-ld --enable-languages=c,c++
--with-gmp=/tmp/toolchain-build-aarch64-linux-4.8/temp-install
--with-mpfr=/tmp/toolchain-build-aarch64-linux-4.8/temp-install
--with-mpc=/tmp/toolchain-build-aarch64-linux-4.8/temp-install
--with-cloog=/tmp/toolchain-build-aarch64-linux-4.8/temp-install
--with-isl=/tmp/toolchain-build-aarch64-linux-4.8/temp-install
--with-ppl=/tmp/toolchain-build-aarch64-linux-4.8/temp-install
--disable-ppl-version-check --disable-cloog-version-check
--disable-isl-version-check --enable-cloog-backend=isl
--with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm'
--disable-libssp --enable-threads --disable-nls --disable-libmudflap
--disable-libgomp --disable-libstdc__-v3 --disable-sjlj-exceptions
--disable-shared --disable-tls --disable-libitm --enable-initfini-array
--disable-nls --prefix=/tmp/toolchain-build-aarch64-linux-4.8/prefix
--with-sysroot=/tmp/toolchain-build-aarch64-linux-4.8/prefix/sysroot
--with-binutils-version=2.23 --with-mpfr-version=3.1.1 --with-mpc-version=1.0.1
--with-gmp-version=5.0.5 --with-gcc-version=4.8 --with-gdb-version=7.6
--with-gxx-include-dir=/tmp/toolchain-build-aarch64-linux-4.8/prefix/include/c++/4.8
--with-bugurl=http://source.android.com/source/report-bugs.html
--disable-bootstrap --disable-libquadmath --enable-plugins --enable-libgomp
--disable-libsanitizer --enable-gold --enable-graphite=yes
--with-cloog-version=0.18.0 --with-isl-version=0.11.1
--enable-eh-frame-hdr-for-static --disable-gold --disable-libgomp
--program-transform-name='s&^&aarch64-linux-android-&'
Thread model: posix
gcc version 4.8 (GCC)
With the attached test.c I get the following assembler code for func2():
Case 1:
aarch64-linux-android-gcc -O0 -march=armv8-a -fno-omit-frame-pointer -S test.c
-o -
func2:
stp x29, x30, [sp, -32]!
add x29, sp, 0
str wzr, [x29,16]
bl func_no_leaf
ldp x29, x30, [sp], 32
ret
-> Correct code
Case 2:
aarch64-linux-android-gcc -O0 -march=armv8-a -fno-omit-frame-pointer
-DINCLUDE_ATTRIBUTE -S test.c -o -
func2:
sub sp, sp, #32
str x30, [sp]
str wzr, [sp,16]
bl func_no_leaf
ldr x30, [sp]
add sp, sp, 32
ret
-> WRONG BEHAVIOUR: adding the function attribute to the source code forces the
whole module code to be compiled with -fomit-frame-pointer!
Case 3:
aarch64-linux-android-gcc -O0 -march=armv8-a -fomit-frame-pointer
-DINCLUDE_ATTRIBUTE -S test.c -o -
func2:
sub sp, sp, #32
str x30, [sp]
str wzr, [sp,16]
bl func_no_leaf
ldr x30, [sp]
add sp, sp, 32
ret
-> WRONG BEHAVIOUR: although there is a function attribute for func2() the code
looks like case 2, instead of the correct code in case 1
Case 4:
aarch64-linux-android-gcc -O0 -march=armv8-a -fomit-frame-pointer
-mno-omit-leaf-frame-pointer -DINCLUDE_ATTRIBUTE -S test.c -o -
func2:
stp x29, x30, [sp, -32]!
add x29, sp, 0
str wzr, [x29,16]
bl func_no_leaf
ldp x29, x30, [sp], 32
ret
-> CORRECT: func2() uses frame pointer, all other code omits the frame pointer.
This is the workaround we currently have to use to get our code to work.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug target/60580] aarch64 generates wrong code for __attribute__ ((optimize("no-omit-frame-pointer")))
2014-03-19 8:37 [Bug target/60580] New: aarch64 generates wrong code for __attribute__ ((optimize("no-omit-frame-pointer"))) chemobejk at gmail dot com
@ 2014-03-19 12:41 ` jakub at gcc dot gnu.org
2014-03-20 23:55 ` ramana at gcc dot gnu.org
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: jakub at gcc dot gnu.org @ 2014-03-19 12:41 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60580
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jakub at gcc dot gnu.org,
| |jsm28 at gcc dot gnu.org,
| |uros at gcc dot gnu.org
--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
This is a complete mess, what aarch64 backend does is completely incompatible
with optimize attribute. I've tried to fix this up:
--- gcc/config/aarch64/aarch64.opt.jj 2014-01-20 14:50:22.000000000 +0100
+++ gcc/config/aarch64/aarch64.opt 2014-03-19 11:52:29.963772607 +0100
@@ -59,6 +59,11 @@ const char *aarch64_cpu_string
Variable
const char *aarch64_tune_string
+; Did we set flag_omit_frame_pointer just so aarch64_frame_pointer_required
+; would be called?
+Variable
+bool faked_omit_frame_pointer
+
mbig-endian
Target Report RejectNegative Mask(BIG_END)
Assume target CPU is configured as big endian
--- gcc/config/aarch64/aarch64.c.jj 2014-03-18 12:26:13.000000000 +0100
+++ gcc/config/aarch64/aarch64.c 2014-03-19 12:20:19.471504562 +0100
@@ -315,10 +315,6 @@ static GTY(()) int gty_dummy;
#define AARCH64_NUM_BITMASKS 5334
static unsigned HOST_WIDE_INT aarch64_bitmasks[AARCH64_NUM_BITMASKS];
-/* Did we set flag_omit_frame_pointer just so
- aarch64_frame_pointer_required would be called? */
-static bool faked_omit_frame_pointer;
-
typedef enum aarch64_cond_code
{
AARCH64_EQ = 0, AARCH64_NE, AARCH64_CS, AARCH64_CC, AARCH64_MI, AARCH64_PL,
@@ -5278,7 +5274,11 @@ aarch64_override_options (void)
static void
aarch64_override_options_after_change (void)
{
- faked_omit_frame_pointer = false;
+ if (global_options_set.x_flag_omit_frame_pointer)
+ {
+ faked_omit_frame_pointer = false;
+ global_options_set.x_faked_omit_frame_pointer = false;
+ }
/* To omit leaf frame pointers, we need to turn flag_omit_frame_pointer on
so
that aarch64_frame_pointer_required will be called. We need to remember
@@ -5288,6 +5288,9 @@ aarch64_override_options_after_change (v
{
flag_omit_frame_pointer = true;
faked_omit_frame_pointer = true;
+ global_options_set.x_faked_omit_frame_pointer
+ = global_options_set.x_flag_omit_frame_pointer;
+ global_options_set.x_flag_omit_frame_pointer = false;
}
}
but while that fixes some of the cases, it doesn't fix everything, the problem
is that the non-TargetVariable Variables aren't actually Saved.
Now, i386 backend seems to handle it differently, instead of adding a
faked_omit_frame_pointer variable (which, as this PR suggests would need to be
handled as an Optimization Saved variable, but supposedly the opts framework
doesn't allow it yet), it clears omit_leaf_frame_pointer flag if
flag_omit_frame_pointer is true:
/* Keep nonleaf frame pointers. */
if (opts->x_flag_omit_frame_pointer)
opts->x_target_flags &= ~MASK_OMIT_LEAF_FRAME_POINTER;
else if (TARGET_OMIT_LEAF_FRAME_POINTER_P (opts->x_target_flags))
opts->x_flag_omit_frame_pointer = 1;
but does that only in in override_options hook. That means that
say for -fomit-frame-pointer -momit-leaf-frame-pointer on the command line
supposedly that turns off TARGET_OMIT_LEAF_FRAME_POINTER and when some function
has __attribute__((optimize ("no-omit-frame-pointer"))) and is leaf, frame
pointer will not be omitted there. But for -fno-omit-frame-pointer
-momit-leaf-frame-pointer on the command line and __attribute__((optimize
("no-omit-frame-pointer"))) supposedly it will not have frame pointer if it is
leaf.
The primary issue is that flag_omit_frame_pointer is Optimization Save flag,
while omit-leaf-frame-pointer is typcially Target Save, the former optimize
attribute thing, the latter target attribute thing.
Not sure what is the best way out of this, but I guess doing in aarch64 what
i386 does would be significant progress.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug target/60580] aarch64 generates wrong code for __attribute__ ((optimize("no-omit-frame-pointer")))
2014-03-19 8:37 [Bug target/60580] New: aarch64 generates wrong code for __attribute__ ((optimize("no-omit-frame-pointer"))) chemobejk at gmail dot com
2014-03-19 12:41 ` [Bug target/60580] " jakub at gcc dot gnu.org
@ 2014-03-20 23:55 ` ramana at gcc dot gnu.org
2014-03-27 10:20 ` mshawcroft at gcc dot gnu.org
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: ramana at gcc dot gnu.org @ 2014-03-20 23:55 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60580
Ramana Radhakrishnan <ramana at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Last reconfirmed| |2014-03-20
CC| |ramana at gcc dot gnu.org
Ever confirmed|0 |1
--- Comment #4 from Ramana Radhakrishnan <ramana at gcc dot gnu.org> ---
Confirmed.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug target/60580] aarch64 generates wrong code for __attribute__ ((optimize("no-omit-frame-pointer")))
2014-03-19 8:37 [Bug target/60580] New: aarch64 generates wrong code for __attribute__ ((optimize("no-omit-frame-pointer"))) chemobejk at gmail dot com
2014-03-19 12:41 ` [Bug target/60580] " jakub at gcc dot gnu.org
2014-03-20 23:55 ` ramana at gcc dot gnu.org
@ 2014-03-27 10:20 ` mshawcroft at gcc dot gnu.org
2014-07-02 13:57 ` ktkachov at gcc dot gnu.org
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: mshawcroft at gcc dot gnu.org @ 2014-03-27 10:20 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60580
mshawcroft at gcc dot gnu.org changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |ASSIGNED
--- Comment #5 from mshawcroft at gcc dot gnu.org ---
Patch applied to trunk r208862
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug target/60580] aarch64 generates wrong code for __attribute__ ((optimize("no-omit-frame-pointer")))
2014-03-19 8:37 [Bug target/60580] New: aarch64 generates wrong code for __attribute__ ((optimize("no-omit-frame-pointer"))) chemobejk at gmail dot com
` (2 preceding siblings ...)
2014-03-27 10:20 ` mshawcroft at gcc dot gnu.org
@ 2014-07-02 13:57 ` ktkachov at gcc dot gnu.org
2014-11-14 11:39 ` jiwang at gcc dot gnu.org
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: ktkachov at gcc dot gnu.org @ 2014-07-02 13:57 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60580
ktkachov at gcc dot gnu.org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |ktkachov at gcc dot gnu.org
--- Comment #6 from ktkachov at gcc dot gnu.org ---
Marcus, can this be closed off?
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug target/60580] aarch64 generates wrong code for __attribute__ ((optimize("no-omit-frame-pointer")))
2014-03-19 8:37 [Bug target/60580] New: aarch64 generates wrong code for __attribute__ ((optimize("no-omit-frame-pointer"))) chemobejk at gmail dot com
` (3 preceding siblings ...)
2014-07-02 13:57 ` ktkachov at gcc dot gnu.org
@ 2014-11-14 11:39 ` jiwang at gcc dot gnu.org
2014-11-14 11:40 ` [Bug middle-end/60580] " jiwang at gcc dot gnu.org
2014-11-20 20:32 ` wdijkstr at arm dot com
6 siblings, 0 replies; 8+ messages in thread
From: jiwang at gcc dot gnu.org @ 2014-11-14 11:39 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60580
Jiong Wang <jiwang at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jiwang at gcc dot gnu.org
--- Comment #7 from Jiong Wang <jiwang at gcc dot gnu.org> ---
I'd take this for long term, hopefully could find a acceptable solution.
X86 is default with -fomit-frame-pointer which makes the logic a little bit
simpler, and thus X86 could survive in more normal case, but still fail in some
corner cases.
the fundamental problem is aarch64 and also x86 want to implement a finer
control of frame pointer which let leaf function be possible without setting up
frame record even under -fno-omit-frame-pointer. While gcc generic code is not
aware of that.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug middle-end/60580] aarch64 generates wrong code for __attribute__ ((optimize("no-omit-frame-pointer")))
2014-03-19 8:37 [Bug target/60580] New: aarch64 generates wrong code for __attribute__ ((optimize("no-omit-frame-pointer"))) chemobejk at gmail dot com
` (4 preceding siblings ...)
2014-11-14 11:39 ` jiwang at gcc dot gnu.org
@ 2014-11-14 11:40 ` jiwang at gcc dot gnu.org
2014-11-20 20:32 ` wdijkstr at arm dot com
6 siblings, 0 replies; 8+ messages in thread
From: jiwang at gcc dot gnu.org @ 2014-11-14 11:40 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60580
Jiong Wang <jiwang at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Priority|P3 |P4
Component|target |middle-end
Version|4.8.3 |5.0
Severity|normal |minor
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug middle-end/60580] aarch64 generates wrong code for __attribute__ ((optimize("no-omit-frame-pointer")))
2014-03-19 8:37 [Bug target/60580] New: aarch64 generates wrong code for __attribute__ ((optimize("no-omit-frame-pointer"))) chemobejk at gmail dot com
` (5 preceding siblings ...)
2014-11-14 11:40 ` [Bug middle-end/60580] " jiwang at gcc dot gnu.org
@ 2014-11-20 20:32 ` wdijkstr at arm dot com
6 siblings, 0 replies; 8+ messages in thread
From: wdijkstr at arm dot com @ 2014-11-20 20:32 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60580
Wilco <wdijkstr at arm dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |wdijkstr at arm dot com
--- Comment #8 from Wilco <wdijkstr at arm dot com> ---
(In reply to Jiong Wang from comment #7)
> I'd take this for long term, hopefully could find a acceptable solution.
>
> X86 is default with -fomit-frame-pointer which makes the logic a little bit
> simpler, and thus X86 could survive in more normal case, but still fail in
> some corner cases.
>
> the fundamental problem is aarch64 and also x86 want to implement a finer
> control of frame pointer which let leaf function be possible without setting
> up frame record even under -fno-omit-frame-pointer. While gcc generic code
> is not aware of that.
Besides the solutions we discussed on the list to fix the underlying issues in
the mid-end, a workaround may be possible in the backend. If we can guarantee a
callback is made to the backend at the end of compilation of each function,
then we can restore the original value of the omit-frame-pointer variable. This
means the options code will never see the fake value, and attributes will work
as expected.
In principle any callback would work as long as the frame pointer variable is
not used for that function again, and it happens before entering the options
code again.
Obviously this is a nasty hack, but at least it works.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2014-11-20 20:32 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-19 8:37 [Bug target/60580] New: aarch64 generates wrong code for __attribute__ ((optimize("no-omit-frame-pointer"))) chemobejk at gmail dot com
2014-03-19 12:41 ` [Bug target/60580] " jakub at gcc dot gnu.org
2014-03-20 23:55 ` ramana at gcc dot gnu.org
2014-03-27 10:20 ` mshawcroft at gcc dot gnu.org
2014-07-02 13:57 ` ktkachov at gcc dot gnu.org
2014-11-14 11:39 ` jiwang at gcc dot gnu.org
2014-11-14 11:40 ` [Bug middle-end/60580] " jiwang at gcc dot gnu.org
2014-11-20 20:32 ` wdijkstr at arm dot com
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).