diff options
author | Adam Nemet <anemet@caviumnetworks.com> | 2009-07-01 21:34:58 +0000 |
---|---|---|
committer | Adam Nemet <nemet@gcc.gnu.org> | 2009-07-01 21:34:58 +0000 |
commit | 479b101323d7601d991a72ba79fc4f3a7dccaebc (patch) | |
tree | 7a605c8f7cca36b8978bff57e5aa90fb6575c756 /gcc/combine.c | |
parent | c600a15524cc3200cd4ee3997e162e9205b79a70 (diff) | |
download | gcc-479b101323d7601d991a72ba79fc4f3a7dccaebc.zip gcc-479b101323d7601d991a72ba79fc4f3a7dccaebc.tar.gz gcc-479b101323d7601d991a72ba79fc4f3a7dccaebc.tar.bz2 |
combine.c (force_to_mode): Handle TRUNCATE.
* combine.c (force_to_mode): Handle TRUNCATE. Factor out
truncation from operands in binary operations.
testsuite/
* gcc.target/mips/truncate-4.c: New testcase.
From-SVN: r149154
Diffstat (limited to 'gcc/combine.c')
-rw-r--r-- | gcc/combine.c | 24 |
1 files changed, 18 insertions, 6 deletions
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); |