This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[testcase] 3.{1,1.1,2} ICE on IA-32


Hi!

The following testcase ICEs on IA-32. The reason is that precondition_loop_p
computes initial_value as
(ashift:SI (plus:SI (reg/v:SI 63) (const_int -1 [0xffffffff])) (const_int 12 [0xc]))
(this comes from fold_rtx_mult_add) and doloop.c (doloop_modify_runtime)
  /* abs (final - initial)  */
  diff = expand_simple_binop (mode, MINUS,
                              copy_rtx (neg_inc ? initial_value : final_value),
                              copy_rtx (neg_inc ? final_value : initial_value),
                              NULL_RTX, unsigned_p, OPTAB_LIB_WIDEN);
passes these to expand_simple_binop.
This results in
(insn 169 162 171 (set (reg:SI 90)
        (ashift:SI (plus:SI (reg/v:SI 63)
                (const_int -1 [0xffffffff]))
            (const_int 12 [0xc]))) -1 (insn_list 28 (nil))
    (nil))
instruction which of course cannot be recognized.
force_reg wouldn't help here, it would result in the identical instruction.

Now, what's the right fix for this?

Disallowing this from being assigned into initial_value could kill
some optimization options (e.g. when it is possible to
simplify the difference between initial_value and final_value).

Should the fix be some force_reg like function for loop which would try to
recog the instruction and if it would not recognize it, would go
inside PLUS, MULT or ASHIFT, maybe others, and first do force_reg on the
argument, then on the whole pattern with the arguments replaced by the
registers (and should it add REG_EQUIV in that case or not)?

Or should doloop_modify_runtime try to recog all instructions it generated
in the sequence and if any of them fails to recognize, bail out?

2002-07-29  Jakub Jelinek  <jakub@redhat.com>

	* gcc.dg/20020729-1.c: New test.

--- gcc/testsuite/gcc.dg/20020729-1.c.jj	2002-07-23 20:50:16.000000000 +0200
+++ gcc/testsuite/gcc.dg/20020729-1.c	2002-07-29 15:03:23.000000000 +0200
@@ -0,0 +1,51 @@
+/* { dg-do compile { target i?86-*-* } } */
+/* { dg-options "-O2 -march=k6" } */
+
+static inline void *
+baz (void *s, unsigned long c, unsigned int count)
+{
+  int d0, d1;
+  __asm__ __volatile__ (""
+			: "=&c" (d0), "=&D" (d1)
+			:"a" (c), "q" (count), "0" (count / 4), "1" ((long) s)
+			:"memory");
+  return s;
+}
+
+struct A
+{
+  unsigned long *a;
+};
+
+inline static void *
+bar (struct A *x, int y)
+{
+  char *ptr;
+
+  ptr = (void *) x->a[y >> 12];
+  ptr += y % (1UL << 12);
+  return (void *) ptr;
+}
+
+int
+foo (struct A *x, unsigned int *y, int z, int u)
+{
+  int a, b, c, d, e;
+
+  z += *y;
+  c = z + u;
+  a = (z >> 12) + 1;
+  do
+    {
+      b = (a << 12);
+      d = b - z;
+      e = c - z;
+      if (e < d)
+	d = e;
+      baz (bar (x, z), 0, d);
+      z = b;
+      a++;
+    }
+  while (z < c);
+  return 0;
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]