re PR rtl-optimization/24883 (fatal error: internal consistency failure building...
authorIan Lance Taylor <ian@airs.com>
Mon, 21 Nov 2005 05:41:36 +0000 (05:41 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Mon, 21 Nov 2005 05:41:36 +0000 (05:41 +0000)
./: PR rtl-optimization/24883
* combine.c (combinable_i3pat): When checking whether the
destination of i3 is used in i3, consider paradoxical subregs.
testsuite/:
PR rtl-optimization/24883
* gcc.c-torture/compile/pr24883.c: New test.

From-SVN: r107279

gcc/ChangeLog
gcc/combine.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr24883.c [new file with mode: 0644]

index 5f1e761a4ad079bfdf9ccdcbed08749816c6204b..630bebc1bbfc2b4a3a6e28bb561f9ee0c97ea502 100644 (file)
@@ -1,3 +1,9 @@
+2005-11-20  Ian Lance Taylor  <ian@airs.com>
+
+       PR rtl-optimization/24883
+       * combine.c (combinable_i3pat): When checking whether the
+       destination of i3 is used in i3, consider paradoxical subregs.
+
 2005-11-21  Kazu Hirata  <kazu@codesourcery.com>
 
        PR middle-end/20583
index 6497336bf4424b55faea31795d8fed5874701bae..abd64582d3ee43c6099d84a10dc07a6ad26ecab3 100644 (file)
@@ -1423,6 +1423,7 @@ combinable_i3pat (rtx i3, rtx *loc, rtx i2dest, rtx i1dest,
       rtx dest = SET_DEST (set);
       rtx src = SET_SRC (set);
       rtx inner_dest = dest;
+      rtx subdest;
 
       while (GET_CODE (inner_dest) == STRICT_LOW_PART
             || GET_CODE (inner_dest) == SUBREG
@@ -1457,27 +1458,35 @@ combinable_i3pat (rtx i3, rtx *loc, rtx i2dest, rtx i1dest,
          || (i1_not_in_src && reg_overlap_mentioned_p (i1dest, src)))
        return 0;
 
-      /* If DEST is used in I3, it is being killed in this insn,
-        so record that for later.
+      /* If DEST is used in I3, it is being killed in this insn, so
+        record that for later.  We have to consider paradoxical
+        subregs here, since they kill the whole register, but we
+        ignore partial subregs, STRICT_LOW_PART, etc.
         Never add REG_DEAD notes for the FRAME_POINTER_REGNUM or the
         STACK_POINTER_REGNUM, since these are always considered to be
         live.  Similarly for ARG_POINTER_REGNUM if it is fixed.  */
-      if (pi3dest_killed && REG_P (dest)
-         && reg_referenced_p (dest, PATTERN (i3))
-         && REGNO (dest) != FRAME_POINTER_REGNUM
+      subdest = dest;
+      if (GET_CODE (subdest) == SUBREG
+         && (GET_MODE_SIZE (GET_MODE (subdest))
+             >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (subdest)))))
+       subdest = SUBREG_REG (subdest);
+      if (pi3dest_killed
+         && REG_P (subdest)
+         && reg_referenced_p (subdest, PATTERN (i3))
+         && REGNO (subdest) != FRAME_POINTER_REGNUM
 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
-         && REGNO (dest) != HARD_FRAME_POINTER_REGNUM
+         && REGNO (subdest) != HARD_FRAME_POINTER_REGNUM
 #endif
 #if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
-         && (REGNO (dest) != ARG_POINTER_REGNUM
-             || ! fixed_regs [REGNO (dest)])
+         && (REGNO (subdest) != ARG_POINTER_REGNUM
+             || ! fixed_regs [REGNO (subdest)])
 #endif
-         && REGNO (dest) != STACK_POINTER_REGNUM)
+         && REGNO (subdest) != STACK_POINTER_REGNUM)
        {
          if (*pi3dest_killed)
            return 0;
 
-         *pi3dest_killed = dest;
+         *pi3dest_killed = subdest;
        }
     }
 
index 48f03546b5f9463321aa3a8ebdd3e9b561e5456a..1a05c183fec54af9cfbd5bb817c8c49e0a5b5438 100644 (file)
@@ -1,3 +1,8 @@
+2005-11-20  Ian Lance Taylor  <ian@airs.com>
+
+       PR rtl-optimization/24883
+       * gcc.c-torture/compile/pr24883.c: New test.
+
 2005-11-21  Kazu Hirata  <kazu@codesourcery.com>
 
        PR middle-end/20583
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr24883.c b/gcc/testsuite/gcc.c-torture/compile/pr24883.c
new file mode 100644 (file)
index 0000000..b2ced75
--- /dev/null
@@ -0,0 +1,21 @@
+typedef struct _rec_stl rec_stl;
+struct _rec_stl {
+   unsigned char **strs;
+};
+orec_str_list(int count) {
+   rec_stl *stl;
+   int i, j;
+   int li, lj;
+   unsigned char ci, cj;
+   for (i = 0; i < count; i++) {
+      for (j = i + 1; j < count; j++) {
+         cj = lj > 2 ? stl->strs[j][0] : (long)stl->strs[j] & 0xff;
+         if ((count >= 16 && cj < ci) || (cj == ci && lj > li)) {
+            stl->strs[j] = stl->strs[i];
+            ci ^= cj;
+            cj ^= ci;
+            ci ^= cj;
+         }
+      }
+   }
+}