Combine expands things like (zero_extend:DI (lshiftrt:SI (reg:SI) (reg:SI))) to (and:DI (subreg:DI (lshiftrt:SI (reg:SI) (reg:SI)) 0) (const_int 0xffffffff)) to do simplifications on, and then make_compound_operation is supposed to transform it back to the simpler form (with the zero_extend).
But it doesn't; it tries to make a zero_extract and then gives up. This fixes it. Bootstrapped and regression tested on powerpc64-linux (-m32,-m32/-mpowerpc64,-m64,-m64/-mlra); no regressions. Committing. Segher 2015-07-02 Segher Boessenkool <seg...@kernel.crashing.org> PR rtl-optimization/66706 * combine.c (make_compound_operation): If an AND of SUBREG of LSHIFTRT does not simplify, see if just the AND of SUBREG does. --- gcc/combine.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gcc/combine.c b/gcc/combine.c index 8eaae7c..b97aa10 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -7893,6 +7893,15 @@ make_compound_operation (rtx x, enum rtx_code in_code) new_rtx = make_extraction (GET_MODE (SUBREG_REG (XEXP (x, 0))), new_rtx, 0, XEXP (SUBREG_REG (XEXP (x, 0)), 1), i, 1, 0, in_code == COMPARE); + + /* If that didn't give anything, see if the AND simplifies on + its own. */ + if (!new_rtx && i >= 0) + { + new_rtx = make_compound_operation (XEXP (x, 0), next_code); + new_rtx = make_extraction (mode, new_rtx, 0, NULL_RTX, i, 1, + 0, in_code == COMPARE); + } } /* Same as previous, but for (xor/ior (lshiftrt...) (lshiftrt...)). */ else if ((GET_CODE (XEXP (x, 0)) == XOR -- 1.8.1.4