public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Make sure shift amount in RTL is not wider than shift mode (PR rtl-optimization/65321)
@ 2015-03-09 21:23 Jakub Jelinek
  2015-03-10  1:07 ` Jeff Law
  0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2015-03-09 21:23 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

Hi!

As mentioned in the PR, e.g. wide-int is very unhappy if the shift second
operand doesn't fit into the shift mode.
Generally, the backend shift patterns ensure that, but in debug insns
nothing enforces that.

This patch fixes that by making sure e.g. QImode shifts have always at
QImode shift amount, HImode shifts have QImode or HImode shift amount etc.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2015-03-09  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/65321
	* cfgexpand.c (expand_debug_expr): Ensure shift amount isn't wider
	than shift mode.
	* var-tracking.c (use_narrower_mode): Likewise.

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

--- gcc/cfgexpand.c.jj	2015-03-09 08:05:13.000000000 +0100
+++ gcc/cfgexpand.c	2015-03-09 09:15:38.139652882 +0100
@@ -3921,6 +3921,31 @@ expand_debug_expr (tree exp)
       op1 = expand_debug_expr (TREE_OPERAND (exp, 1));
       if (!op1)
 	return NULL_RTX;
+      switch (TREE_CODE (exp))
+	{
+	case LSHIFT_EXPR:
+	case RSHIFT_EXPR:
+	case LROTATE_EXPR:
+	case RROTATE_EXPR:
+	case WIDEN_LSHIFT_EXPR:
+	  /* Ensure second operand isn't wider than the first one.  */
+	  inner_mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 1)));
+	  if (SCALAR_INT_MODE_P (inner_mode))
+	    {
+	      machine_mode opmode = mode;
+	      if (VECTOR_MODE_P (mode))
+		opmode = GET_MODE_INNER (mode);
+	      if (SCALAR_INT_MODE_P (opmode)
+		  && (GET_MODE_PRECISION (opmode)
+		      < GET_MODE_PRECISION (inner_mode)))
+		op1 = simplify_gen_subreg (opmode, op1, inner_mode,
+					   subreg_lowpart_offset (opmode,
+								  inner_mode));
+	    }
+	  break;
+	default:
+	  break;
+	}
       /* Fall through.  */
 
     unary:
--- gcc/var-tracking.c.jj	2015-01-15 20:25:40.000000000 +0100
+++ gcc/var-tracking.c	2015-03-09 09:07:00.042127704 +0100
@@ -1011,7 +1011,13 @@ use_narrower_mode (rtx x, machine_mode m
       return simplify_gen_binary (GET_CODE (x), mode, op0, op1);
     case ASHIFT:
       op0 = use_narrower_mode (XEXP (x, 0), mode, wmode);
-      return simplify_gen_binary (ASHIFT, mode, op0, XEXP (x, 1));
+      op1 = XEXP (x, 1);
+      /* Ensure shift amount is not wider than mode.  */
+      if (GET_MODE (op1) == VOIDmode)
+	op1 = lowpart_subreg (mode, op1, wmode);
+      else if (GET_MODE_PRECISION (mode) < GET_MODE_PRECISION (GET_MODE (op1)))
+	op1 = lowpart_subreg (mode, op1, GET_MODE (op1));
+      return simplify_gen_binary (ASHIFT, mode, op0, op1);
     default:
       gcc_unreachable ();
     }
--- gcc/testsuite/gcc.dg/pr65321.c.jj	2015-03-09 09:10:32.110658776 +0100
+++ gcc/testsuite/gcc.dg/pr65321.c	2015-03-09 09:10:19.000000000 +0100
@@ -0,0 +1,31 @@
+/* PR rtl-optimization/65321 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -g" } */
+
+int a, b, c, d, e;
+
+int
+foo (void)
+{
+  int h;
+  char i;
+  for (; c > 0;)
+    {
+      for (d = 0; d < 2; d++)
+	{
+	  i = 1 << d;
+	  if (i - a)
+	    {
+	      e = b = 0;
+	      for (; c; c--)
+		d = 127;
+	    }
+	}
+      h = ~d;
+      if (h > c)
+	for (;;)
+	  ;
+      return 0;
+    }
+  return 0;
+}

	Jakub

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Make sure shift amount in RTL is not wider than shift mode (PR rtl-optimization/65321)
  2015-03-09 21:23 [PATCH] Make sure shift amount in RTL is not wider than shift mode (PR rtl-optimization/65321) Jakub Jelinek
@ 2015-03-10  1:07 ` Jeff Law
  0 siblings, 0 replies; 2+ messages in thread
From: Jeff Law @ 2015-03-10  1:07 UTC (permalink / raw)
  To: Jakub Jelinek, Richard Biener; +Cc: gcc-patches

On 03/09/15 15:23, Jakub Jelinek wrote:
> Hi!
>
> As mentioned in the PR, e.g. wide-int is very unhappy if the shift second
> operand doesn't fit into the shift mode.
> Generally, the backend shift patterns ensure that, but in debug insns
> nothing enforces that.
>
> This patch fixes that by making sure e.g. QImode shifts have always at
> QImode shift amount, HImode shifts have QImode or HImode shift amount etc.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2015-03-09  Jakub Jelinek  <jakub@redhat.com>
>
> 	PR rtl-optimization/65321
> 	* cfgexpand.c (expand_debug_expr): Ensure shift amount isn't wider
> 	than shift mode.
> 	* var-tracking.c (use_narrower_mode): Likewise.
>
> 	* gcc.dg/pr65321.c: New test.
OK.

jeff

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-03-10  1:07 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-09 21:23 [PATCH] Make sure shift amount in RTL is not wider than shift mode (PR rtl-optimization/65321) Jakub Jelinek
2015-03-10  1:07 ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).