From 3f03d2db0ee6cc97fc21009b2be574c445bb4e1b Mon Sep 17 00:00:00 2001 From: nemet Date: Wed, 1 Jul 2009 21:34:58 +0000 Subject: [PATCH] * combine.c (force_to_mode): Handle TRUNCATE. Factor out truncation from operands in binary operations. testsuite/ * gcc.target/mips/truncate-4.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149154 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 5 +++++ gcc/combine.c | 24 ++++++++++++++++++------ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.target/mips/truncate-4.c | 10 ++++++++++ 4 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.target/mips/truncate-4.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b1273fb..93a912d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2009-07-01 Adam Nemet + * combine.c (force_to_mode): Handle TRUNCATE. Factor out + truncation from operands in binary operations. + +2009-07-01 Adam Nemet + Revert: 2009-01-11 Adam Nemet * expmed.c (store_bit_field_1): Properly truncate the paradoxical diff --git a/gcc/combine.c b/gcc/combine.c index b8c080c..a4f0d66 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -7358,6 +7358,10 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask, return force_to_mode (SUBREG_REG (x), mode, mask, next_select); break; + case TRUNCATE: + /* Similarly for a truncate. */ + return force_to_mode (XEXP (x, 0), mode, mask, next_select); + case AND: /* If this is an AND with a constant, convert it into an AND whose constant is the AND of that constant with MASK. If it @@ -7502,12 +7506,20 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask, /* For most binary operations, just propagate into the operation and change the mode if we have an operation of that mode. */ - op0 = gen_lowpart_or_truncate (op_mode, - force_to_mode (XEXP (x, 0), mode, mask, - next_select)); - op1 = gen_lowpart_or_truncate (op_mode, - force_to_mode (XEXP (x, 1), mode, mask, - next_select)); + op0 = force_to_mode (XEXP (x, 0), mode, mask, next_select); + op1 = force_to_mode (XEXP (x, 1), mode, mask, next_select); + + /* If we ended up truncating both operands, truncate the result of the + operation instead. */ + if (GET_CODE (op0) == TRUNCATE + && GET_CODE (op1) == TRUNCATE) + { + op0 = XEXP (op0, 0); + op1 = XEXP (op1, 0); + } + + op0 = gen_lowpart_or_truncate (op_mode, op0); + op1 = gen_lowpart_or_truncate (op_mode, op1); if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0) || op1 != XEXP (x, 1)) x = simplify_gen_binary (code, op_mode, op0, op1); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e929100..6eea718 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2009-07-01 Adam Nemet + + * gcc.target/mips/truncate-4.c: New testcase. + 2009-07-01 Richard Guenther PR tree-optimization/19831 diff --git a/gcc/testsuite/gcc.target/mips/truncate-4.c b/gcc/testsuite/gcc.target/mips/truncate-4.c new file mode 100644 index 0000000..2958be8 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/truncate-4.c @@ -0,0 +1,10 @@ +/* The and is performed in DI mode so there is no need for truncation. */ +/* { dg-options "-O -mgp64" } */ +/* { dg-final { scan-assembler-not "\tsll\t" } } */ + +unsigned long long +f (unsigned long long s) +{ + unsigned u = s & 0xfff; + return u; +} -- 2.7.4