On Thu, Oct 13, 2011 at 3:33 PM, Richard Kenner <ken...@vlsi1.ultra.nyu.edu> wrote: >> I am testing this patch. The difference is it checks nonzero >> bits of the first operand. > > I would suggest moving (and expanding) the comments from the existing block > into your new block. >
Like ths? -- H.J. --- diff --git a/gcc/combine.c b/gcc/combine.c index 6c3b17c..4b57b88 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -7739,16 +7739,6 @@ make_compound_operation (rtx x, enum rtx_code in_code) XEXP (XEXP (x, 0), 1))); } - /* If the constant is one less than a power of two, this might be - representable by an extraction even if no shift is present. - If it doesn't end up being a ZERO_EXTEND, we will ignore it unless - we are in a COMPARE. */ - else if ((i = exact_log2 (UINTVAL (XEXP (x, 1)) + 1)) >= 0) - new_rtx = make_extraction (mode, - make_compound_operation (XEXP (x, 0), - next_code), - 0, NULL_RTX, i, 1, 0, in_code == COMPARE); - /* If we are in a comparison and this is an AND with a power of two, convert this into the appropriate bit extract. */ else if (in_code == COMPARE @@ -7758,6 +7748,26 @@ make_compound_operation (rtx x, enum rtx_code in_code) next_code), i, NULL_RTX, 1, 1, 0, 1); + /* If the constant is an extraction mask with the zero bits in + the first operand ignored, this might be representable by an + extraction even if no shift is present. If it doesn't end up + being a ZERO_EXTEND, we will ignore it unless we are in a + COMPARE. */ + else + { + unsigned HOST_WIDE_INT nonzero = + nonzero_bits (XEXP (x, 0), GET_MODE (XEXP (x, 0))); + unsigned HOST_WIDE_INT mask = UINTVAL (XEXP (x, 1)); + unsigned HOST_WIDE_INT len = ceil_log2 (mask); + if ((nonzero & (((unsigned HOST_WIDE_INT) 1 << len) - 1)) + == (nonzero & mask)) + { + new_rtx = make_compound_operation (XEXP (x, 0), next_code); + new_rtx = make_extraction (mode, new_rtx, 0, NULL_RTX, + len, 1, 0, in_code == COMPARE); + } + } + break; case LSHIFTRT: