diff mbox

Handle truncate of a memory location

Message ID CA+=Sn1=akrDQVF5GQ3Odzk63nwQybrAk4EG_GpNT6iExDae9CQ@mail.gmail.com
State New
Headers show

Commit Message

Andrew Pinski Aug. 27, 2012, 9:21 p.m. UTC
Hi,
  A truncate of a memory location can be simplified to a memory load
just like what is done for a subreg of a memory load.
This patch adds that simplification to simplify-rtx.c.

OK? Bootstrapped and tested on mips64-linux-gnu with no regressions.

Thanks,
Andrew Pinski

ChangeLog:

* simplify-rtx.c (simplify_unary_operation_1 <case TRUNCATE>):
A truncate of a memory is just loading the low part of the memory.

testsuite/ChangeLog:
* gcc.target/mips/truncate-8.c: New testcase.

Comments

Richard Sandiford Sept. 1, 2012, 8:54 a.m. UTC | #1
Sorry for the slow review.

Andrew Pinski <pinskia@gmail.com> writes:
> Index: simplify-rtx.c
> ===================================================================
> --- simplify-rtx.c	(revision 190730)
> +++ simplify-rtx.c	(working copy)
> @@ -869,6 +869,14 @@ simplify_unary_operation_1 (enum rtx_cod
>  	  && COMPARISON_P (op)
>  	  && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0)
>  	return rtl_hooks.gen_lowpart_no_emit (mode, op);
> +
> +      /* A truncate of a memory is just loading the low part of the memory
> +	 if are not changing the meaning of the address. */
> +      if (GET_CODE (op) == MEM
> +	  && !MEM_VOLATILE_P (op)
> +	  && !mode_dependent_address_p (XEXP (op, 0)))
> +	return rtl_hooks.gen_lowpart_no_emit (mode, op);

"if we are not..."

> Index: testsuite/gcc.target/mips/truncate-8.c
> ===================================================================
> --- testsuite/gcc.target/mips/truncate-8.c	(revision 0)
> +++ testsuite/gcc.target/mips/truncate-8.c	(revision 0)
> @@ -0,0 +1,17 @@
> +/* { dg-options "-mgp64" } */
> +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
> +/* { dg-final { scan-assembler "lw\t" } } */

"\tlw\t".  Might be better to use:

/* { dg-final { scan-assembler-times "\tlw\t" 1 } } */

and add:

/* { dg-final { scan-assembler-not "\tld" } } */

just to make sure that there really is only one load in the output
(which there ought to be for something as simple as this).

> +/* { dg-final { scan-assembler-not "sll" } } */

"\td?sll"

OK with those changes, thanks.

Richard
diff mbox

Patch

Index: simplify-rtx.c
===================================================================
--- simplify-rtx.c	(revision 190730)
+++ simplify-rtx.c	(working copy)
@@ -869,6 +869,14 @@  simplify_unary_operation_1 (enum rtx_cod
 	  && COMPARISON_P (op)
 	  && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0)
 	return rtl_hooks.gen_lowpart_no_emit (mode, op);
+
+      /* A truncate of a memory is just loading the low part of the memory
+	 if are not changing the meaning of the address. */
+      if (GET_CODE (op) == MEM
+	  && !MEM_VOLATILE_P (op)
+	  && !mode_dependent_address_p (XEXP (op, 0)))
+	return rtl_hooks.gen_lowpart_no_emit (mode, op);
+
       break;
 
     case FLOAT_TRUNCATE:
Index: testsuite/gcc.target/mips/truncate-8.c
===================================================================
--- testsuite/gcc.target/mips/truncate-8.c	(revision 0)
+++ testsuite/gcc.target/mips/truncate-8.c	(revision 0)
@@ -0,0 +1,17 @@ 
+/* { dg-options "-mgp64" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+/* { dg-final { scan-assembler "lw\t" } } */
+/* { dg-final { scan-assembler-not "sll" } } */
+
+struct s
+{
+  long long a;
+  int b;
+};
+
+int
+foo (struct s *x)
+{
+  return x->a;
+}
+