This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR optimization/6759
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 22 May 2002 23:52:03 +0200
- Subject: [PATCH] Fix PR optimization/6759
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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