summaryrefslogtreecommitdiff
path: root/gcc/simplify-rtx.c
diff options
context:
space:
mode:
authorPaolo Bonzini <bonzini@gnu.org>2004-04-29 07:50:55 +0000
committerPaolo Bonzini <bonzini@gcc.gnu.org>2004-04-29 07:50:55 +0000
commitc6fb08ad284af074092aa4fb9edd1a9a44014b49 (patch)
tree4be29049b780d10dd9423c8ad52d77c6929b956b /gcc/simplify-rtx.c
parent6cf1ac42db0684f0c386ec9a665ddcaa12a4f1c9 (diff)
downloadgcc-c6fb08ad284af074092aa4fb9edd1a9a44014b49.tar.gz
combine.c (combine_simplify_rtx): Adjust call to use simplify_relational_operation.
2004-04-29 Paolo Bonzini <bonzini@gnu.org> * combine.c (combine_simplify_rtx): Adjust call to use simplify_relational_operation. Do not use SELECT_CC_MODE when a comparison already has a MODE_CC mode. (simplify_set): simplify_relational_operation may now return another relational expression. * cse.c (fold_rtx): simplify_relational_operation now takes of computing the comparison mode. * dojump.c (compare_from_rtx): Use simplify_relational_operation, remove dead code. (do_compare_rtx_and_jump): Likewise. * integrate.c (subst_constants): simplify_relational_operation may now return another relational expression. * simplify-rtx.c (simplify_gen_relational): Move most code to the new simplify_relational_operation and simplify_relational_operation_1 functions. (simplify_relational_operation): Rewritten. (simplify_relational_operation_1): New function. (simplify_ternary_operation): simplify_relational_operation may now return another relational expression. (simplify_rtx): Remove unnecessary temp variable. From-SVN: r81282
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r--gcc/simplify-rtx.c226
1 files changed, 126 insertions, 100 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index b6340e54c8b..5895bb90686 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -58,6 +58,8 @@ static rtx simplify_immed_subreg (enum machine_mode, rtx, enum machine_mode,
unsigned int);
static rtx simplify_associative_operation (enum rtx_code, enum machine_mode,
rtx, rtx);
+static rtx simplify_relational_operation_1 (enum rtx_code, enum machine_mode,
+ enum machine_mode, rtx, rtx);
/* Negate a CONST_INT rtx, truncating (because a conversion from a
maximally negative number can overflow). */
@@ -221,10 +223,9 @@ simplify_gen_ternary (enum rtx_code code, enum machine_mode mode,
return gen_rtx_fmt_eee (code, mode, op0, op1, op2);
}
-
+
/* Likewise, for relational operations.
- CMP_MODE specifies mode comparison is done in.
- */
+ CMP_MODE specifies mode comparison is done in. */
rtx
simplify_gen_relational (enum rtx_code code, enum machine_mode mode,
@@ -232,46 +233,9 @@ simplify_gen_relational (enum rtx_code code, enum machine_mode mode,
{
rtx tem;
- if (cmp_mode == VOIDmode)
- cmp_mode = GET_MODE (op0);
- if (cmp_mode == VOIDmode)
- cmp_mode = GET_MODE (op1);
-
- if (cmp_mode != VOIDmode)
- {
- tem = simplify_relational_operation (code, mode, cmp_mode, op0, op1);
- if (tem)
- return tem;
- }
-
- /* For the following tests, ensure const0_rtx is op1. */
- if (swap_commutative_operands_p (op0, op1)
- || (op0 == const0_rtx && op1 != const0_rtx))
- tem = op0, op0 = op1, op1 = tem, code = swap_condition (code);
-
- /* If op0 is a compare, extract the comparison arguments from it. */
- if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
- return simplify_gen_relational (code, mode, VOIDmode,
- XEXP (op0, 0), XEXP (op0, 1));
-
- /* If op0 is a comparison, extract the comparison arguments form it. */
- if (COMPARISON_P (op0) && op1 == const0_rtx)
- {
- if (code == NE)
- {
- if (GET_MODE (op0) == mode)
- return op0;
- return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
- XEXP (op0, 0), XEXP (op0, 1));
- }
- else if (code == EQ)
- {
- enum rtx_code new = reversed_comparison_code (op0, NULL_RTX);
- if (new != UNKNOWN)
- return simplify_gen_relational (new, mode, VOIDmode,
- XEXP (op0, 0), XEXP (op0, 1));
- }
- }
+ if (0 != (tem = simplify_relational_operation (code, mode, cmp_mode,
+ op0, op1)))
+ return tem;
return gen_rtx_fmt_ee (code, mode, op0, op1);
}
@@ -1201,7 +1165,6 @@ simplify_associative_operation (enum rtx_code code, enum machine_mode mode,
Don't use this for relational operations such as EQ or LT.
Use simplify_relational_operation instead. */
-
rtx
simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
rtx op0, rtx op1)
@@ -2662,10 +2625,102 @@ simplify_plus_minus (enum rtx_code code, enum machine_mode mode, rtx op0,
}
/* Like simplify_binary_operation except used for relational operators.
- MODE is the mode of the operands, not that of the result. If MODE
- is VOIDmode, both operands must also be VOIDmode and we compare the
- operands in "infinite precision".
+ MODE is the mode of the result. If MODE is VOIDmode, both operands must
+ also be VOIDmode.
+
+ CMP_MODE specifies in which mode the comparison is done in, so it is
+ the mode of the operands. If CMP_MODE is VOIDmode, it is taken from
+ the operands or, if both are VOIDmode, the operands are compared in
+ "infinite precision". */
+rtx
+simplify_relational_operation (enum rtx_code code, enum machine_mode mode,
+ enum machine_mode cmp_mode, rtx op0, rtx op1)
+{
+ rtx tem, trueop0, trueop1;
+
+ if (cmp_mode == VOIDmode)
+ cmp_mode = GET_MODE (op0);
+ if (cmp_mode == VOIDmode)
+ cmp_mode = GET_MODE (op1);
+
+ tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
+ if (tem)
+ {
+#ifdef FLOAT_STORE_FLAG_VALUE
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ if (tem == const0_rtx)
+ return CONST0_RTX (mode);
+ else if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ REAL_VALUE_TYPE val;
+ val = FLOAT_STORE_FLAG_VALUE (mode);
+ return CONST_DOUBLE_FROM_REAL_VALUE (val, mode);
+ }
+ }
+#endif
+
+ return tem;
+ }
+
+ /* For the following tests, ensure const0_rtx is op1. */
+ if (swap_commutative_operands_p (op0, op1)
+ || (op0 == const0_rtx && op1 != const0_rtx))
+ tem = op0, op0 = op1, op1 = tem, code = swap_condition (code);
+
+ /* If op0 is a compare, extract the comparison arguments from it. */
+ if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
+ return simplify_relational_operation (code, mode, VOIDmode,
+ XEXP (op0, 0), XEXP (op0, 1));
+
+ if (mode == VOIDmode
+ || GET_MODE_CLASS (cmp_mode) == MODE_CC
+ || CC0_P (op0))
+ return NULL_RTX;
+
+ trueop0 = avoid_constant_pool_reference (op0);
+ trueop1 = avoid_constant_pool_reference (op1);
+ return simplify_relational_operation_1 (code, mode, cmp_mode,
+ trueop0, trueop1);
+}
+
+/* This part of simplify_relational_operation is only used when CMP_MODE
+ is not in class MODE_CC (i.e. it is a real comparison).
+
+ MODE is the mode of the result, while CMP_MODE specifies in which
+ mode the comparison is done in, so it is the mode of the operands. */
+rtx
+simplify_relational_operation_1 (enum rtx_code code, enum machine_mode mode,
+ enum machine_mode cmp_mode, rtx op0, rtx op1)
+{
+ if (GET_CODE (op1) == CONST_INT)
+ {
+ if (INTVAL (op1) == 0 && COMPARISON_P (op0))
+ {
+ /* If op0 is a comparison, extract the comparison arguments form it. */
+ if (code == NE)
+ {
+ if (GET_MODE (op0) == cmp_mode)
+ return simplify_rtx (op0);
+ else
+ return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
+ XEXP (op0, 0), XEXP (op0, 1));
+ }
+ else if (code == EQ)
+ {
+ enum rtx_code new = reversed_comparison_code (op0, NULL_RTX);
+ if (new != UNKNOWN)
+ return simplify_gen_relational (new, mode, VOIDmode,
+ XEXP (op0, 0), XEXP (op0, 1));
+ }
+ }
+ }
+ return NULL_RTX;
+}
+
+/* Check if the given comparison (done in the given MODE) is actually a
+ tautology or a contradiction.
If no simplification is possible, this function returns zero.
Otherwise, it returns either const_true_rtx or const0_rtx. */
@@ -2954,36 +3009,6 @@ simplify_const_relational_operation (enum rtx_code code,
abort ();
}
}
-
-/* Like simplify_binary_operation except used for relational operators.
- MODE is the mode of the result, and CMP_MODE is the mode of the operands.
- If CMP_MODE is VOIDmode, both operands must also be VOIDmode and we
- compare the operands in "infinite precision". */
-
-rtx
-simplify_relational_operation (enum rtx_code code,
- enum machine_mode mode ATTRIBUTE_UNUSED,
- enum machine_mode cmp_mode, rtx op0, rtx op1)
-{
- rtx tmp;
-
- tmp = simplify_const_relational_operation (code, cmp_mode, op0, op1);
- if (tmp)
- {
-#ifdef FLOAT_STORE_FLAG_VALUE
- if (GET_MODE_CLASS (mode) == MODE_FLOAT)
- {
- if (tmp == const0_rtx)
- return CONST0_RTX (mode);
- return CONST_DOUBLE_FROM_REAL_VALUE (FLOAT_STORE_FLAG_VALUE (mode),
- mode);
- }
-#endif
- return tmp;
- }
-
- return NULL_RTX;
-}
/* Simplify CODE, an operation with result mode MODE and three operands,
OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became
@@ -3078,20 +3103,6 @@ simplify_ternary_operation (enum rtx_code code, enum machine_mode mode,
? GET_MODE (XEXP (op0, 1))
: GET_MODE (XEXP (op0, 0)));
rtx temp;
- if (cmp_mode == VOIDmode)
- cmp_mode = op0_mode;
- temp = simplify_const_relational_operation (GET_CODE (op0),
- cmp_mode,
- XEXP (op0, 0),
- XEXP (op0, 1));
-
- /* See if any simplifications were possible. */
- if (temp == const0_rtx)
- return op2;
- else if (temp == const_true_rtx)
- return op1;
- else if (temp)
- abort ();
/* Look for happy constants in op1 and op2. */
if (GET_CODE (op1) == CONST_INT && GET_CODE (op2) == CONST_INT)
@@ -3112,7 +3123,23 @@ simplify_ternary_operation (enum rtx_code code, enum machine_mode mode,
else
break;
- return gen_rtx_fmt_ee (code, mode, XEXP (op0, 0), XEXP (op0, 1));
+ return simplify_gen_relational (code, op0_mode, cmp_mode,
+ XEXP (op0, 0), XEXP (op0, 1));
+ }
+
+ if (cmp_mode == VOIDmode)
+ cmp_mode = op0_mode;
+ temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
+ cmp_mode, XEXP (op0, 0),
+ XEXP (op0, 1));
+
+ /* See if any simplifications were possible. */
+ if (temp)
+ {
+ if (GET_CODE (temp) == CONST_INT)
+ return temp == const0_rtx ? op2 : op1;
+ else if (temp)
+ return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
}
}
break;
@@ -3721,7 +3748,6 @@ simplify_rtx (rtx x)
{
enum rtx_code code = GET_CODE (x);
enum machine_mode mode = GET_MODE (x);
- rtx temp;
switch (GET_RTX_CLASS (code))
{
@@ -3745,13 +3771,13 @@ simplify_rtx (rtx x)
case RTX_COMPARE:
case RTX_COMM_COMPARE:
- temp = simplify_relational_operation (code, mode,
- ((GET_MODE (XEXP (x, 0))
- != VOIDmode)
- ? GET_MODE (XEXP (x, 0))
- : GET_MODE (XEXP (x, 1))),
- XEXP (x, 0), XEXP (x, 1));
- return temp;
+ return simplify_relational_operation (code, mode,
+ ((GET_MODE (XEXP (x, 0))
+ != VOIDmode)
+ ? GET_MODE (XEXP (x, 0))
+ : GET_MODE (XEXP (x, 1))),
+ XEXP (x, 0),
+ XEXP (x, 1));
case RTX_EXTRA:
if (code == SUBREG)