public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/13772] New: [tree-ssa] ICE in get_expr_operands
@ 2004-01-20 16:20 reichelt at gcc dot gnu dot org
  2004-01-20 16:25 ` [Bug optimization/13772] " pinskia at gcc dot gnu dot org
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: reichelt at gcc dot gnu dot org @ 2004-01-20 16:20 UTC (permalink / raw)
  To: gcc-bugs

The following example causes an ICE when compiled with "g++ -O -c":

======================================================
struct A
{
    int i[2];

    int& operator[] (int j) { return i[j]; }

    int foo() { return (*this)[1]; }
};

void bar()
{
    A a[1];
    a[0].foo();
}
======================================================

The error message is:

ssa-bug.cc: In function `void bar()':
ssa-bug.cc:11: internal compiler error: in get_expr_operands, at
tree-ssa-operands.c:918
Please submit a full bug report, [etc.]

This is closely related to PR 13681, but here we don't have an
out-of-bounds access.

-- 
           Summary: [tree-ssa] ICE in get_expr_operands
           Product: gcc
           Version: tree-ssa
            Status: UNCONFIRMED
          Keywords: ice-on-valid-code
          Severity: critical
          Priority: P2
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: reichelt at gcc dot gnu dot org
                CC: bangerth at dealii dot org,gcc-bugs at gcc dot gnu dot
                    org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13772


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug optimization/13772] [tree-ssa] ICE in get_expr_operands
  2004-01-20 16:20 [Bug c++/13772] New: [tree-ssa] ICE in get_expr_operands reichelt at gcc dot gnu dot org
@ 2004-01-20 16:25 ` pinskia at gcc dot gnu dot org
  2004-01-22 10:41 ` zack at codesourcery dot com
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2004-01-20 16:25 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2004-01-20 16:25 -------
Confirmed.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
          Component|c++                         |optimization
     Ever Confirmed|                            |1
   Last reconfirmed|0000-00-00 00:00:00         |2004-01-20 16:25:01
               date|                            |
   Target Milestone|---                         |tree-ssa


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13772


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug optimization/13772] [tree-ssa] ICE in get_expr_operands
  2004-01-20 16:20 [Bug c++/13772] New: [tree-ssa] ICE in get_expr_operands reichelt at gcc dot gnu dot org
  2004-01-20 16:25 ` [Bug optimization/13772] " pinskia at gcc dot gnu dot org
@ 2004-01-22 10:41 ` zack at codesourcery dot com
  2004-01-22 11:02 ` zack at codesourcery dot com
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: zack at codesourcery dot com @ 2004-01-22 10:41 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From zack at codesourcery dot com  2004-01-22 10:40 -------
Subject: PR 13772 candidate fix


This is my candidate patch for the ia64/ada bootstrap failure
introduced by my TI/TFmode changes last week.  It takes the entire
problem off reload's hands, by careful use of postincrement so that
the scratch register becomes unnecessary.

Richard - I didn't use peephole2 as we discussed because that's only
effective in an optimizing compilation; so I had to make the splitters
do the work, and then it seemed silly to do it again.  It might be
worthwhile adding a bit more smarts about when the pointer is dead and
therefore doesn't need to be postmodified the second time; it might
also be worthwhile to add a peep2 to convert

  ld8 r12 = [r14], 8
  ;;
  ld8 r13 = [r14], -8

to

  adds r15 = r14, 8
  ;;
  ld8  r12 = [r14]
  ld8  r13 = [r15]

when a scratch register is available; this exposes a smidge more
parallelism.

I am bootstrapping this on ia64-hpux, C and C++ only.  I would
appreciate help testing ia64-linux and/or Ada.  I can confirm that
a cross-gnat1 built with this patch can compile a-elchha.adb at both
-O2 and -O0 without aborting.

zw

        * config/ia64/ia64.c (ia64_split_tmode, ia64_split_tmode_move): 
        Rewrite using POST_INC/POST_DEC/POST_MODIFY and no scratch registers.
        (ia64_secondary_reload_class): Remove GR_REGS TImode/TFmode clause.

        * config/ia64/ia64.md (movti, *movti_internal, movtf, *movtf_internal):
        Remove scratch from pattern.
        (reload_inti, reload_outti, reload_intf, reload_outtf): Delete.

===================================================================
Index: config/ia64/ia64.c
--- config/ia64/ia64.c	16 Jan 2004 01:27:37 -0000	1.265
+++ config/ia64/ia64.c	22 Jan 2004 10:37:36 -0000
@@ -1362,62 +1362,28 @@ ia64_emit_cond_move (rtx op0, rtx op1, r
 }
 
 /* Split a post-reload TImode or TFmode reference into two DImode
-   components.  */
+   components.  This is made extra difficult by the fact that we do
+   not get any scratch registers to work with, because reload cannot
+   be prevented from giving us a scratch that overlaps the register
+   pair involved.  So instead, when addressing memory, we tweak the
+   pointer register up and back down with POST_INCs.  Or up and not
+   back down when we can get away with it.  */
 
-static rtx
-ia64_split_tmode (rtx out[2], rtx in, rtx scratch)
+static void
+ia64_split_tmode (rtx out[2], rtx in, bool reversed)
 {
   switch (GET_CODE (in))
     {
     case REG:
-      out[0] = gen_rtx_REG (DImode, REGNO (in));
-      out[1] = gen_rtx_REG (DImode, REGNO (in) + 1);
-      return NULL_RTX;
-
-    case MEM:
-      {
-	rtx base = XEXP (in, 0);
-
-	switch (GET_CODE (base))
-	  {
-	  case REG:
-	    out[0] = adjust_address (in, DImode, 0);
-	    break;
-	  case POST_MODIFY:
-	    base = XEXP (base, 0);
-	    out[0] = adjust_address (in, DImode, 0);
-	    break;
-
-	  /* Since we're changing the mode, we need to change to POST_MODIFY
-	     as well to preserve the size of the increment.  Either that or
-	     do the update in two steps, but we've already got this scratch
-	     register handy so let's use it.  */
-	  case POST_INC:
-	    base = XEXP (base, 0);
-	    out[0]
-	      = change_address (in, DImode,
-				gen_rtx_POST_MODIFY
-				(Pmode, base, plus_constant (base, 16)));
-	    break;
-	  case POST_DEC:
-	    base = XEXP (base, 0);
-	    out[0]
-	      = change_address (in, DImode,
-				gen_rtx_POST_MODIFY
-				(Pmode, base, plus_constant (base, -16)));
-	    break;
-	  default:
-	    abort ();
-	  }
-
-	if (scratch == NULL_RTX)
-	  abort ();
-	out[1] = change_address (in, DImode, scratch);
-	return gen_adddi3 (scratch, base, GEN_INT (8));
-      }
+      out[reversed] = gen_rtx_REG (DImode, REGNO (in));
+      out[!reversed] = gen_rtx_REG (DImode, REGNO (in) + 1);
+      break;
 
     case CONST_INT:
     case CONST_DOUBLE:
+      /* Cannot occur reversed.  */
+      if (reversed) abort ();
+      
       if (GET_MODE (in) != TFmode)
 	split_double (in, &out[0], &out[1]);
       else
@@ -1444,7 +1410,74 @@ ia64_split_tmode (rtx out[2], rtx in, rt
 	  out[0] = GEN_INT (p[0]);
 	  out[1] = GEN_INT (p[1]);
 	}
-      return NULL_RTX;
+      break;
+
+    case MEM:
+      {
+	rtx base = XEXP (in, 0);
+	rtx offset;
+
+	switch (GET_CODE (base))
+	  {
+	  case REG:
+	    /* Pointer expected to remain unchanged - post_inc it up,
+	       post_dec it back down.  If reversed, it means this
+	       pointer dies here, so we must load the second field
+	       first.  This requires the emission of an extra addition
+	       insn.  */
+	    if (!reversed)
+	      {
+		out[0] = change_address (in, DImode,
+					 gen_rtx_POST_INC (Pmode, base));
+		out[1] = change_address (in, DImode,
+					 gen_rtx_POST_DEC (Pmode, base));
+	      }
+	    else
+	      {
+		emit_insn (gen_adddi3 (base, base, GEN_INT (8)));
+		out[0] = change_address (in, DImode,
+					 gen_rtx_POST_DEC (Pmode, base));
+		out[1] = adjust_address (in, DImode, 0);
+	      }
+	    break;
+
+	  case POST_INC:
+	    if (reversed) abort ();
+	    /* Do the increment in two steps.  */
+	    out[0] = change_address (in, DImode,
+				     gen_rtx_POST_INC (Pmode, base));
+	    out[1] = change_address (in, DImode,
+				     gen_rtx_POST_INC (Pmode, base));
+	    break;
+
+	  case POST_DEC:
+	    if (reversed) abort ();
+	    /* Add 8, subtract 24.  */
+	    out[0] = change_address (in, DImode,
+				     gen_rtx_POST_INC (Pmode, base));
+	    out[1] = change_address (in, DImode,
+				     gen_rtx_POST_MODIFY
+				     (Pmode, base, plus_constant (base, -24)));
+	    break;
+
+	  case POST_MODIFY:
+	    if (reversed) abort ();
+	    /* Extract and adjust the modification.  */
+	    offset = XEXP (base, 1);
+	    base = XEXP (base, 0);
+
+	    out[0] = change_address (in, DImode,
+				     gen_rtx_POST_INC (Pmode, base));
+	    out[1] = change_address (in, DImode,
+				     gen_rtx_POST_MODIFY
+				     (Pmode, base, plus_constant (offset, -8)));
+	    break;
+
+	  default:
+	    abort ();
+	  }
+	break;
+      }
 
     default:
       abort ();
@@ -1456,37 +1489,32 @@ ia64_split_tmode (rtx out[2], rtx in, rt
 void
 ia64_split_tmode_move (rtx operands[])
 {
-  rtx adj1, adj2, in[2], out[2], insn;
-  int first;
+  rtx in[2], out[2], insn;
+  bool reversed = false;
 
-  adj1 = ia64_split_tmode (in, operands[1], operands[2]);
-  adj2 = ia64_split_tmode (out, operands[0], operands[2]);
-
-  first = 0;
-  if (reg_overlap_mentioned_p (out[0], in[1]))
-    {
-      if (reg_overlap_mentioned_p (out[1], in[0]))
-	abort ();
-      first = 1;
-    }
-
-  if (adj1 && adj2)
-    abort ();
-  if (adj1)
-    emit_insn (adj1);
-  if (adj2)
-    emit_insn (adj2);
-  insn = emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
-  if (GET_CODE (out[first]) == MEM
-      && GET_CODE (XEXP (out[first], 0)) == POST_MODIFY)
+  /* It is possible for reload to decide to overwrite a pointer with
+     the value it points to.  In that case we have to do the loads in
+     the opposite order so that the pointer is not destroyed too early.
+     Also we must not generate a postmodify for that second load, or
+     rws_access_regno will abort.  */
+  if (GET_CODE (operands[1]) == MEM
+      && reg_overlap_mentioned_p (operands[0], operands[1]))
+    reversed = true;
+
+  ia64_split_tmode (in, operands[1], reversed);
+  ia64_split_tmode (out, operands[0], reversed);
+
+  insn = emit_insn (gen_rtx_SET (VOIDmode, out[0], in[0]));
+  if (GET_CODE (out[0]) == MEM
+      && GET_CODE (XEXP (out[0], 0)) == POST_MODIFY)
     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
-					  XEXP (XEXP (out[first], 0), 0),
+					  XEXP (XEXP (out[0], 0), 0),
 					  REG_NOTES (insn));
-  insn = emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
-  if (GET_CODE (out[!first]) == MEM
-      && GET_CODE (XEXP (out[!first], 0)) == POST_MODIFY)
+  insn = emit_insn (gen_rtx_SET (VOIDmode, out[1], in[1]));
+  if (GET_CODE (out[1]) == MEM
+      && GET_CODE (XEXP (out[1], 0)) == POST_MODIFY)
     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
-					  XEXP (XEXP (out[!first], 0), 0),
+					  XEXP (XEXP (out[1], 0), 0),
 					  REG_NOTES (insn));
 
 }
@@ -4451,13 +4479,6 @@ ia64_secondary_reload_class (enum reg_cl
       /* This can happen when we take a BImode subreg of a DImode value,
 	 and that DImode value winds up in some non-GR register.  */
       if (regno >= 0 && ! GENERAL_REGNO_P (regno) && ! PR_REGNO_P (regno))
-	return GR_REGS;
-      break;
-
-    case GR_REGS:
-      /* Since we have no offsettable memory addresses, we need a temporary
-	 to hold the address of the second word.  */
-      if (mode == TImode || mode == TFmode)
 	return GR_REGS;
       break;
 
===================================================================
Index: config/ia64/ia64.md
--- config/ia64/ia64.md	16 Jan 2004 01:27:38 -0000	1.119
+++ config/ia64/ia64.md	22 Jan 2004 10:37:36 -0000
@@ -584,11 +584,12 @@
   [(set_attr "itanium_class" "ialu")])
 
 ;; With no offsettable memory references, we've got to have a scratch
-;; around to play with the second word.
+;; around to play with the second word.  However, in order to avoid a
+;; reload nightmare we lie, claim we don't need one, and fix it up
+;; in ia64_split_tmode_move.
 (define_expand "movti"
-  [(parallel [(set (match_operand:TI 0 "general_operand" "")
-		   (match_operand:TI 1 "general_operand" ""))
-	      (clobber (match_scratch:DI 2 ""))])]
+  [(set (match_operand:TI 0 "general_operand" "")
+	(match_operand:TI 1 "general_operand" ""))]
   ""
 {
   rtx op1 = ia64_expand_move (operands[0], operands[1]);
@@ -599,8 +600,7 @@
 
 (define_insn_and_split "*movti_internal"
   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
-	(match_operand:TI 1 "general_operand"      "ri,m,r"))
-   (clobber (match_scratch:DI 2 "=X,&r,&r"))]
+	(match_operand:TI 1 "general_operand"      "ri,m,r"))]
   "ia64_move_ok (operands[0], operands[1])"
   "#"
   "reload_completed"
@@ -612,20 +612,6 @@
   [(set_attr "itanium_class" "unknown")
    (set_attr "predicable" "no")])
 
-(define_expand "reload_inti"
-  [(parallel [(set (match_operand:TI 0 "register_operand" "=r")
-		   (match_operand:TI 1 "memory_operand" "m"))
-	      (clobber (match_operand:DI 2 "register_operand" "=&r"))])]
-  ""
-  "")
-
-(define_expand "reload_outti"
-  [(parallel [(set (match_operand:TI 0 "memory_operand" "=m")
-		   (match_operand:TI 1 "register_operand" "r"))
-	      (clobber (match_operand:DI 2 "register_operand" "=&r"))])]
-  ""
-  "")
-
 ;; Floating Point Moves
 ;;
 ;; Note - Patterns for SF mode moves are compulsory, but
@@ -764,13 +750,10 @@
   [(set_attr "itanium_class" "fmisc,fld,stf")])
 
 ;; Better code generation via insns that deal with TFmode register pairs
-;; directly.
-;; With no offsettable memory references, we've got to have a scratch
-;; around to play with the second word.
+;; directly.  Same concerns apply as for TImode.
 (define_expand "movtf"
-  [(parallel [(set (match_operand:TF 0 "general_operand" "")
-		   (match_operand:TF 1 "general_operand" ""))
-	      (clobber (match_scratch:DI 2 ""))])]
+  [(set (match_operand:TF 0 "general_operand" "")
+	(match_operand:TF 1 "general_operand" ""))]
   ""
 {
   rtx op1 = ia64_expand_move (operands[0], operands[1]);
@@ -781,8 +764,7 @@
 
 (define_insn_and_split "*movtf_internal"
   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,r,m")
-	(match_operand:TF 1 "general_operand"      "ri,m,r"))
-   (clobber (match_scratch:DI 2 "=X,&r,&r"))]
+	(match_operand:TF 1 "general_operand"      "ri,m,r"))]
   "ia64_move_ok (operands[0], operands[1])"
   "#"
   "reload_completed"
@@ -794,19 +776,6 @@
   [(set_attr "itanium_class" "unknown")
    (set_attr "predicable" "no")])
 
-(define_expand "reload_intf"
-  [(parallel [(set (match_operand:TF 0 "register_operand" "=r")
-		   (match_operand:TF 1 "memory_operand" "m"))
-	      (clobber (match_operand:DI 2 "register_operand" "=&r"))])]
-  ""
-  "")
-
-(define_expand "reload_outtf"
-  [(parallel [(set (match_operand:TF 0 "memory_operand" "=m")
-		   (match_operand:TF 1 "register_operand" "r"))
-	      (clobber (match_operand:DI 2 "register_operand" "=&r"))])]
-  ""
-  "")
 \f
 ;; ::::::::::::::::::::
 ;; ::


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13772


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug optimization/13772] [tree-ssa] ICE in get_expr_operands
  2004-01-20 16:20 [Bug c++/13772] New: [tree-ssa] ICE in get_expr_operands reichelt at gcc dot gnu dot org
  2004-01-20 16:25 ` [Bug optimization/13772] " pinskia at gcc dot gnu dot org
  2004-01-22 10:41 ` zack at codesourcery dot com
@ 2004-01-22 11:02 ` zack at codesourcery dot com
  2004-01-22 13:07 ` schwab at suse dot de
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: zack at codesourcery dot com @ 2004-01-22 11:02 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From zack at codesourcery dot com  2004-01-22 11:02 -------
Subject: Re: PR 13772 candidate fix

"Zack Weinberg" <zack@codesourcery.com> writes:

> This is my candidate patch for the ia64/ada bootstrap failure
> introduced by my TI/TFmode changes last week.  It takes the entire
> problem off reload's hands, by careful use of postincrement so that
> the scratch register becomes unnecessary.

Augh, several mistakes in that patch, please test this one instead.

(Can someone clue me in on the difference between change_address and
adjust_address?)

zw

===================================================================
Index: config/ia64/ia64.c
--- config/ia64/ia64.c	16 Jan 2004 01:27:37 -0000	1.265
+++ config/ia64/ia64.c	22 Jan 2004 11:00:35 -0000
@@ -1362,62 +1362,33 @@ ia64_emit_cond_move (rtx op0, rtx op1, r
 }
 
 /* Split a post-reload TImode or TFmode reference into two DImode
-   components.  */
+   components.  This is made extra difficult by the fact that we do
+   not get any scratch registers to work with, because reload cannot
+   be prevented from giving us a scratch that overlaps the register
+   pair involved.  So instead, when addressing memory, we tweak the
+   pointer register up and back down with POST_INCs.  Or up and not
+   back down when we can get away with it.
+
+   REVERSED is true when the loads must be done in reversed order
+   (high word first) for correctness.  DEAD is true when the pointer
+   dies with the second insn we generate and therefore the second address
+   must not carry a postmodify.  */
 
-static rtx
-ia64_split_tmode (rtx out[2], rtx in, rtx scratch)
+static void
+ia64_split_tmode (rtx out[2], rtx in, bool reversed, bool dead)
 {
   switch (GET_CODE (in))
     {
     case REG:
-      out[0] = gen_rtx_REG (DImode, REGNO (in));
-      out[1] = gen_rtx_REG (DImode, REGNO (in) + 1);
-      return NULL_RTX;
-
-    case MEM:
-      {
-	rtx base = XEXP (in, 0);
-
-	switch (GET_CODE (base))
-	  {
-	  case REG:
-	    out[0] = adjust_address (in, DImode, 0);
-	    break;
-	  case POST_MODIFY:
-	    base = XEXP (base, 0);
-	    out[0] = adjust_address (in, DImode, 0);
-	    break;
-
-	  /* Since we're changing the mode, we need to change to POST_MODIFY
-	     as well to preserve the size of the increment.  Either that or
-	     do the update in two steps, but we've already got this scratch
-	     register handy so let's use it.  */
-	  case POST_INC:
-	    base = XEXP (base, 0);
-	    out[0]
-	      = change_address (in, DImode,
-				gen_rtx_POST_MODIFY
-				(Pmode, base, plus_constant (base, 16)));
-	    break;
-	  case POST_DEC:
-	    base = XEXP (base, 0);
-	    out[0]
-	      = change_address (in, DImode,
-				gen_rtx_POST_MODIFY
-				(Pmode, base, plus_constant (base, -16)));
-	    break;
-	  default:
-	    abort ();
-	  }
-
-	if (scratch == NULL_RTX)
-	  abort ();
-	out[1] = change_address (in, DImode, scratch);
-	return gen_adddi3 (scratch, base, GEN_INT (8));
-      }
+      out[reversed] = gen_rtx_REG (DImode, REGNO (in));
+      out[!reversed] = gen_rtx_REG (DImode, REGNO (in) + 1);
+      break;
 
     case CONST_INT:
     case CONST_DOUBLE:
+      /* Cannot occur reversed.  */
+      if (reversed) abort ();
+      
       if (GET_MODE (in) != TFmode)
 	split_double (in, &out[0], &out[1]);
       else
@@ -1444,7 +1415,72 @@ ia64_split_tmode (rtx out[2], rtx in, rt
 	  out[0] = GEN_INT (p[0]);
 	  out[1] = GEN_INT (p[1]);
 	}
-      return NULL_RTX;
+      break;
+
+    case MEM:
+      {
+	rtx base = XEXP (in, 0);
+	rtx offset;
+
+	switch (GET_CODE (base))
+	  {
+	  case REG:
+	    if (!reversed)
+	      {
+		out[0] = change_address (in, DImode,
+					 gen_rtx_POST_INC (Pmode, base));
+		out[1] = change_address (in, DImode,
+					 dead ? 0
+					 : gen_rtx_POST_DEC (Pmode, base));
+	      }
+	    else
+	      {
+		if (!dead) abort();
+		/* Reversal requires a pre-increment, which can only
+		   be done as a separate insn.  */
+		emit_insn (gen_adddi3 (base, base, GEN_INT (8)));
+		out[0] = change_address (in, DImode,
+					 gen_rtx_POST_DEC (Pmode, base));
+		out[1] = adjust_address (in, DImode, 0);
+	      }
+	    break;
+
+	  case POST_INC:
+	    if (reversed || dead) abort ();
+	    /* Just do the increment in two steps.  */
+	    out[0] = change_address (in, DImode, 0);
+	    out[1] = change_address (in, DImode, 0);
+	    break;
+
+	  case POST_DEC:
+	    if (reversed || dead) abort ();
+	    /* Add 8, subtract 24.  */
+	    base = XEXP (base, 0);
+	    out[0] = change_address (in, DImode,
+				     gen_rtx_POST_INC (Pmode, base));
+	    out[1] = change_address (in, DImode,
+				     gen_rtx_POST_MODIFY
+				     (Pmode, base, plus_constant (base, -24)));
+	    break;
+
+	  case POST_MODIFY:
+	    if (reversed || dead) abort ();
+	    /* Extract and adjust the modification.  */
+	    offset = XEXP (base, 1);
+	    base = XEXP (base, 0);
+
+	    out[0] = change_address (in, DImode,
+				     gen_rtx_POST_INC (Pmode, base));
+	    out[1] = change_address (in, DImode,
+				     gen_rtx_POST_MODIFY
+				     (Pmode, base, plus_constant (offset, -8)));
+	    break;
+
+	  default:
+	    abort ();
+	  }
+	break;
+      }
 
     default:
       abort ();
@@ -1456,37 +1492,41 @@ ia64_split_tmode (rtx out[2], rtx in, rt
 void
 ia64_split_tmode_move (rtx operands[])
 {
-  rtx adj1, adj2, in[2], out[2], insn;
-  int first;
-
-  adj1 = ia64_split_tmode (in, operands[1], operands[2]);
-  adj2 = ia64_split_tmode (out, operands[0], operands[2]);
-
-  first = 0;
-  if (reg_overlap_mentioned_p (out[0], in[1]))
-    {
-      if (reg_overlap_mentioned_p (out[1], in[0]))
-	abort ();
-      first = 1;
-    }
-
-  if (adj1 && adj2)
-    abort ();
-  if (adj1)
-    emit_insn (adj1);
-  if (adj2)
-    emit_insn (adj2);
-  insn = emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
-  if (GET_CODE (out[first]) == MEM
-      && GET_CODE (XEXP (out[first], 0)) == POST_MODIFY)
+  rtx in[2], out[2], insn;
+  bool dead = false;
+  bool reversed = false;
+
+  /* It is possible for reload to decide to overwrite a pointer with
+     the value it points to.  In that case we have to do the loads in
+     the appropriate order so that the pointer is not destroyed too
+     early.  Also we must not generate a postmodify for that second
+     load, or rws_access_regno will abort.  */
+  if (GET_CODE (operands[1]) == MEM
+      && reg_overlap_mentioned_p (operands[0], operands[1]))
+    {
+      rtx base = XEXP (operands[1], 0);
+      while (GET_CODE (base) != REG)
+	base = XEXP (base, 0);
+
+      if (REGNO (base) == REGNO (operands[0]))
+	reversed = true;
+      dead = true;
+    }
+
+  ia64_split_tmode (in, operands[1], reversed, dead);
+  ia64_split_tmode (out, operands[0], reversed, dead);
+
+  insn = emit_insn (gen_rtx_SET (VOIDmode, out[0], in[0]));
+  if (GET_CODE (out[0]) == MEM
+      && GET_CODE (XEXP (out[0], 0)) == POST_MODIFY)
     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
-					  XEXP (XEXP (out[first], 0), 0),
+					  XEXP (XEXP (out[0], 0), 0),
 					  REG_NOTES (insn));
-  insn = emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
-  if (GET_CODE (out[!first]) == MEM
-      && GET_CODE (XEXP (out[!first], 0)) == POST_MODIFY)
+  insn = emit_insn (gen_rtx_SET (VOIDmode, out[1], in[1]));
+  if (GET_CODE (out[1]) == MEM
+      && GET_CODE (XEXP (out[1], 0)) == POST_MODIFY)
     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
-					  XEXP (XEXP (out[!first], 0), 0),
+					  XEXP (XEXP (out[1], 0), 0),
 					  REG_NOTES (insn));
 
 }
@@ -4451,13 +4491,6 @@ ia64_secondary_reload_class (enum reg_cl
       /* This can happen when we take a BImode subreg of a DImode value,
 	 and that DImode value winds up in some non-GR register.  */
       if (regno >= 0 && ! GENERAL_REGNO_P (regno) && ! PR_REGNO_P (regno))
-	return GR_REGS;
-      break;
-
-    case GR_REGS:
-      /* Since we have no offsettable memory addresses, we need a temporary
-	 to hold the address of the second word.  */
-      if (mode == TImode || mode == TFmode)
 	return GR_REGS;
       break;
 
===================================================================
Index: config/ia64/ia64.md
--- config/ia64/ia64.md	16 Jan 2004 01:27:38 -0000	1.119
+++ config/ia64/ia64.md	22 Jan 2004 11:00:35 -0000
@@ -584,11 +584,12 @@
   [(set_attr "itanium_class" "ialu")])
 
 ;; With no offsettable memory references, we've got to have a scratch
-;; around to play with the second word.
+;; around to play with the second word.  However, in order to avoid a
+;; reload nightmare we lie, claim we don't need one, and fix it up
+;; in ia64_split_tmode_move.
 (define_expand "movti"
-  [(parallel [(set (match_operand:TI 0 "general_operand" "")
-		   (match_operand:TI 1 "general_operand" ""))
-	      (clobber (match_scratch:DI 2 ""))])]
+  [(set (match_operand:TI 0 "general_operand" "")
+	(match_operand:TI 1 "general_operand" ""))]
   ""
 {
   rtx op1 = ia64_expand_move (operands[0], operands[1]);
@@ -599,8 +600,7 @@
 
 (define_insn_and_split "*movti_internal"
   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
-	(match_operand:TI 1 "general_operand"      "ri,m,r"))
-   (clobber (match_scratch:DI 2 "=X,&r,&r"))]
+	(match_operand:TI 1 "general_operand"      "ri,m,r"))]
   "ia64_move_ok (operands[0], operands[1])"
   "#"
   "reload_completed"
@@ -612,20 +612,6 @@
   [(set_attr "itanium_class" "unknown")
    (set_attr "predicable" "no")])
 
-(define_expand "reload_inti"
-  [(parallel [(set (match_operand:TI 0 "register_operand" "=r")
-		   (match_operand:TI 1 "memory_operand" "m"))
-	      (clobber (match_operand:DI 2 "register_operand" "=&r"))])]
-  ""
-  "")
-
-(define_expand "reload_outti"
-  [(parallel [(set (match_operand:TI 0 "memory_operand" "=m")
-		   (match_operand:TI 1 "register_operand" "r"))
-	      (clobber (match_operand:DI 2 "register_operand" "=&r"))])]
-  ""
-  "")
-
 ;; Floating Point Moves
 ;;
 ;; Note - Patterns for SF mode moves are compulsory, but
@@ -764,13 +750,10 @@
   [(set_attr "itanium_class" "fmisc,fld,stf")])
 
 ;; Better code generation via insns that deal with TFmode register pairs
-;; directly.
-;; With no offsettable memory references, we've got to have a scratch
-;; around to play with the second word.
+;; directly.  Same concerns apply as for TImode.
 (define_expand "movtf"
-  [(parallel [(set (match_operand:TF 0 "general_operand" "")
-		   (match_operand:TF 1 "general_operand" ""))
-	      (clobber (match_scratch:DI 2 ""))])]
+  [(set (match_operand:TF 0 "general_operand" "")
+	(match_operand:TF 1 "general_operand" ""))]
   ""
 {
   rtx op1 = ia64_expand_move (operands[0], operands[1]);
@@ -781,8 +764,7 @@
 
 (define_insn_and_split "*movtf_internal"
   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,r,m")
-	(match_operand:TF 1 "general_operand"      "ri,m,r"))
-   (clobber (match_scratch:DI 2 "=X,&r,&r"))]
+	(match_operand:TF 1 "general_operand"      "ri,m,r"))]
   "ia64_move_ok (operands[0], operands[1])"
   "#"
   "reload_completed"
@@ -794,19 +776,6 @@
   [(set_attr "itanium_class" "unknown")
    (set_attr "predicable" "no")])
 
-(define_expand "reload_intf"
-  [(parallel [(set (match_operand:TF 0 "register_operand" "=r")
-		   (match_operand:TF 1 "memory_operand" "m"))
-	      (clobber (match_operand:DI 2 "register_operand" "=&r"))])]
-  ""
-  "")
-
-(define_expand "reload_outtf"
-  [(parallel [(set (match_operand:TF 0 "memory_operand" "=m")
-		   (match_operand:TF 1 "register_operand" "r"))
-	      (clobber (match_operand:DI 2 "register_operand" "=&r"))])]
-  ""
-  "")
 \f
 ;; ::::::::::::::::::::
 ;; ::


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13772


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug optimization/13772] [tree-ssa] ICE in get_expr_operands
  2004-01-20 16:20 [Bug c++/13772] New: [tree-ssa] ICE in get_expr_operands reichelt at gcc dot gnu dot org
                   ` (2 preceding siblings ...)
  2004-01-22 11:02 ` zack at codesourcery dot com
@ 2004-01-22 13:07 ` schwab at suse dot de
  2004-01-22 16:06 ` bangerth at dealii dot org
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: schwab at suse dot de @ 2004-01-22 13:07 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From schwab at suse dot de  2004-01-22 13:07 -------
Subject: Re: PR 13772 candidate fix

"Zack Weinberg" <zack@codesourcery.com> writes:

> "Zack Weinberg" <zack@codesourcery.com> writes:
>
>> This is my candidate patch for the ia64/ada bootstrap failure
>> introduced by my TI/TFmode changes last week.  It takes the entire
>> problem off reload's hands, by careful use of postincrement so that
>> the scratch register becomes unnecessary.
>
> Augh, several mistakes in that patch, please test this one instead.

Still doesn't fly.

stage1/xgcc -Bstage1/ -B/usr/local/ia64-suse-linux/bin/ -c -g -O2      -gnatpg -gnata -I- -I. -Iada -I../../gcc/ada ../../gcc/ada/opt.adb -o ada/opt.o
+===========================GNAT BUG DETECTED==============================+
| 3.5.0 20040122 (experimental) (ia64-suse-linux-gnu) GCC error:           |
| in change_address_1, at emit-rtl.c:1849                                  |

#0  fancy_abort (file=0x4000000000d9f070 "../../gcc/emit-rtl.c", line=1849, 
    function=0x4000000000d9f580 "change_address_1")
    at ../../gcc/diagnostic.c:584
#1  0x4000000000650c90 in change_address_1 (memref=0x20000000006b0ce0, 
    mode=DImode, addr=0x20000000006f6f20, validate=1)
    at ../../gcc/emit-rtl.c:1849
#2  0x4000000000651890 in change_address (memref=0x20000000006b0ce0, 
    mode=DImode, addr=0x20000000006f6f20) at ../../gcc/emit-rtl.c:1869
#3  0x4000000000b102c0 in ia64_split_tmode (out=0x60000fffffffa168, 
    in=0x20000000006b0ce0, reversed=false, dead=false)
    at ../../gcc/config/ia64/ia64.c:1379
#4  0x4000000000b108b0 in ia64_split_tmode_move (operands=0x6000000000065a28)
    at ../../gcc/config/ia64/ia64.c:1517
#5  0x400000000090baf0 in gen_split_296 (operands=0x6000000000065a28)
    at insn-emit.c:2289
#6  0x400000000090f9a0 in split_insns (x0=0x20000000006b0ec0, 
    insn=0x20000000006b0da0) at insn-recog.c:20387
#7  0x400000000065ac40 in try_split (pat=0x20000000006b0ec0, 
    trial=0x20000000006aa080, last=1) at ../../gcc/emit-rtl.c:3226
#8  0x40000000009ee160 in split_insn (insn=0x20000000006aa080)
    at ../../gcc/recog.c:2689
#9  0x40000000009ee840 in split_all_insns (upd_life=0)
    at ../../gcc/recog.c:2720
#10 0x4000000000a96f40 in rest_of_compilation (decl=0x200000000069f4d0)
    at ../../gcc/toplev.c:3434

memref:

(mem/s:TI (post_modify:DI (reg/f:DI 36 loc4 [400])
        (plus:DI (reg/f:DI 36 loc4 [400])
            (const_int 8 [0x8]))) [4 opt__R47s+0 S16 A128])

Andreas.



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13772


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug optimization/13772] [tree-ssa] ICE in get_expr_operands
  2004-01-20 16:20 [Bug c++/13772] New: [tree-ssa] ICE in get_expr_operands reichelt at gcc dot gnu dot org
                   ` (3 preceding siblings ...)
  2004-01-22 13:07 ` schwab at suse dot de
@ 2004-01-22 16:06 ` bangerth at dealii dot org
  2004-01-22 19:45 ` rth at redhat dot com
  2004-01-23 14:51 ` reichelt at gcc dot gnu dot org
  6 siblings, 0 replies; 8+ messages in thread
From: bangerth at dealii dot org @ 2004-01-22 16:06 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From bangerth at dealii dot org  2004-01-22 16:06 -------
This seems to be fixed with rth's patch to PR 13681. Volker, can 
you confirm this as well? 
 
W. 

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13772


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug optimization/13772] [tree-ssa] ICE in get_expr_operands
  2004-01-20 16:20 [Bug c++/13772] New: [tree-ssa] ICE in get_expr_operands reichelt at gcc dot gnu dot org
                   ` (4 preceding siblings ...)
  2004-01-22 16:06 ` bangerth at dealii dot org
@ 2004-01-22 19:45 ` rth at redhat dot com
  2004-01-23 14:51 ` reichelt at gcc dot gnu dot org
  6 siblings, 0 replies; 8+ messages in thread
From: rth at redhat dot com @ 2004-01-22 19:45 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From rth at redhat dot com  2004-01-22 19:45 -------
Subject: Re: PR 13772 candidate fix

On Thu, Jan 22, 2004 at 02:07:12PM +0100, Andreas Schwab wrote:
> (mem/s:TI (post_modify:DI (reg/f:DI 36 loc4 [400])
>         (plus:DI (reg/f:DI 36 loc4 [400])
>             (const_int 8 [0x8]))) [4 opt__R47s+0 S16 A128])

Yep, looking at the patch, I was about to remind Zack that 
(1) post-modify can take registers as well as constants, and
(2) you have to check for overflowing the 9-bit post-modify
    constant.

Hum, and, actually, that post-modify seems very improbable.
addr += addr?  There's sure to be a typo somewhere.


r~


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13772


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug optimization/13772] [tree-ssa] ICE in get_expr_operands
  2004-01-20 16:20 [Bug c++/13772] New: [tree-ssa] ICE in get_expr_operands reichelt at gcc dot gnu dot org
                   ` (5 preceding siblings ...)
  2004-01-22 19:45 ` rth at redhat dot com
@ 2004-01-23 14:51 ` reichelt at gcc dot gnu dot org
  6 siblings, 0 replies; 8+ messages in thread
From: reichelt at gcc dot gnu dot org @ 2004-01-23 14:51 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From reichelt at gcc dot gnu dot org  2004-01-23 14:51 -------
Yup. Seems to be fixed for me, too.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13772


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2004-01-23 14:51 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-01-20 16:20 [Bug c++/13772] New: [tree-ssa] ICE in get_expr_operands reichelt at gcc dot gnu dot org
2004-01-20 16:25 ` [Bug optimization/13772] " pinskia at gcc dot gnu dot org
2004-01-22 10:41 ` zack at codesourcery dot com
2004-01-22 11:02 ` zack at codesourcery dot com
2004-01-22 13:07 ` schwab at suse dot de
2004-01-22 16:06 ` bangerth at dealii dot org
2004-01-22 19:45 ` rth at redhat dot com
2004-01-23 14:51 ` reichelt at gcc dot gnu dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).