If we have (truncate:M1 (and:M2 (lshiftrt:M2 (x:M2) C) C2))
we can write it instead as (and:M1 (lshiftrt:M1 (truncate:M1 (x:M2)) C) C2) (if that is valid, of course), which has smaller modes for the binary ops, and the truncate can often simplify further (if "x" is a register, for example). This fixes gcc.target/powerpc/20050603-3.c for -m32 -mpowerpc64; also that test is currently restricted to ilp32, but we can run it with lp64 just fine, in which case it fixes that, too. Bootstrapped and tested on powerpc64-linux (-m32,-m32/-mpowerpc64,-m64). Is this okay for trunk? Segher 2015-11-09 Segher Boessenkool <seg...@kernel.crashing.org> * gcc/simplify-rtx.c (simplify_truncation): Simplify TRUNCATE of AND of [LA]SHIFTRT. --- gcc/simplify-rtx.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 17568ba..1adb393 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -714,6 +714,31 @@ simplify_truncation (machine_mode mode, rtx op, return simplify_gen_binary (ASHIFT, mode, XEXP (XEXP (op, 0), 0), XEXP (op, 1)); + /* Likewise (truncate:QI (and:SI (lshiftrt:SI (x:SI) C) C2)) into + (and:QI (lshiftrt:QI (truncate:QI (x:SI)) C) C2) for suitable C + and C2. */ + if (GET_CODE (op) == AND + && (GET_CODE (XEXP (op, 0)) == LSHIFTRT + || GET_CODE (XEXP (op, 0)) == ASHIFTRT) + && CONST_INT_P (XEXP (XEXP (op, 0), 1)) + && CONST_INT_P (XEXP (op, 1)) + && UINTVAL (XEXP (XEXP (op, 0), 1)) < precision + && ((GET_MODE_MASK (mode) >> UINTVAL (XEXP (XEXP (op, 0), 1))) + & UINTVAL (XEXP (op, 1))) + == ((GET_MODE_MASK (op_mode) >> UINTVAL (XEXP (XEXP (op, 0), 1))) + & UINTVAL (XEXP (op, 1)))) + { + rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (XEXP (op, 0), 0), + op_mode); + if (op0) + { + op0 = simplify_gen_binary (LSHIFTRT, mode, op0, + XEXP (XEXP (op, 0), 1)); + if (op0) + return simplify_gen_binary (AND, mode, op0, XEXP (op, 1)); + } + } + /* Recognize a word extraction from a multi-word subreg. */ if ((GET_CODE (op) == LSHIFTRT || GET_CODE (op) == ASHIFTRT) -- 1.9.3