diff options
author | Jakub Jelinek <jakub@redhat.com> | 2013-05-13 13:04:26 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2013-05-13 13:04:26 +0200 |
commit | ae6fa899e7000352aa8573a23b1e92c225337ea1 (patch) | |
tree | 6346bea605532f76d3b46ee9bfb0d6588ee811de /gcc/expmed.c | |
parent | 4502fe8dfcb1cc2c59b50b868ac75fb5cdd742fc (diff) | |
download | gcc-ae6fa899e7000352aa8573a23b1e92c225337ea1.tar.gz |
re PR tree-optimization/45216 (Rotate expressions not recognized at tree level)
PR tree-optimization/45216
PR tree-optimization/57157
* tree-ssa-forwprop.c (simplify_rotate): Only recognize
the (-Y) & (B - 1) variant if OP is |.
* expmed.c (expand_shift_1): For rotations by const0_rtx just
return shifted. Use (-op1) & (prec - 1) as other_amount
instead of prec - op1.
* c-c++-common/rotate-1.c: Add 32 tests with +.
* c-c++-common/rotate-1a.c: Adjust.
* c-c++-common/rotate-2.c: Add 32 tests with +, expect
only 48 rotates.
* c-c++-common/rotate-2b.c: New test.
* c-c++-common/rotate-3.c: Add 32 tests with +.
* c-c++-common/rotate-4.c: Add 32 tests with +, expect
only 48 rotates.
* c-c++-common/rotate-4b.c: New test.
* c-c++-common/rotate-5.c: New test.
From-SVN: r198823
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r-- | gcc/expmed.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c index 3910612da01..6e61e9a402e 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -2166,7 +2166,8 @@ expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted, { /* If we have been unable to open-code this by a rotation, do it as the IOR of two shifts. I.e., to rotate A - by N bits, compute (A << N) | ((unsigned) A >> (C - N)) + by N bits, compute + (A << N) | ((unsigned) A >> ((-N) & (C - 1))) where C is the bitsize of A. It is theoretically possible that the target machine might @@ -2181,14 +2182,22 @@ expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted, rtx temp1; new_amount = op1; - if (CONST_INT_P (op1)) + if (op1 == const0_rtx) + return shifted; + else if (CONST_INT_P (op1)) other_amount = GEN_INT (GET_MODE_BITSIZE (mode) - INTVAL (op1)); else - other_amount - = simplify_gen_binary (MINUS, GET_MODE (op1), - GEN_INT (GET_MODE_PRECISION (mode)), - op1); + { + other_amount + = simplify_gen_unary (NEG, GET_MODE (op1), + op1, GET_MODE (op1)); + other_amount + = simplify_gen_binary (AND, GET_MODE (op1), + other_amount, + GEN_INT (GET_MODE_PRECISION (mode) + - 1)); + } shifted = force_reg (mode, shifted); |