Opened 10 years ago

Closed 10 years ago

Last modified 10 years ago

#3147 closed defect (fixed)

gcc 4.9 generates bad code for longjmp in local scope

Reported by: Stefan Hoelldampf <stefan.hoelldampf@…> Owned by: Martin Sjölund
Priority: high Milestone: 1.9.2
Component: Code Generation Version: trunk
Keywords: Cc:

Description

I have successfully compiled openmodelica-1.9.2-beta1 (r24355) on Fedora 20 x86_64,
the simulation of examples works fine.

On Fedora 21 x86_64 however, the der() operator causes problems, e.g.:

1 20:47:03 Translation Error
Error occurred while flattening model Modelica.Mechanics.Translational.Examples.SignConvention

2 20:47:03 Scripting Error
/var/tmp/openmodelica-1.9.2-beta1/lib/omlibrary/Modelica 3.2.1/Mechanics/Translational.mo: 1439:7-1439:17: The der() operator is not allowed in function context (possible solutions: pass the derivative as an explicit input; use a block instead of function).

Any hints? Diffing the console outputs of both compile runs does not give a pointer.

Some differences between Fedora 20 and Fedora 21, which I have seen so far:

Fedora 20: gcc-4.8.3, java-1.7.0-openjdk
Fedora 21: gcc-4.9.2, java-1.8.0-openjdk

In SimulationRuntime/c/util/java_interface, I had to update antlr-3.1.3.jar to antlr-complete-3.5.2.jar for Java 8, but this will be another ticket...

Attachments (3)

gcc-4.8.2.txt (1.8 KB ) - added by Adrian Pop 10 years ago.
gcc-4.9.2.txt (1.8 KB ) - added by Adrian Pop 10 years ago.
openmodelica-r24582-gcc4.9-flags.patch (475 bytes ) - added by Stefan Hoelldampf <stefan.hoelldampf@…> 10 years ago.
openmodelica-r24582-gcc4.9-flags.patch (does not fix the problem!)

Download all attachments as: .zip

Change History (25)

comment:1 by Martin Sjölund, 10 years ago

Try compiling with clang on Fedora 21. GCC tends to perform unsafe optimizations.

comment:2 by Gustaf Thorslund, 10 years ago

I had same issue on Debian Jessie x86_64 with GCC 4.9.1 (Debian 4.9.1-19) and omc 1.9.2+dev (r24510) from subversion. A minimal test case from http://book.xogeny.com/behavior/equations/first_order/:

class FirstOrder
  Real x;
equation
  der(x) = 1.0 - x;
end FirstOrder;

For me changing to clang seems to fix the issue.

comment:3 by Adrian Pop, 10 years ago

Can you check without revision r24497?
https://trac.openmodelica.org/OpenModelica/changeset/24497

I mean revert this revision and check if this problem still persists with GCC 4.9.1.
Unfortunately we don't have access to GCC 4.9.1 to check this.

comment:4 by Stefan Hoelldampf <stefan.hoelldampf@…>, 10 years ago

On Fedora 21 with GCC, I just tried r24535 with and without r24497 applied, the problem remains in both cases. The GCC RPM system package is "gcc-4.9.2-1.fc21.x86_64".

clang will be the next try...

comment:5 by Gustaf Thorslund, 10 years ago

Removing r24497 didn't help for me either. I've also tried earlier versions and the not so exciting result is that the first version where the bug appears when using GCC 4.9.1 on Debian testing/Jessie/8.0 is r24289. The same commit including the additional check and error message.

comment:6 by Martin Sjölund, 10 years ago

That's weird. Because according to the GCC 4.9 tests we added, gcc-4.9 does not only fail with this message but some other ones equally surprising.

comment:7 by Gustaf Thorslund, 10 years ago

Well, this was the only test I tried with the various versions. I suppose running more tests could result in more failures. If you like doing brain surgery with a blindfold, you might got some mud to dive into now.

Last edited 10 years ago by Gustaf Thorslund (previous) (diff)

comment:8 by Adrian Pop, 10 years ago

I just tried with GCC 4.9.2 and -g instead of -O2 and all tests pass:
https://test.openmodelica.org/hudson/job/OpenModelica_TEST_GCC_4.9/

I will play with the optimization flags a bit and see if i can find
out which one is to blame. I'm searching now for GCC 4.9.2 changes
compared to 4.8.2 so I can see if there are new optimizations included
in -O2.

by Adrian Pop, 10 years ago

Attachment: gcc-4.8.2.txt added

by Adrian Pop, 10 years ago

Attachment: gcc-4.9.2.txt added

comment:9 by Adrian Pop, 10 years ago

Here is the optimization diff:

  • (a) gcc482_txt vs. (b) gcc492_txt

    a b  
    1 GCC 4.8.2 -O/O1
     1GCC 4.9.2 -O/O1
    22          -fauto-inc-dec
    33          -fcompare-elim
    44          -fcprop-registers
     
    3131          -ftree-ter
    3232          -funit-at-a-time
    3333          -fomit-frame-pointer (maybe)
    34 GCC 4.8.2 -O2
     34GCC 4.9.2 -O2
    3535          -fthread-jumps
    3636          -falign-functions  -falign-jumps
    3737          -falign-loops  -falign-labels
     
    3939          -fcrossjumping
    4040          -fcse-follow-jumps  -fcse-skip-blocks
    4141          -fdelete-null-pointer-checks
    42           -fdevirtualize
     42          -fdevirtualize -fdevirtualize-speculatively
    4343          -fexpensive-optimizations
    4444          -fgcse  -fgcse-lm 
    4545          -fhoist-adjacent-loads
     
    4646          -finline-small-functions
    4747          -findirect-inlining
    4848          -fipa-sra
     49          -fisolate-erroneous-paths-dereference
    4950          -foptimize-sibling-calls
    5051          -fpartial-inlining
    5152          -fpeephole2
    52           -fregmove
    5353          -freorder-blocks  -freorder-functions
    5454          -frerun-cse-after-loop 
    5555          -fsched-interblock  -fsched-spec

comment:10 by Adrian Pop, 10 years ago

Even with -O1 it has issues. It seems that some of the optimizations in -O1 are bad for us.

comment:11 by Stefan Hoelldampf <stefan.hoelldampf@…>, 10 years ago

Passing
CFLAGS="-fno-tree-bit-ccp"
to the configure script solves the problem for r24582 on Fedora 21 (gcc-4.9.2-1.fc21.x86_64).

I also tried to extend the existing flag detection for GCC 4.8 in configure.in, but the attached patch does not fix the problem. Perhaps the environment variable CFLAGS is used somewhere else not covered by the flag detection magic...

by Stefan Hoelldampf <stefan.hoelldampf@…>, 10 years ago

openmodelica-r24582-gcc4.9-flags.patch (does not fix the problem!)

comment:12 by Martin Sjölund, 10 years ago

If you pass CFLAGS="-fno-tree-bit-cpp", you will automatically use -O0, right? So it probably means it is not the interesting flag.

comment:13 by Martin Sjölund, 10 years ago

I will try:

echo "Finding result" > log
for flag in \
 -fauto-inc-dec -fcompare-elim -fcprop-registers -fdce -fdefer-pop -fdelayed-branch -fdse -fguess-branch-probability -fif-conversion2 -fif-conversion -fipa-pure-const -fipa-profile -fipa-reference -fmerge-constants -fsplit-wide-types -ftree-bit-ccp -ftree-builtin-call-dce -ftree-ccp -ftree-ch -ftree-copyrename -ftree-dce -ftree-dominator-opts -ftree-dse -ftree-forwprop -ftree-fre -ftree-phiprop -ftree-slsr -ftree-sra -ftree-pta -ftree-ter -funit-at-a-time \
 -fthread-jumps -falign-functions -falign-jumps -falign-loops -falign-labels -fcaller-saves -fcrossjumping -fcse-follow-jumps -fcse-skip-blocks -fdelete-null-pointer-checks -fdevirtualize -fdevirtualize-speculatively -fexpensive-optimizations -fgcse -fgcse-lm -fhoist-adjacent-loads -finline-small-functions -findirect-inlining -fipa-sra -fisolate-erroneous-paths-dereference -foptimize-sibling-calls -fpartial-inlining -fpeephole2 -freorder-blocks -freorder-functions -frerun-cse-after-loop -fsched-interblock -fsched-spec -fschedule-insns -fschedule-insns2 -fstrict-aliasing -fstrict-overflow -ftree-switch-conversion -ftree-tail-merge -ftree-pre -ftree-vrp \
 -finline-functions -funswitch-loops -fpredictive-commoning -fgcse-after-reload -ftree-loop-vectorize -ftree-slp-vectorize -fvect-cost-model -ftree-partial-pre -fipa-cp-clone
do
 echo $flag
 ./configure "CFLAGS=$flag" 'CC=gcc-4.9' 'CXX=g++-4.9' 'OMPCC=gcc-4.9 -fopenmp' '--disable-modelica3d' '--with-omniORB' '--with-omc=/usr/bin/omc'
 make -j40 clean
 if make -j40 sanity-check; then
 echo "$flag OK" >> log
 else
 echo "$flag FAILED" >> log
 fi
done

comment:14 by Martin Sjölund, 10 years ago

All of the flags succeeded. So it is some combination of flags? :(

comment:15 by Gustaf Thorslund, 10 years ago

I did some less successful flag testing last night. To get the difference between -O0 (the one working) and -O1 (the first one failing) I used:

  diff -u <(gcc -Q --help=optimizers -O0) <(gcc -Q --help=optimizers -O1) |\
  grep "^+ " | cut -d" " -f3

-fbranch-count-reg
-fcombine-stack-adjustments
-fcompare-elim
-fcprop-registers
-fdefer-pop
-fforward-propagate
-fguess-branch-probability
-fif-conversion
-fif-conversion2
-finline-functions-called-once
-fipa-profile
-fipa-pure-const
-fipa-reference
-fmerge-constants
-fmove-loop-invariants
-fshrink-wrap
-fsplit-wide-types
-ftree-bit-ccp
-ftree-ccp
-ftree-ch
-ftree-copy-prop
-ftree-copyrename
-ftree-dce
-ftree-dominator-opts
-ftree-dse
-ftree-fre
-ftree-pta
-ftree-sink
-ftree-slsr
-ftree-sra
-ftree-ter

I grouped them into three groups and compiled with CFLAGS="-O0 $(cat group-$i)", but none of them failed. Then I tried adding all flags, so compiling with:

CFLAGS="-O0 -fbranch-count-reg -fcombine-stack-adjustments -fcompare-elim -fcprop-registers -fdefer-pop -fforward-propagate -fguess-branch-probability -fif-conversion -fif-conversion2 -finline-functions-called-once -fipa-profile -fipa-pure-const -fipa-reference -fmerge-constants -fmove-loop-invariants -fshrink-wrap -fsplit-wide-types -ftree-bit-ccp -ftree-ccp -ftree-ch -ftree-copy-prop -ftree-copyrename -ftree-dce -ftree-dominator-opts -ftree-dse -ftree-fre -ftree-pta -ftree-sink -ftree-slsr -ftree-sra -ftree-ter "

But that one didn't fail the test either. Maybe it would be worth removing one flag at the time from -O1 or -O2, instead of just trying all flags one at the time.

comment:16 by Martin Sjölund, 10 years ago

I have a possible fix in the works (replacing MMC_THROW_INTERNAL longjmp'ing to the local function with goto). It seemed to work for the simple testcase; running the testsuite now.

comment:17 by Martin Sjölund, 10 years ago

Try r24585

comment:18 by Adrian Pop, 10 years ago

If not, this will definitely fix it properly (and is just a bit slower), but I will make a version that has some ifdefs based on compiler versions:

  • Compiler/Template/CodegenC.tpl

     
    1004310043        then 'tmpMeta[<%System.tmpTickIndex(1)%>]'
    1004410044      else
    1004510045        let newVarIx = 'tmp<%System.tmpTick()%>'
    10046         let &varDecls += '<%ty%> <%newVarIx%>;<%\n%>'
     10046        let &varDecls += 'volatile <%ty%> <%newVarIx%>;<%\n%>'
    1004710047        newVarIx
    1004810048  newVar
    1004910049end tempDecl;

comment:19 by Stefan Hoelldampf <stefan.hoelldampf@…>, 10 years ago

Thanks, r24585 works on Fedora 21 (gcc-4.9.2-1.fc21.x86_64) without additional patches and without CFLAGS being set.

I did some more testing regarding CFLAGS and r24584, the following "no" flags also fix the problem:

CFLAGS="-g -O2 -fno-if-conversion -fno-if-conversion2"
("-g -O2" mimics the default CFLAGS)

comment:20 by Martin Sjölund, 10 years ago

Owner: changed from somebody to Martin Sjölund
Status: newassigned

comment:21 by Martin Sjölund, 10 years ago

Component: UnknownCode Generation
Resolution: fixed
Status: assignedclosed

Thanks everyone who helped try to find out what went wrong. We have a bit smarter code generation now. We could get some additional performance improvements with a better IR (fewer setjmp/longjmp). But at least the code is more correct now than before.

comment:22 by Martin Sjölund, 10 years ago

Summary: Fedora 21 x86_64: der() operator not allowed in function contextgcc 4.9 generates bad code for longjmp in local scope
Note: See TracTickets for help on using tickets.