This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR18683: Bad C++/cgraph/middle-end/rs6000 interaction (fix2)
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 20 Dec 2004 09:41:23 -0700 (MST)
- Subject: [PATCH] PR18683: Bad C++/cgraph/middle-end/rs6000 interaction (fix2)
PR middle-end/18683 is a critical ICE-on-valid regression in current
mainline affecting C++ on powerpc targets. It is caused by an obscure
interaction between the rs6000 backend and the g++ front-end during
local register allocation. The unfortunate sequence of events (described
in the bugzilla PR) causes reg_renumber to be reset to zero during
register allocation, which leads to a segmentation fault.
There are several possible ways to tackle this issue...
In the patch below, the solution is to prevent reg_class from calling
make_decl_rtl during local register allocation in the rs6000 backend.
The cause is that the function current_file_function_operand, which
checks whether an symbol reference is local to the current translation
unit, attempts to compare against current_function_decl's DECL_RTL.
It turns out that for the testcase in the PR, we've not yet generated
an assembler name for this C++ template (unless we've been generating
debugging dumps!?), which invokes make_decl_rtl which has the
unanticipated side-effect of reseting the reg_renumber array to zero.
The work-around (and micro-optimization) below is that a symbol
reference (probably?) can't refer to the current function if we haven't
yet generated an assembler name for it. This is implemented by testing
DECL_RTL_SET_P before referencing DECL_RTL.
In addition to this change, I'll also submit another change to the
middle-end that is also sufficient to resolve the failure. However
both of these fixes may possibly be papering over a more fundamental
problem in the interaction between g++ and cgraph; should we guarantee
that current_function_decl has an assembler name before generating RTL?
The following patch has been tested on powerpc-unknown-linux-gnu with
a full "make bootstrap", all default languages, and regression tested
with a top-level "make -k check" with no new failures.
Ok for mainline?
2004-12-20 Roger Sayle <roger@eyesopen.com>
PR middle-end/18683
* config/rs6000/rs6000.c (current_file_function_operand): Only check
current_function_decl's DECL_RTL if it has already been set.
* g++.dg/opt/pr18683-1.C: New test case.
Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.765
diff -c -3 -p -r1.765 rs6000.c
*** config/rs6000/rs6000.c 14 Dec 2004 18:43:48 -0000 1.765
--- config/rs6000/rs6000.c 20 Dec 2004 05:54:02 -0000
*************** current_file_function_operand (rtx op,
*** 2960,2966 ****
return (GET_CODE (op) == SYMBOL_REF
&& (DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op))
&& (SYMBOL_REF_LOCAL_P (op)
! || (op == XEXP (DECL_RTL (current_function_decl), 0))));
}
/* Return 1 if this operand is a valid input for a move insn. */
--- 2960,2967 ----
return (GET_CODE (op) == SYMBOL_REF
&& (DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op))
&& (SYMBOL_REF_LOCAL_P (op)
! || (DECL_RTL_SET_P (current_function_decl)
! && op == XEXP (DECL_RTL (current_function_decl), 0))));
}
/* Return 1 if this operand is a valid input for a move insn. */
// PR middle-end/18683
// { dg-do compile }
// { dg-options "-O0" }
template<typename _CharT>
struct basic_ostream
{
basic_ostream& operator<<(int __n);
};
extern basic_ostream<char> cout;
template<int> struct linear_congruential
{
template<class CharT>
friend basic_ostream<CharT>&
operator<<(basic_ostream<CharT>& os,
const linear_congruential& lcg)
{
return os << 1;
}
};
void instantiate_all()
{
linear_congruential<0> lcf;
cout << lcf;
}
Roger
--
Roger Sayle, E-mail: roger@eyesopen.com
OpenEye Scientific Software, WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road, Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507. Fax: (+1) 505-473-0833