This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
combine canonicalization tweeks
- To: gcc-patches at gcc dot gnu dot org
- Subject: combine canonicalization tweeks
- From: Richard Henderson <rth at cygnus dot com>
- Date: Mon, 29 May 2000 00:27:53 -0700
Two things: first, while being able to canonicalize PLUS to IOR is
nice, and may lead to other simplifications, it may not. And there
is a whole lot of interesting combinations to be done with addressing
modes, all of which use PLUS and not IOR. So I do the brute force
thing -- try it and see if it can in fact be further simplified.
Second, while looking at the commentary surrounding the IOR conversion,
I thought I'd see if (X & 1) + (X & 2) => (X & 3) actually worked.
It didn't. This may be hidden holdovers from the conditional_arithmetic
stuff, but we wind up canonicalizing
(set t1 (and x 1))
(set t2 (and x 2))
(set t3 (plus t2 t1))
as
(if_then_else (ne t1 0)
(ior (and x 2)
1)
(and x 2))
which doesn't do anyone any good. Blocking the if_then_else conversion
unless the arguments are general_operands seems to do the trick.
With both patches in place both the (X & 3) combination and my
address arithmetic combination happens.
Bootstrapped i686 and alphaev67.
r~
* combine.c (combine_simplify_rtx): Don't create an if_then_else
unless both args are general_operand. Don't canonicalize plus
to ior unless it helps.
Index: combine.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/combine.c,v
retrieving revision 1.131
diff -c -p -d -r1.131 combine.c
*** combine.c 2000/05/28 01:06:11 1.131
--- combine.c 2000/05/29 07:15:04
*************** combine_simplify_rtx (x, op0_mode, last,
*** 3589,3625 ****
true = subst (true, pc_rtx, pc_rtx, 0, 0);
false = subst (false, pc_rtx, pc_rtx, 0, 0);
! /* Restarting if we generate a store-flag expression will cause
! us to loop. Just drop through in this case. */
! /* If the result values are STORE_FLAG_VALUE and zero, we can
! just make the comparison operation. */
! if (true == const_true_rtx && false == const0_rtx)
! x = gen_binary (cond_code, mode, cond, cop1);
! else if (true == const0_rtx && false == const_true_rtx)
! x = gen_binary (reverse_condition (cond_code), mode, cond, cop1);
! /* Likewise, we can make the negate of a comparison operation
! if the result values are - STORE_FLAG_VALUE and zero. */
! else if (GET_CODE (true) == CONST_INT
! && INTVAL (true) == - STORE_FLAG_VALUE
! && false == const0_rtx)
! x = gen_unary (NEG, mode, mode,
! gen_binary (cond_code, mode, cond, cop1));
! else if (GET_CODE (false) == CONST_INT
! && INTVAL (false) == - STORE_FLAG_VALUE
! && true == const0_rtx)
! x = gen_unary (NEG, mode, mode,
! gen_binary (reverse_condition (cond_code),
! mode, cond, cop1));
! else
! return gen_rtx_IF_THEN_ELSE (mode,
! gen_binary (cond_code, VOIDmode,
! cond, cop1),
! true, false);
! code = GET_CODE (x);
! op0_mode = VOIDmode;
}
}
--- 3589,3632 ----
true = subst (true, pc_rtx, pc_rtx, 0, 0);
false = subst (false, pc_rtx, pc_rtx, 0, 0);
! /* If true and false are not general_operands, an if_then_else
! is unlikely to be simpler. */
! if (general_operand (true, VOIDmode)
! && general_operand (false, VOIDmode))
! {
! /* Restarting if we generate a store-flag expression will cause
! us to loop. Just drop through in this case. */
! /* If the result values are STORE_FLAG_VALUE and zero, we can
! just make the comparison operation. */
! if (true == const_true_rtx && false == const0_rtx)
! x = gen_binary (cond_code, mode, cond, cop1);
! else if (true == const0_rtx && false == const_true_rtx)
! x = gen_binary (reverse_condition (cond_code),
! mode, cond, cop1);
! /* Likewise, we can make the negate of a comparison operation
! if the result values are - STORE_FLAG_VALUE and zero. */
! else if (GET_CODE (true) == CONST_INT
! && INTVAL (true) == - STORE_FLAG_VALUE
! && false == const0_rtx)
! x = gen_unary (NEG, mode, mode,
! gen_binary (cond_code, mode, cond, cop1));
! else if (GET_CODE (false) == CONST_INT
! && INTVAL (false) == - STORE_FLAG_VALUE
! && true == const0_rtx)
! x = gen_unary (NEG, mode, mode,
! gen_binary (reverse_condition (cond_code),
! mode, cond, cop1));
! else
! return gen_rtx_IF_THEN_ELSE (mode,
! gen_binary (cond_code, VOIDmode,
! cond, cop1),
! true, false);
! code = GET_CODE (x);
! op0_mode = VOIDmode;
! }
}
}
*************** combine_simplify_rtx (x, op0_mode, last,
*** 4229,4235 ****
if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
&& (nonzero_bits (XEXP (x, 0), mode)
& nonzero_bits (XEXP (x, 1), mode)) == 0)
! return gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1));
break;
case MINUS:
--- 4236,4252 ----
if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
&& (nonzero_bits (XEXP (x, 0), mode)
& nonzero_bits (XEXP (x, 1), mode)) == 0)
! {
! /* Try to simplify the expression further. */
! rtx tor = gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1));
! temp = combine_simplify_rtx (tor, mode, last, in_dest);
!
! /* If we could, great. If not, do not go ahead with the IOR
! replacement, since PLUS appears in many special purpose
! address arithmetic instructions. */
! if (GET_CODE (temp) != CLOBBER && temp != tor)
! return temp;
! }
break;
case MINUS: