This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR optimization/6759


Hi!

The following testcase ICEs on SPARC. The problem is that
cse_insn calls fold_rtx with non-zero insn on
    (expr_list:REG_EQUAL (zero_extend:SI (reg/v:HI 119))
where:
(insn 33 54 34 (set (reg/v:HI 119)
        (const_int -1 [0xffffffffffffffff])) -1 (nil)
    (nil))
(from .jump dump).
fold_rtx with non-zero insn does apply changes directly, ie. doesn't
create copy, and substitutes -1 for reg 119:
    (expr_list:REG_EQUAL (zero_extend:SI (const_int -1 [0xffffffffffffffff]))
Then there is code in fold_rtx which fixes this up:
        new = simplify_unary_operation (code, mode,
                                        const_arg0 ? const_arg0 : folded_arg0,
                                        mode_arg0);
so fold_rtx in the end returns (const_int 65535 [0xffff]), but that is
just the returned value, as fold_rtx doesn't know the address where should
this store into. Then CSE does its magic and
leaves the bogus (zero_extend:SI (const_int -1)) in the REG_EQUAL note and
soon after we ICE, because that's of course not valid.
>From what I understand about fold_rtx, it either has to be called with
NULL insn, or the caller has to replace the rtx which it called on
with either fold_rtx's return value, or some other unrelated rtx, so that
we don't end up with a replacement in a middle.

The following patch fixes this by replacing the REG_EQUAL note
with the folded value (and also prevents fold_rtx from being called on the
same value multiple times for each set in a PARALLEL).
Other solution might be to call fold_rtx for REG_EQUAL note with NULL insn.

Bootstrapped/regtested on i386-redhat-linux, tested on the testcase on
sparc-redhat-linux.

Ok to commit?
This is a regression, ok to commit to branch too?

2002-05-22  Jakub Jelinek  <jakub@redhat.com>

	PR optimization/6759
	* cse.c (cse_insn): Fold src_eqv just once, store it folded back into
	the REQ_EQUAL note.

	* g++.dg/opt/cse1.C: New test.

--- gcc/cse.c.jj	Tue May 21 20:19:15 2002
+++ gcc/cse.c	Wed May 22 13:04:23 2002
@@ -4919,7 +4919,10 @@ cse_insn (insn, libcall_insn)
       && (tem = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0
       && (! rtx_equal_p (XEXP (tem, 0), SET_SRC (sets[0].rtl))
 	  || GET_CODE (SET_DEST (sets[0].rtl)) == STRICT_LOW_PART))
-    src_eqv = canon_reg (XEXP (tem, 0), NULL_RTX);
+    {
+      src_eqv = fold_rtx (canon_reg (XEXP (tem, 0), NULL_RTX), insn);
+      XEXP (tem, 0) = src_eqv;
+    }
 
   /* Canonicalize sources and addresses of destinations.
      We do this in a separate pass to avoid problems when a MATCH_DUP is
@@ -5023,7 +5026,6 @@ cse_insn (insn, libcall_insn)
 	    eqvmode = GET_MODE (SUBREG_REG (XEXP (dest, 0)));
 	  do_not_record = 0;
 	  hash_arg_in_memory = 0;
-	  src_eqv = fold_rtx (src_eqv, insn);
 	  src_eqv_hash = HASH (src_eqv, eqvmode);
 
 	  /* Find the equivalence class for the equivalent expression.  */
--- gcc/testsuite/g++.dg/opt/cse1.C.jj	Thu Aug 30 22:30:55 2001
+++ gcc/testsuite/g++.dg/opt/cse1.C	Wed May 22 14:02:55 2002
@@ -0,0 +1,12 @@
+// PR optimization/6759
+// This testcase ICEd on SPARC because folded REG_EQUAL
+// note was note stored back and fold_rtx left invalid rtx
+// in it.
+// { dg-do compile }
+// { dg-options "-O2" }
+
+struct A
+{
+  long long a;
+  A (unsigned short d) : a (d) {}
+} x (65535);

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]