[PATCH] Fix Alpha ICE in if_then_else_cond

Jakub Jelinek jakub@redhat.com
Wed Dec 19 12:03:00 GMT 2001


Hi!

The following testcase ICEs on Alpha.
It happens when simplifying:
(ashiftrt:DI (ashift:DI (subreg:DI (udiv:SI (reg/v:DI 71)
                (ashiftrt:DI (ashift:DI (if_then_else:DI (eq (reg:DI 79)
                                (const_int 0 [0x0]))
                            (reg:DI 76)
                            (const_int 1 [0x1]))
                        (const_int 32 [0x20]))
                    (const_int 32 [0x20]))) 0)
        (const_int 32 [0x20]))
    (const_int 32 [0x20]))
If reg 79 is not equal to 0, the subreg part is first simplified into:
(subreg:DI (udiv:SI (reg/v:DI 71) (const_int 1 [0x1])) 0)
but then simplify_binary_operation optimizes:
(udiv:SI (reg/v:DI 71) (const_int 1 [0x1]))
into
(reg/v:DI 71)
and we ICE soon afterwards, because (subreg:DI (reg/v:DI 71) 0) shouldn't
happen.
I think simplify_binary_operation should return
(subreg:SI (reg/v:DI 71) 0)
instead, since udiv's mode is SI only.
Ok to commit?

2001-12-19  Jakub Jelinek  <jakub@redhat.com>

	* simplify-rtx.c (simplifi_binary_operation) [DIV]: If DIV has
	narrower mode than op0, only return the bits in DIV's mode.

	* gcc.c-torture/compile/20011219-2.c: New test.

--- gcc/testsuite/gcc.c-torture/compile/20011219-2.c.jj	Thu Aug 30 22:30:55 2001
+++ gcc/testsuite/gcc.c-torture/compile/20011219-2.c	Wed Dec 19 20:40:28 2001
@@ -0,0 +1,20 @@
+/* This testcase failed on Alpha at -O2 when simplifying conditional
+   expressions.  */
+
+struct S {
+  unsigned long a;
+  double b, c;
+};
+
+extern double bar (double, double);
+
+int
+foo (unsigned long x, unsigned int y, struct S *z)
+{
+  unsigned int a = z->a;
+  int b = y / z->a > 1 ? y / z->a : 1;
+
+  a = y / b < z->a ? y / b : z->a;
+  z->c = z->b * bar ((double) a, (double) x);
+  return 0;
+}
--- gcc/simplify-rtx.c.jj	Fri Dec 14 13:05:08 2001
+++ gcc/simplify-rtx.c	Wed Dec 19 21:48:13 2001
@@ -1412,7 +1412,10 @@ simplify_binary_operation (code, mode, o
 
 	case DIV:
 	  if (trueop1 == CONST1_RTX (mode))
-	    return op0;
+	    {
+	      rtx x = gen_lowpart_common (mode, op0);
+	      return x ? x : op0;
+	    }
 
 	  /* In IEEE floating point, 0/x is not always 0.  */
 	  if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT

	Jakub



More information about the Gcc-patches mailing list