Created attachment 1018412 [details] reproducer.sh Description of problem: GCC 5 miscompiles one object of libjvm.so (from the java-1.8.0-openjdk package) incorrectly. I've narrowed it down to type.o but I was yet unsuccessful to narrow it down further. For more background see bug 1208369. Version-Release number of selected component (if applicable): gcc-5.0.0-0.21.fc22.x86_64 How reproducible: 100% Steps to Reproduce: 1. Build a java-1.8.0-openjdk fast debug build using the attached spec file patch. I can provide srpm if needed. 1.1 $ fedpkg clone java-1.8.0-openjdk 1.2 $ fedpkg switch-branch f22 1.3 $ git checkout db2c528191c5b19dca09d6e234e6bdcedaebc1bb 1.4 $ git am 0001-spec-file-patch-for-GCC-reproducer.patch 1.5.$ fedpkg local 2. In directory java-1.8.0-openjdk/$NVR.$ARCH/jdk8/build/jdk8.build/hotspot/linux_amd64_compiler2/fastdebug all the *.o objects needed. 3. copy type.o.i into that dir 4. cd into java-1.8.0-openjdk/$NVR.$ARCH/jdk8/build/jdk8.build/hotspot/linux_amd64_compiler2/fastdebug 5. $ rm -f type.o && rm -f libjvm.so && /usr/bin/g++ -fPIC -fno-rtti -fno-exceptions -fcheck-new -fvisibility=hidden -m64 -pipe -fno-strict-aliasing -g -O3 -Werror -Wpointer-arith -Wsign-compare -Wundef -Wunused-function -Wunused-value -fstack-protector-strong -fno-devirtualize -Wno-return-local-addr -c -MMD -MP -MF ../generated/dependencies/type.o.d -fpch-deps -o type.o type.o.i && bash path/to/relink.sh 6. run reproducer.sh script which either asserts as in https://bugzilla.redhat.com/show_bug.cgi?id=1208369#c17 or runs fine 7. BUILD_DIR in reproducer.sh should be java-1.8.0-openjdk/$NVR.$ARCH/jdk8/build/jdk8.build/ Actual results: Miscompiled object with tree-vrp turned on. Expected results: Working type.o with tree-vrp turned on. Additional info: Compile attached pre-processed file type.o.i with and without tree-vrp turned on. The resulting type.o will assert in a fastdebug build of java-1.8.0-openjdk and run fine if turned off respectively. I'll be happy to help if you have trouble reproducing the issue.
Created attachment 1018413 [details] type.o.i (with some __attribute__ tries which I've added)
Created attachment 1018414 [details] 0001-spec-file-patch-for-GCC-reproducer.patch
Created attachment 1018415 [details] relink.sh
With all the optimize attributes you have in there this seems to have started with http://gcc.gnu.org/r219823 , but wonder if that isn't exactly because of the optimize attributes with that revision.
So, after removing all the __attribute__((optimize ("O0"))) stuff, I've bisected this to http://gcc.gnu.org/r215697 , which is indeed a VRP change and looking e.g. at vrp1 diffs, I see changes e.g. in TypeInt::xdual or TypeInt::make (i.e. functions that inline normalize_int_widen or normalize_long_widen). And, by adding noinline/noclone on both normalize_{int,long}_widen, and then optimize (0) on them selectively to find which one is the problem, I've came up with short reproducer: __attribute__((noinline, noclone)) int normalize_long_widen (long long lo, long long hi, int w) { if (lo <= hi) { if ((unsigned long long) (hi - lo) <= 3ULL) w = 0; if ((unsigned long long) (hi - lo) >= -1ULL) w = 3; } else { if ((unsigned long long) (lo - hi) <= 3ULL) w = 0; if ((unsigned long long) (lo - hi) >= -1ULL) w = 0; } return w; } int main () { __builtin_printf ("%d\n", normalize_long_widen (-__LONG_LONG_MAX__ - 1, __LONG_LONG_MAX__, 16)); return 0; } and that just seems that hotspot relies on undefined behavior, as LONG_LONG_MIN is smaller than LONG_LONG_MAX (thus lo <= hi is true), but hi - lo is undefined behavior. Guess you want something like (so that the subtraction is performed in unsigned type with well defined overflow): --- type.o.i~ 2015-04-24 14:17:08.000000000 +0200 +++ type.o.i 2015-04-24 17:07:08.258819716 +0200 @@ -129471,11 +129471,11 @@ static int normalize_int_widen( jint lo, if (lo <= hi) { - if ((juint)(hi - lo) <= ((juint)3)) w = Type::WidenMin; - if ((juint)(hi - lo) >= max_juint) w = Type::WidenMax; + if ((juint)hi - lo <= ((juint)3)) w = Type::WidenMin; + if ((juint)hi - lo >= max_juint) w = Type::WidenMax; } else { - if ((juint)(lo - hi) <= ((juint)3)) w = Type::WidenMin; - if ((juint)(lo - hi) >= max_juint) w = Type::WidenMin; + if ((juint)lo - hi <= ((juint)3)) w = Type::WidenMin; + if ((juint)lo - hi >= max_juint) w = Type::WidenMin; } return w; } @@ -129753,11 +129753,11 @@ static int normalize_long_widen( jlong l if (lo <= hi) { - if ((julong)(hi - lo) <= ((juint)3)) w = Type::WidenMin; - if ((julong)(hi - lo) >= max_julong) w = Type::WidenMax; + if ((julong)hi - lo <= ((juint)3)) w = Type::WidenMin; + if ((julong)hi - lo >= max_julong) w = Type::WidenMax; } else { - if ((julong)(lo - hi) <= ((juint)3)) w = Type::WidenMin; - if ((julong)(lo - hi) >= max_julong) w = Type::WidenMin; + if ((julong)lo - hi <= ((juint)3)) w = Type::WidenMin; + if ((julong)lo - hi >= max_julong) w = Type::WidenMin; } return w; } (of course applied to the source, not preprocessed source) as a fix. Or ((juint)hi - (juint)lo) instead of (juint)hi - lo, depends on the projects coding conventions... You could have tried -fsanitize=undefined first before filing bugs... (next time).
(In reply to Jakub Jelinek from comment #5) > You could have tried -fsanitize=undefined first before filing bugs... (next > time). Thank you very much for the analysis, Jakub. I'll certainly use -fsanitize=undefined next time before filing bugs. Thanks again!