From: Richard Kenner Date: Sat, 26 Jun 1993 15:06:55 +0000 (-0400) Subject: (subst): apply_distributive_law can also handle AND. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=224eeff2ea7cee133a2614f9562d6fa8bfeb0a85;p=gcc.git (subst): apply_distributive_law can also handle AND. (subst, case IF_THEN_ELSE): Make a shift when appropriate. (simplify_shift_const): If we have an outer operation and made a shift, see if it can be simplified. From-SVN: r4748 --- diff --git a/gcc/combine.c b/gcc/combine.c index 7aa534879f5..d986f7d9e55 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -2931,7 +2931,8 @@ subst (x, from, to, in_dest, unique_copy) x = temp, code = GET_CODE (temp); /* First see if we can apply the inverse distributive law. */ - if (code == PLUS || code == MINUS || code == IOR || code == XOR) + if (code == PLUS || code == MINUS + || code == AND || code == IOR || code == XOR) { x = apply_distributive_law (x); code = GET_CODE (x); @@ -3814,6 +3815,27 @@ subst (x, from, to, in_dest, unique_copy) return temp; } } + + /* If we have (if_then_else (ne A 0) C1 0) and either A is known to + be 0 or 1 and C1 is a single bit or A is known to be 0 or -1 and + C1 is the negation of a single bit, we can convert this operation + to a shift. We can actually do this in more general cases, but it + doesn't seem worth it. */ + + if (GET_CODE (XEXP (x, 0)) == NE && XEXP (XEXP (x, 0), 1) == const0_rtx + && XEXP (x, 2) == const0_rtx && GET_CODE (XEXP (x, 1)) == CONST_INT + && ((1 == nonzero_bits (XEXP (XEXP (x, 0), 0), + GET_MODE (XEXP (XEXP (x, 0), 0))) + && (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0) + || ((num_sign_bit_copies (XEXP (XEXP (x, 0), 0), + GET_MODE (XEXP (XEXP (x, 0), 0))) + == GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (x, 0), 0)))) + && (i = exact_log2 (- INTVAL (XEXP (x, 1)))) >= 0))) + return + simplify_shift_const (NULL_RTX, ASHIFT, mode, + gen_lowpart_for_combine (mode, + XEXP (XEXP (x, 0), 0)), + i); break; case ZERO_EXTRACT: @@ -7615,6 +7637,16 @@ simplify_shift_const (x, code, result_mode, varop, count) SUBST (XEXP (x, 1), const_rtx); } + /* If we have an outer operation and we just made a shift, it is + possible that we could have simplified the shift were it not + for the outer operation. So try to do the simplification + recursively. */ + + if (outer_op != NIL && GET_CODE (x) == code + && GET_CODE (XEXP (x, 1)) == CONST_INT) + x = simplify_shift_const (x, code, shift_mode, XEXP (x, 0), + INTVAL (XEXP (x, 1))); + /* If we were doing a LSHIFTRT in a wider mode than it was originally, turn off all the bits that the shift would have turned off. */ if (orig_code == LSHIFTRT && result_mode != shift_mode)