Is this related to the loop termination bug I reported
on the m32c?
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37665

The generated code is using the lower 16-bits of the
address for end of the array rather than the full 24-bit
address.

--joel


DJ Delorie wrote:
I've got a partial patch which works with older (4.3) gccs, but fails
gimple's check for trunk (attached).  My trivial test case...

char *
foo (char *a, int b)
{
  return a-b;
}

...fails thusly:

 <integer_type 0xb7f52c30 public unsigned SI
    size <integer_cst 0xb7ee7540 type <integer_type 0xb7ef5068 bit_size_type> 
constant 32>
    unit size <integer_cst 0xb7ee72bc type <integer_type 0xb7ef5000 unsigned int> 
constant 4>
    align 8 symtab 0 alias set -1 canonical type 0xb7f52c30 precision 32 min <integer_cst 
0xb7f6a0c4 0> max <integer_cst 0xb7ee7e8c 4294967295>>
 <integer_type 0xb7ef5000 unsigned int public unsigned sizetype HI
    size <integer_cst 0xb7ee7428 type <integer_type 0xb7ef5068 bit_size_type> 
constant 16>
    unit size <integer_cst 0xb7ee7444 type <integer_type 0xb7ef5000 unsigned int> 
constant 2>
    align 8 symtab 0 alias set -1 canonical type 0xb7efc000 precision 16 min <integer_cst 
0xb7ee74d0 0> max <integer_cst 0xb7ee7ad4 -1>>
useless false: ../../gcc/gcc/tree-ssa.c 1092
dj.c: In function 'foo':
dj.c:2: error: type mismatch in pointer plus expression
D.1194 = a + D.1196;

char *

char *

<unnamed-unsigned:32>

D.1194 = a + D.1196;

dj.c:2: internal compiler error: verify_gimple failed


I'm obviously doing something wrong in the cast-to-bigger step.  How
can I get this to pass gimple?  What I'm trying to accomplish is this:

1. Values added to pointers need to be treated as signed (at least, if
   they're signed types, certainly if you're going to use a
   NEGATE_EXPR).

2. If sizeof(size_t) < sizeof(void *), sign extend the intop to be
   pointer-sized before adding it.



Index: c-common.c
===================================================================
--- c-common.c  (revision 140759)
+++ c-common.c  (working copy)
@@ -3337,20 +3337,28 @@ pointer_int_sum (enum tree_code resultco
     intop = convert (c_common_type_for_size (TYPE_PRECISION (sizetype),
                                             TYPE_UNSIGNED (sizetype)), intop);

   /* Replace the integer argument with a suitable product by the object size.
      Do this multiplication as signed, then convert to the appropriate
      type for the pointer operation.  */
-  intop = convert (sizetype,
+  intop = convert (ssizetype,
                   build_binary_op (EXPR_LOCATION (intop),
                                    MULT_EXPR, intop,
                                    convert (TREE_TYPE (intop), size_exp), 1));

   /* Create the sum or difference.  */
   if (resultcode == MINUS_EXPR)
-    intop = fold_build1 (NEGATE_EXPR, sizetype, intop);
+    intop = fold_build1 (NEGATE_EXPR, ssizetype, intop);
+
+  if (TREE_CODE (result_type) == POINTER_TYPE
+      && TYPE_PRECISION (result_type) > TYPE_PRECISION (TREE_TYPE (intop)))
+    {
+      tree iptr_type = c_common_type_for_mode (TYPE_MODE (result_type),
+                                              TYPE_UNSIGNED (result_type));
+      intop = fold_build1 (NOP_EXPR, iptr_type, intop);
+    }

   ret = fold_build2 (POINTER_PLUS_EXPR, result_type, ptrop, intop);

   fold_undefer_and_ignore_overflow_warnings ();

   return ret;
Index: tree.c
===================================================================
--- tree.c      (revision 140759)
+++ tree.c      (working copy)
@@ -3283,15 +3283,21 @@ build2_stat (enum tree_code code, tree t

   if ((code == MINUS_EXPR || code == PLUS_EXPR || code == MULT_EXPR)
       && arg0 && arg1 && tt && POINTER_TYPE_P (tt))
     gcc_assert (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == 
INTEGER_CST);

   if (code == POINTER_PLUS_EXPR && arg0 && arg1 && tt)
-    gcc_assert (POINTER_TYPE_P (tt) && POINTER_TYPE_P (TREE_TYPE (arg0))
-               && INTEGRAL_TYPE_P (TREE_TYPE (arg1))
-               && useless_type_conversion_p (sizetype, TREE_TYPE (arg1)));
+    {
+      gcc_assert (POINTER_TYPE_P (tt));
+      gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg0)));
+      gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (arg1)));
+#if 0
+      gcc_assert (useless_type_conversion_p (sizetype, TREE_TYPE (arg1))
+                 || useless_type_conversion_p (ssizetype, TREE_TYPE (arg1)));
+#endif
+    }

   t = make_node_stat (code PASS_MEM_STAT);
   TREE_TYPE (t) = tt;

   /* Below, we automatically set TREE_SIDE_EFFECTS and TREE_READONLY for the
      result based on those same flags for the arguments.  But if the


--
Joel Sherrill, Ph.D.             Director of Research & Development
[EMAIL PROTECTED]        On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35805
  Support Available             (256) 722-9985


Reply via email to