On Thu, Oct 13, 2011 at 11:15 AM, Richard Kenner <ken...@vlsi1.ultra.nyu.edu> wrote: >> The answer to H.J.'s "Why do we do it for MEM then?" is simply >> "because no one ever thought about not doing it" > > No, that's false. The same expand_compound_operation / > make_compound_operation > pair is present in the MEM case as in the SET case. It's just that > there's some bug here that's noticable in not making proper MEMs that > doesn't show up in the SET case because of the way the insns are structured. >
When we have (and (OP) M) where (and (OP) M) == (and (OP) ((1 << ceil_log2 (M)) - 1) )) (and (OP) M) is zero_extract bits 0 to ceil_log2 (M). Does it look OK? Thanks. -- H.J. --- diff --git a/gcc/combine.c b/gcc/combine.c index 6c3b17c..5962b1d 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -7758,6 +7758,23 @@ make_compound_operation (rtx x, enum rtx_code in_code) next_code), i, NULL_RTX, 1, 1, 0, 1); + + /* If we are (and (OP) M) and M is an extraction mask, this is an + extraction. */ + else + { + unsigned HOST_WIDE_INT nonzero = + nonzero_bits (XEXP (x, 0), GET_MODE (XEXP (x, 0))); + unsigned HOST_WIDE_INT mask = INTVAL (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: