Blame SOURCES/gcc48-pr58997.patch

543165
2013-11-05  Jakub Jelinek  <jakub@redhat.com>
543165
543165
	PR rtl-optimization/58997
543165
	* loop-iv.c (iv_subreg): For IV_UNKNOWN_EXTEND, expect
543165
	get_iv_value to be in iv->mode rather than iv->extend_mode.
543165
	(iv_extend): Likewise.  Otherwise, if iv->extend != extend,
543165
	use lowpart_subreg on get_iv_value before calling simplify_gen_unary.
543165
	* loop-unswitch.c (may_unswitch_on): Make sure op[i] is in the right
543165
	mode.
543165
543165
	* gcc.c-torture/compile/pr58997.c: New test.
543165
543165
--- gcc/loop-unswitch.c	(revision 204412)
543165
+++ gcc/loop-unswitch.c	(revision 204413)
543165
@@ -191,6 +191,7 @@ may_unswitch_on (basic_block bb, struct
543165
   if (!test)
543165
     return NULL_RTX;
543165
 
543165
+  mode = VOIDmode;
543165
   for (i = 0; i < 2; i++)
543165
     {
543165
       op[i] = XEXP (test, i);
543165
@@ -205,11 +206,15 @@ may_unswitch_on (basic_block bb, struct
543165
 	return NULL_RTX;
543165
 
543165
       op[i] = get_iv_value (&iv, const0_rtx);
543165
+      if (iv.extend != IV_UNKNOWN_EXTEND
543165
+	  && iv.mode != iv.extend_mode)
543165
+	op[i] = lowpart_subreg (iv.mode, op[i], iv.extend_mode);
543165
+      if (mode == VOIDmode)
543165
+	mode = iv.mode;
543165
+      else
543165
+	gcc_assert (mode == iv.mode);
543165
     }
543165
 
543165
-  mode = GET_MODE (op[0]);
543165
-  if (mode == VOIDmode)
543165
-    mode = GET_MODE (op[1]);
543165
   if (GET_MODE_CLASS (mode) == MODE_CC)
543165
     {
543165
       if (at != BB_END (bb))
543165
--- gcc/loop-iv.c	(revision 204412)
543165
+++ gcc/loop-iv.c	(revision 204413)
543165
@@ -436,7 +436,9 @@ iv_subreg (struct rtx_iv *iv, enum machi
543165
       && !iv->first_special)
543165
     {
543165
       rtx val = get_iv_value (iv, const0_rtx);
543165
-      val = lowpart_subreg (mode, val, iv->extend_mode);
543165
+      val = lowpart_subreg (mode, val,
543165
+			    iv->extend == IV_UNKNOWN_EXTEND
543165
+			    ? iv->mode : iv->extend_mode);
543165
 
543165
       iv->base = val;
543165
       iv->extend = IV_UNKNOWN_EXTEND;
543165
@@ -476,8 +478,14 @@ iv_extend (struct rtx_iv *iv, enum iv_ex
543165
       && !iv->first_special)
543165
     {
543165
       rtx val = get_iv_value (iv, const0_rtx);
543165
+      if (iv->extend_mode != iv->mode
543165
+	  && iv->extend != IV_UNKNOWN_EXTEND
543165
+	  && iv->extend != extend)
543165
+	val = lowpart_subreg (iv->mode, val, iv->extend_mode);
543165
       val = simplify_gen_unary (iv_extend_to_rtx_code (extend), mode,
543165
-				val, iv->extend_mode);
543165
+				val,
543165
+				iv->extend == extend
543165
+				? iv->extend_mode : iv->mode);
543165
       iv->base = val;
543165
       iv->extend = IV_UNKNOWN_EXTEND;
543165
       iv->mode = iv->extend_mode = mode;
543165
--- gcc/testsuite/gcc.c-torture/compile/pr58997.c	(revision 0)
543165
+++ gcc/testsuite/gcc.c-torture/compile/pr58997.c	(revision 204413)
543165
@@ -0,0 +1,19 @@
543165
+/* PR rtl-optimization/58997 */
543165
+
543165
+int a, b, c, e;
543165
+short d;
543165
+char h;
543165
+
543165
+void
543165
+foo ()
543165
+{
543165
+  while (b)
543165
+    {
543165
+      d = a ? c : 1 % a;
543165
+      c = d;
543165
+      h = d;
543165
+      if (!h)
543165
+	while (e)
543165
+	  ;
543165
+    }
543165
+}