aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>1999-03-21 23:44:51 +0000
committerRichard Kenner <kenner@vlsi1.ultra.nyu.edu>1999-03-21 23:44:51 +0000
commit54a98a3e2bd7c3a66148dbbf01a40377925ccbf2 (patch)
tree04083d69c47191ab52a717ea48d03d455d73ae12
parent084aaf75125d41a5b368ab6b6b4b557bced3e84b (diff)
(contains_muldiv): New function.
(try_combine): Call it when dividing a PARALLEL. (simplify_rtx, case TRUNCATE): Don't remove for umulsi3_highpart. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/premerge-fsf-branch@25887 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/combine.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index 31d2814b6cd..fd25ea2bd55 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -392,6 +392,7 @@ static void setup_incoming_promotions PROTO((void));
static void set_nonzero_bits_and_sign_copies PROTO((rtx, rtx));
static int can_combine_p PROTO((rtx, rtx, rtx, rtx, rtx *, rtx *));
static int combinable_i3pat PROTO((rtx, rtx *, rtx, rtx, int, rtx *));
+static int contains_muldiv PROTO((rtx));
static rtx try_combine PROTO((rtx, rtx, rtx));
static void undo_all PROTO((void));
static rtx *find_split_point PROTO((rtx *, rtx));
@@ -1234,6 +1235,36 @@ combinable_i3pat (i3, loc, i2dest, i1dest, i1_not_in_src, pi3dest_killed)
return 1;
}
+/* Return 1 if X is an arithmetic expression that contains a multiplication
+ and division. We don't count multiplications by powers of two here. */
+
+static int
+contains_muldiv (x)
+ rtx x;
+{
+ switch (GET_CODE (x))
+ {
+ case MOD: case DIV: case UMOD: case UDIV:
+ return 1;
+
+ case MULT:
+ return ! (GET_CODE (XEXP (x, 1)) == CONST_INT
+ && exact_log2 (INTVAL (XEXP (x, 1))) >= 0);
+ }
+
+ switch (GET_RTX_CLASS (GET_CODE (x)))
+ {
+ case 'c': case '<': case '2':
+ return contains_muldiv (XEXP (x, 0)) || contains_muldiv (XEXP (x, 1));
+
+ case '1':
+ return contains_muldiv (XEXP (x, 0));
+
+ default:
+ return 0;
+ }
+}
+
/* Try to combine the insns I1 and I2 into I3.
Here I1 and I2 appear earlier than I3.
I1 can be zero; then we combine just I2 into I3.
@@ -2088,7 +2119,9 @@ try_combine (i3, i2, i1)
&& ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 1)),
XVECEXP (newpat, 0, 0))
&& ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 0)),
- XVECEXP (newpat, 0, 1)))
+ XVECEXP (newpat, 0, 1))
+ && ! (contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 0)))
+ && contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 1)))))
{
/* Normally, it doesn't matter which of the two is done first,
but it does if one references cc0. In that case, it has to
@@ -3685,9 +3718,13 @@ simplify_rtx (x, op0_mode, last, in_dest)
return SUBREG_REG (XEXP (x, 0));
/* If we know that the value is already truncated, we can
- replace the TRUNCATE with a SUBREG. */
+ replace the TRUNCATE with a SUBREG. But don't do this for
+ an (LSHIFTRT (MULT ...)) since this will cause problems with
+ the umulXi3_highpart patterns. */
if (num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
- >= GET_MODE_BITSIZE (mode) + 1)
+ >= GET_MODE_BITSIZE (mode) + 1
+ && ! (GET_CODE (XEXP (x, 0)) == LSHIFTRT
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT))
return gen_lowpart_for_combine (mode, XEXP (x, 0));
/* A truncate of a comparison can be replaced with a subreg if