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]

[PATCH] Fix LRA ICE in lra_substitute_pseudo on DEBUG_INSN (PR rtl-optimization/83723)


Hi!

Unlike normal insns where SUBREGs must properly validate, in
DEBUG_INSNs we allow arbitrary SUBREGs, either the dwarf2out code
will be able to use it, or it will just punt.  The reason for it is
among other things that during analysis we usually need to ignore
debug insns, so can't reject some optimization just because it would
create subreg in debug insn that doesn't validate, and resetting such
debug insns is too big hammer.

On the following testcase on i?86 we ICE because we have a SFmode
pseudo and want to use a XFmode new_reg for it and such subreg doesn't
validate on i386.

Fixed by using gen_rtx_raw_SUBREG in DEBUG_INSNs as other passes do.
We don't have gen_lowpart_raw_SUBREG, so the patch inlines what
gen_lowpart_SUBREG does to compute the offset and uses gen_rtx_{,raw_}SUBREG
in all cases.  Bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2018-02-14  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/83723
	* lra-int.h (lra_substitute_pseudo): Add DEBUG_P argument.
	* lra.c (lra_substitute_pseudo): Likewise.  If true, use
	gen_rtx_raw_SUBREG instead of gen_rtx_SUBREG.  Pass DEBUG_P to
	recursive calls.
	(lra_substitute_pseudo_within_insn): Adjust lra_substitute_pseudo
	callers.
	* lra-constraints.c (inherit_reload_reg, split_reg): Likewise.

	* gcc.dg/pr83723.c: New test.

--- gcc/lra-int.h.jj	2018-01-03 10:19:53.848533738 +0100
+++ gcc/lra-int.h	2018-02-14 10:48:21.246324445 +0100
@@ -309,7 +309,7 @@ extern void lra_update_dups (lra_insn_re
 extern void lra_process_new_insns (rtx_insn *, rtx_insn *, rtx_insn *,
 				   const char *);
 
-extern bool lra_substitute_pseudo (rtx *, int, rtx, bool);
+extern bool lra_substitute_pseudo (rtx *, int, rtx, bool, bool);
 extern bool lra_substitute_pseudo_within_insn (rtx_insn *, int, rtx, bool);
 
 extern lra_insn_recog_data_t lra_set_insn_recog_data (rtx_insn *);
--- gcc/lra.c.jj	2018-01-03 10:19:54.726533889 +0100
+++ gcc/lra.c	2018-02-14 10:47:52.033315369 +0100
@@ -1893,9 +1893,11 @@ lra_process_new_insns (rtx_insn *insn, r
 
 /* Replace all references to register OLD_REGNO in *LOC with pseudo
    register NEW_REG.  Try to simplify subreg of constant if SUBREG_P.
-   Return true if any change was made.  */
+   DEBUG_P is if LOC is within a DEBUG_INSN.  Return true if any
+   change was made.  */
 bool
-lra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg, bool subreg_p)
+lra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg, bool subreg_p,
+		       bool debug_p)
 {
   rtx x = *loc;
   bool result = false;
@@ -1931,11 +1933,14 @@ lra_substitute_pseudo (rtx *loc, int old
       if (mode != inner_mode
 	  && ! (CONST_INT_P (new_reg) && SCALAR_INT_MODE_P (mode)))
 	{
-	  if (!partial_subreg_p (mode, inner_mode)
-	      || ! SCALAR_INT_MODE_P (inner_mode))
-	    new_reg = gen_rtx_SUBREG (mode, new_reg, 0);
+	  poly_uint64 offset = 0;
+	  if (partial_subreg_p (mode, inner_mode)
+	      && SCALAR_INT_MODE_P (inner_mode))
+	    offset = subreg_lowpart_offset (mode, inner_mode);
+	  if (debug_p)
+	    new_reg = gen_rtx_raw_SUBREG (mode, new_reg, offset);
 	  else
-	    new_reg = gen_lowpart_SUBREG (mode, new_reg);
+	    new_reg = gen_rtx_SUBREG (mode, new_reg, offset);
 	}
       *loc = new_reg;
       return true;
@@ -1948,14 +1953,14 @@ lra_substitute_pseudo (rtx *loc, int old
       if (fmt[i] == 'e')
 	{
 	  if (lra_substitute_pseudo (&XEXP (x, i), old_regno,
-				     new_reg, subreg_p))
+				     new_reg, subreg_p, debug_p))
 	    result = true;
 	}
       else if (fmt[i] == 'E')
 	{
 	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
 	    if (lra_substitute_pseudo (&XVECEXP (x, i, j), old_regno,
-				       new_reg, subreg_p))
+				       new_reg, subreg_p, debug_p))
 	      result = true;
 	}
     }
@@ -1970,7 +1975,8 @@ lra_substitute_pseudo_within_insn (rtx_i
 				   rtx new_reg, bool subreg_p)
 {
   rtx loc = insn;
-  return lra_substitute_pseudo (&loc, old_regno, new_reg, subreg_p);
+  return lra_substitute_pseudo (&loc, old_regno, new_reg, subreg_p,
+				DEBUG_INSN_P (insn));
 }
 
 
--- gcc/lra-constraints.c.jj	2018-02-09 06:44:36.392805568 +0100
+++ gcc/lra-constraints.c	2018-02-14 10:49:22.193340178 +0100
@@ -5287,7 +5287,8 @@ inherit_reload_reg (bool def_p, int orig
 	  lra_assert (DEBUG_INSN_P (usage_insn));
 	  next_usage_insns = XEXP (next_usage_insns, 1);
 	}
-      lra_substitute_pseudo (&usage_insn, original_regno, new_reg, false);
+      lra_substitute_pseudo (&usage_insn, original_regno, new_reg, false,
+			     DEBUG_INSN_P (usage_insn));
       lra_update_insn_regno_info (as_a <rtx_insn *> (usage_insn));
       if (lra_dump_file != NULL)
 	{
@@ -5608,7 +5609,8 @@ split_reg (bool before_p, int original_r
       usage_insn = XEXP (next_usage_insns, 0);
       lra_assert (DEBUG_INSN_P (usage_insn));
       next_usage_insns = XEXP (next_usage_insns, 1);
-      lra_substitute_pseudo (&usage_insn, original_regno, new_reg, false);
+      lra_substitute_pseudo (&usage_insn, original_regno, new_reg, false,
+			     true);
       lra_update_insn_regno_info (as_a <rtx_insn *> (usage_insn));
       if (lra_dump_file != NULL)
 	{
--- gcc/testsuite/gcc.dg/pr83723.c.jj	2018-02-14 10:58:46.269441787 +0100
+++ gcc/testsuite/gcc.dg/pr83723.c	2018-02-14 11:00:07.780456471 +0100
@@ -0,0 +1,20 @@
+/* PR rtl-optimization/83723 */
+/* { dg-do compile } */
+/* { dg-options "-g -O2" } */
+/* { dg-additional-options "-mfpmath=sse -msse2" { target i?86-*-* x86_64-*-* } } */
+/* { dg-additional-options "-fpie" { target pie } } */
+
+int foo (void);
+float bar (float);
+int *v;
+
+void
+baz (void)
+{
+  float a = bar (0.0);
+  bar (a);
+  if (v)
+    bar (1.0);
+  if (a < 1.0)
+    a = foo () / a;
+}

	Jakub


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