This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
ppc: fix for pr31281, ObjC try-catch ICEs 4.2
- From: Stuart Hastings <stuart at apple dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: dje at watson dot ibm dot com
- Date: Tue, 20 Mar 2007 09:57:15 -0700
- Subject: ppc: fix for pr31281, ObjC try-catch ICEs 4.2
On powerpc-apple-darwin, this testcase
int f(unsigned int i)
{
@try { } @catch(id) { }
for (;;)
for (;;)
@try {
if (i)
break;
} @catch(id) { }
}
ICEs the 4.2 Objective-C compiler. I think this is a regression; the
4.0 version of cc1obj does not ICE on this testcase. (The testcase
has undergone significant reduction, and no longer makes any sense.)
I believe the ICE is caused by an omitted check in cse.c; previous CSE
work has turned a COMPARE insn into a MOVCC, and record_jump_equiv()
winds up recording that a PPC condition register is equal to zero.
Eventually it tries to move constant zero into the condition register,
and that fails because the movcc pattern can't really generate that
insn because of constraint difficulties... but I'm less worried about
that.
This patch adds the missing check (cut & pasted from the other call to
find_comparison_args()):
Index: gcc.fsf.42.ice1/gcc/cse.c
===================================================================
--- gcc.fsf.42.ice1/gcc/cse.c (revision 122999)
+++ gcc.fsf.42.ice1/gcc/cse.c (working copy)
@@ -4542,6 +4542,14 @@ record_jump_equiv (rtx insn, int taken)
op1 = fold_rtx (XEXP (XEXP (SET_SRC (set), 0), 1), insn);
code = find_comparison_args (code, &op0, &op1, &mode0, &mode1);
+
+ /* If the mode is VOIDmode or a MODE_CC mode, we don't know
+ what kinds of things are being compared, so we can't do
+ anything with this comparison. */
+
+ if (mode0 == VOIDmode || GET_MODE_CLASS (mode0) == MODE_CC)
+ return;
+
if (! cond_known_true)
{
code = reversed_comparison_code_parts (code, op0, op1, insn);
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
While the above patch fixes the ICE and produces correct-looking code,
the generated code is ugly, as GCC generates a mfcr/mtcr, much
shifting and masking, plus a conditional branch to accomplish... an
unconditional branch. I believe the cause is in the Objective-C front-
end; removing the 'volatile' attribute from the artificial 'rethrow'
variable fixes the ugly code. Note the first change is inside a large
(and welcome!) comment:
Index: gcc.fsf.42.ice2/gcc/objc/objc-act.c
===================================================================
--- gcc.fsf.42.ice2/gcc/objc/objc-act.c (revision 122999)
+++ gcc.fsf.42.ice2/gcc/objc/objc-act.c (working copy)
@@ -3632,7 +3632,7 @@ next_sjlj_build_catch_list (void)
{
struct _objc_exception_data _stack;
- id volatile _rethrow = 0;
+ id _rethrow = 0;
try
{
objc_exception_try_enter (&_stack);
@@ -3676,7 +3676,6 @@ next_sjlj_build_try_catch_finally (void)
rethrow_decl = objc_create_temporary_var (objc_object_type);
cur_try_context->rethrow_decl = rethrow_decl;
- TREE_THIS_VOLATILE (rethrow_decl) = 1;
TREE_CHAIN (rethrow_decl) = stack_decl;
/* Build the outermost variable binding level. */
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The second patch suffices to remove the ICE and fix the ugly code, but
I personally think both patches are necessary for correctness.
Both patches have been bootstrapped individually and DejaGnu-ed on ppc-
apple-darwin; no regressions.
O.K. to commit into 4.2?
stuart hastings
Apple