On Thu, Oct 13, 2011 at 11:15 AM, Richard Kenner
<[email protected]> 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: