re PR rtl-optimization/14235 (ICE in verify_local_live_at start (flow.c:546))
authorEric Botcazou <ebotcazou@libertysurf.fr>
Thu, 4 Mar 2004 09:01:03 +0000 (10:01 +0100)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 4 Mar 2004 09:01:03 +0000 (09:01 +0000)
PR optimization/14235
* expr.c (convert_move): Copy the source to a new pseudo
when converting from a sub-word source to a larger-than-word
register which conflicts with the source.

From-SVN: r78893

gcc/ChangeLog
gcc/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/20040304-1.c [new file with mode: 0644]

index f1dd35f5dc74140d2d0cbf3ec4566991f818f394..3c6aae3558b0ac3c516692c1500227ae2e3a7114 100644 (file)
@@ -1,3 +1,10 @@
+2004-03-04  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       PR optimization/14235
+       * expr.c (convert_move): Copy the source to a new pseudo
+       when converting from a sub-word source to a larger-than-word
+       register which conflicts with the source.
+
 2004-03-03  Zack Weinberg  <zack@codesourcery.com>
 
        PR 13728
index e2063c1950f06a69a32c522d4e8f883980a125a7..14809498a937046c7779336ce10d005b92c78e4c 100644 (file)
@@ -682,7 +682,11 @@ convert_move (rtx to, rtx from, int unsignedp)
                   != CODE_FOR_nothing))
        {
          if (GET_CODE (to) == REG)
-           emit_insn (gen_rtx_CLOBBER (VOIDmode, to));
+           {
+             if (reg_overlap_mentioned_p (to, from))
+               from = force_reg (from_mode, from);
+             emit_insn (gen_rtx_CLOBBER (VOIDmode, to));
+           }
          convert_move (gen_lowpart (word_mode, to), from, unsignedp);
          emit_unop_insn (code, to,
                          gen_lowpart (word_mode, to), equiv_code);
index b0edee4d54a3238879ed42e01f957221cdb33fff..931439d24b5a2b13fb98a14aa7fc3b6e1b202c09 100644 (file)
@@ -1,3 +1,7 @@
+2004-03-04  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       * gcc.c-torture/compile/20040304-1.c: New test.
+
 2004-03-03  Zack Weinberg  <zack@codesourcery.com>
 
        PR 13728
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040304-1.c b/gcc/testsuite/gcc.c-torture/compile/20040304-1.c
new file mode 100644 (file)
index 0000000..146d42f
--- /dev/null
@@ -0,0 +1,45 @@
+/* PR optimization/14235 */
+/* Origin: <senor_fjord@yahoo.com> */
+
+typedef signed char        int8_t;
+typedef short              int16_t;
+typedef int                int32_t;
+typedef unsigned long long uint64_t;
+
+static const uint64_t LOW_BYTE_MASK    = 0x00000000000000ffULL;
+static const uint64_t HIGH_BYTE_MASK   = 0x000000000000ff00ULL;
+static const uint64_t WORD_MASK        = 0x000000000000ffffULL;
+static const uint64_t DWORD_MASK       = 0x00000000ffffffffULL;
+
+extern uint64_t *srca_mask;
+extern int *assert_thrown;
+
+void foo()
+{
+  uint64_t tempA = 0; /* actually a bunch of code to set A */ 
+  uint64_t tempB = 0; /* actually a bunch of code to set B */ 
+
+  /* cast A to right size */
+  tempA = (((*srca_mask == LOW_BYTE_MASK) || 
+            (*srca_mask == HIGH_BYTE_MASK)) ?
+           ((int8_t)tempA) : 
+           ((*srca_mask == WORD_MASK) ? 
+            ((int16_t)tempA) : 
+            ((*srca_mask == DWORD_MASK) ? 
+             ((int32_t)tempA) : 
+             tempA)));
+
+  /* cast B to right size */
+  tempB = (((*srca_mask == LOW_BYTE_MASK) || 
+            (*srca_mask == HIGH_BYTE_MASK)) ? 
+           ((int8_t)tempB) : 
+           ((*srca_mask == WORD_MASK) ? 
+            ((int16_t)tempB) : 
+            ((*srca_mask == DWORD_MASK) ? 
+             ((int32_t)tempB) : 
+             tempB))); 
+    
+  if ((int) tempA > (int) tempB) { 
+    *assert_thrown = 1;
+  }
+}