Current mainline gfortran fails to build four SPEC CPU2000 tests on powerpc64-linux using "-m64 -O2 -ffast-math -funroll-loops". In a call to is_gimple_stmt it tries to dereference a pointer that the garbage collector has poisoned. This reduced test case (which can undoubtedly be made smaller) demonstrates the problem using --param gcc-min-heapsize=1 for powerpc-linux: subroutine foo implicit real*8 (a-h,o-z) real u(5,60,60,60) do i = 2, nx-1 x = dble(i-1) / (nx-1) do m = 1, 5 px = (1.0d+00 - x) * u(m,1,j,k) + x * u(m,nx,j,k) pz = (1.0d+00 - z) * u(m,i,j,l) + z * u(m,i,j,nz) u(m,i,j,k) = px + p + pz end do end do return end elm3b11% /opt/gcc-nightly/mline/bin/gfortran -c -m64 -O2 -ffast-math -funroll-loops --param ggc-min-heapsize=1 bug.f bug.f: In function ‘foo’: bug.f:1: internal compiler error: Segmentation fault elm3b11% /opt/gcc-nightly/mline/bin/gfortran -c -m32 -O2 -ffast-math --param ggc-min-heapsize=1 bug.f bug.f: In function ‘foo’: bug.f:1: internal compiler error: Segmentation fault The failure begins with this patch from dje: http://gcc.gnu.org/ml/gcc-cvs/2005-04/msg00598.html
Here is a testcase which removes the use of uninitialized variables and still crashes: subroutine foo(z, nx,j,k,l,nz) implicit real*8 (a-h,o-z) real u(5,60,60,60) do i = 2, nx-1 x = dble(i) / (nx) do m = 1, 5 u(m,i,j,k) = x * u(m,1,j,k) + z * u(m,i,j,nz) + u(m,i,j,l) end do end do return end
Here is a reduced testcase with the additional option of --param ggc-min-expand=0 which forces collection all the time: subroutine foo( nx,j,dble) implicit none integer i,j,nx real*8 x,dble(nx) real u(5,60,60) do i = 2, nx-1 x = dble(i) / (nx) u(2,i,j) = x end do return end
Applying the following patch causes the ICE to be seen earlier: Index: tree-ssa-loop-im.c =============================================================== ==== RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop-im.c,v retrieving revision 2.36 diff -u -p -r2.36 tree-ssa-loop-im.c --- tree-ssa-loop-im.c 11 Apr 2005 20:17:38 -0000 2.36 +++ tree-ssa-loop-im.c 15 Apr 2005 20:45:58 -0000 @@ -38,6 +38,7 @@ Software Foundation, 59 Temple Place - S #include "tree-pass.h" #include "flags.h" #include "real.h" +#include "ggc.h" /* TODO: Support for predicated code motion. I.e. @@ -622,9 +623,10 @@ determine_invariantness_stmt (struct dom The multiply stmt is not invariant, so update iterator and avoid rescanning. */ bsi_replace (&bsi, stmt1, true); - get_stmt_operands (stmt1); /* Should not be necessary. */ bsi_insert_after (&bsi, stmt2, BSI_NEW_STMT); SSA_NAME_DEF_STMT (lhs) = stmt2; + ggc_collect (); + verify_ssa (true); /* Continue processing with invariant reciprocal statment. */ stmt = stmt1; I think we are missing an update use.
I am testing the following patch: Index: tree-ssa-loop-im.c =============================================================== ==== RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop-im.c,v retrieving revision 2.36 diff -u -p -r2.36 tree-ssa-loop-im.c --- tree-ssa-loop-im.c 11 Apr 2005 20:17:38 -0000 2.36 +++ tree-ssa-loop-im.c 15 Apr 2005 21:10:37 -0000 @@ -38,6 +38,7 @@ Software Foundation, 59 Temple Place - S #include "tree-pass.h" #include "flags.h" #include "real.h" +#include "tree-ssa-propagate.h" /* TODO: Support for predicated code motion. I.e. @@ -600,7 +601,7 @@ determine_invariantness_stmt (struct dom && outermost_invariant_loop_expr (rhs, loop_containing_stmt (stmt)) == NULL) { - tree lhs, stmt1, stmt2, var, name; + tree lhs, stmt1, var, name, tmp; lhs = TREE_OPERAND (stmt, 0); @@ -614,17 +615,16 @@ determine_invariantness_stmt (struct dom TREE_OPERAND (rhs, 1))); name = make_ssa_name (var, stmt1); TREE_OPERAND (stmt1, 0) = name; - stmt2 = build2 (MODIFY_EXPR, void_type_node, lhs, - build2 (MULT_EXPR, TREE_TYPE (rhs), - name, TREE_OPERAND (rhs, 0))); + tmp = build2 (MULT_EXPR, TREE_TYPE (rhs), + name, TREE_OPERAND (rhs, 0)); /* Replace division stmt with reciprocal and multiply stmts. The multiply stmt is not invariant, so update iterator and avoid rescanning. */ - bsi_replace (&bsi, stmt1, true); - get_stmt_operands (stmt1); /* Should not be necessary. */ - bsi_insert_after (&bsi, stmt2, BSI_NEW_STMT); - SSA_NAME_DEF_STMT (lhs) = stmt2; + bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT); + if (!set_rhs (bsi_stmt_ptr (bsi), tmp)) + abort (); + update_stmt (stmt); /* Continue processing with invariant reciprocal statment. */ stmt = stmt1;
debug_immediate_uses() does not seem right after the reciprocal transformation: BEFORE D.478_11 : --> single use. x_14 = D.478_11 / pretmp.3_54; pretmp.3_54 : -->2 uses. x_14 = D.478_11 / pretmp.3_54; D.479_13 = pretmp.3_54; AFTER D.478_11 : -->2 uses. x_14 = D.478_11 * reciptmp.7_42; x_14 = D.478_11 / pretmp.3_54; reciptmp.7_42 : --> single use. x_14 = D.478_11 * reciptmp.7_42; pretmp.3_54 : -->3 uses. reciptmp.7_42 = 1.0e+0 / pretmp.3_54; x_14 = D.478_11 / pretmp.3_54; D.479_13 = pretmp.3_54; Why are the original division stmts still present? If the immediate uses still exist in the list but the statements were overwritten, that might cause problems.
Andrew could you look into this and see why the use info is not being updated correctly? Also note the patch in comment #4 is only working around the buggyness of the use information not being updated correctly.
*** Bug 21219 has been marked as a duplicate of this bug. ***
Created attachment 8738 [details] patch to fix the bug This should fix the problem. The problem arises since bsi_replace replaces the old stmt pointer with a new stmt pointer. Unfortunately, the stmt annotation is associated with the stmt pointer, so the new stmt does not inherit any of the operand cache from the old stmt. We dont do anything further with the old stmt, so the operands are never examined. The simplist solution at this point is to simply delink any of the operands from the old stmt. Im running this through bootstrap on x86 and such now. Want to try this on powerpc64?
Subject: Re: [4.1 Regression] use of poisoned ggc memory causes cpu2000 build failures Yes, I'll do a bootstrap and testrun and try the CPU2000 test.
Subject: Re: [4.1 Regression] use of poisoned ggc memory causes cpu2000 build failures The patch fixes the testcase for me on AIX.
Two of the four CPU2000 tests started building again a couple of days ago and the other two are fixed with this patch, on powerpc64-linux with -m64 -O2 -ffast-math -funroll-loops. Bootstrap of c,c++,f95,objc succeeded, testsuite is still running.
Test results for powerpc64-linux with -m32/-m64 are the same as for my last nightly build.
I rebuild the compiler with patch from Comment #8 and could now compile qt334 without problems. Michael Cieslinski
Fixed.