Hi,
  The problem here is lra_substitute_pseudo calls gen_rtx_SUBREG with
a VOIDmode (const_int) argument but really it should not be calling
gen_rtx_SUBREG directly instead it should be using
gen_lowpart_if_possible.  This patch fixes that and adds a testcase
that had happened on x86_64.

OK? I bootstrapped and tested this on both aarch64-linux-gnu and
x86_64-linux-gnu with no regression on either.

Thanks,
Andrew Pinski

ChangeLog:
        * lra.c (lra_substitute_pseudo): Use gen_lowpart_if_possible
        instead of gen_rtx_SUBREG/gen_lowpart_SUBREG.

testsuite/ChangeLog:

        * gcc.dg/pr64061.c: New testcase.
Index: testsuite/gcc.dg/pr64061.c
===================================================================
--- testsuite/gcc.dg/pr64061.c  (revision 0)
+++ testsuite/gcc.dg/pr64061.c  (revision 0)
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -g -fno-dce -fno-tree-dce" } */
+extern void *buf;
+
+extern void bar (void);
+
+int
+foo (int i)
+{
+  int j = 0;
+  if (__builtin_setjmp (buf) == 0)
+    {
+      while (1)
+       {
+         j = 1;
+         bar ();
+       }
+    }
+  return j ? i : 0;
+}
Index: lra.c
===================================================================
--- lra.c       (revision 218071)
+++ lra.c       (working copy)
@@ -1807,13 +1807,7 @@ lra_substitute_pseudo (rtx *loc, int old
       machine_mode inner_mode = GET_MODE (new_reg);
 
       if (mode != inner_mode)
-       {
-         if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (inner_mode)
-             || ! SCALAR_INT_MODE_P (inner_mode))
-           new_reg = gen_rtx_SUBREG (mode, new_reg, 0);
-         else
-           new_reg = gen_lowpart_SUBREG (mode, new_reg);
-       }
+       new_reg = gen_lowpart_if_possible (mode, new_reg);
       *loc = new_reg;
       return true;
     }

Reply via email to