#3147 closed defect (fixed)
gcc 4.9 generates bad code for longjmp in local scope
Reported by: | 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)
Change History (25)
comment:1 by , 10 years ago
comment:2 by , 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 , 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 , 10 years ago
comment:5 by , 10 years ago
comment:6 by , 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 , 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.
comment:8 by , 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 , 10 years ago
Attachment: | gcc-4.8.2.txt added |
---|
by , 10 years ago
Attachment: | gcc-4.9.2.txt added |
---|
comment:9 by , 10 years ago
Here is the optimization diff:
-
(a) gcc482_txt vs. (b) gcc492_txt
a b 1 GCC 4. 8.2 -O/O11 GCC 4.9.2 -O/O1 2 2 -fauto-inc-dec 3 3 -fcompare-elim 4 4 -fcprop-registers … … 31 31 -ftree-ter 32 32 -funit-at-a-time 33 33 -fomit-frame-pointer (maybe) 34 GCC 4. 8.2 -O234 GCC 4.9.2 -O2 35 35 -fthread-jumps 36 36 -falign-functions -falign-jumps 37 37 -falign-loops -falign-labels … … 39 39 -fcrossjumping 40 40 -fcse-follow-jumps -fcse-skip-blocks 41 41 -fdelete-null-pointer-checks 42 -fdevirtualize 42 -fdevirtualize -fdevirtualize-speculatively 43 43 -fexpensive-optimizations 44 44 -fgcse -fgcse-lm 45 45 -fhoist-adjacent-loads … … 46 46 -finline-small-functions 47 47 -findirect-inlining 48 48 -fipa-sra 49 -fisolate-erroneous-paths-dereference 49 50 -foptimize-sibling-calls 50 51 -fpartial-inlining 51 52 -fpeephole2 52 -fregmove53 53 -freorder-blocks -freorder-functions 54 54 -frerun-cse-after-loop 55 55 -fsched-interblock -fsched-spec
comment:10 by , 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 , 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 , 10 years ago
Attachment: | openmodelica-r24582-gcc4.9-flags.patch added |
---|
openmodelica-r24582-gcc4.9-flags.patch (does not fix the problem!)
comment:12 by , 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 , 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:15 by , 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 , 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:18 by , 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
10043 10043 then 'tmpMeta[<%System.tmpTickIndex(1)%>]' 10044 10044 else 10045 10045 let newVarIx = 'tmp<%System.tmpTick()%>' 10046 let &varDecls += ' <%ty%> <%newVarIx%>;<%\n%>'10046 let &varDecls += 'volatile <%ty%> <%newVarIx%>;<%\n%>' 10047 10047 newVarIx 10048 10048 newVar 10049 10049 end tempDecl;
comment:19 by , 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 , 10 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:21 by , 10 years ago
Component: | Unknown → Code Generation |
---|---|
Resolution: | → fixed |
Status: | assigned → closed |
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 , 10 years ago
Summary: | Fedora 21 x86_64: der() operator not allowed in function context → gcc 4.9 generates bad code for longjmp in local scope |
---|
Try compiling with clang on Fedora 21. GCC tends to perform unsafe optimizations.