aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/simplify-rtx.c29
2 files changed, 31 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d63c59c..685f4b8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2015-02-04 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/64817
+ * simplify-rtx.c (simplify_binary_operation_1): Rewrite
+ simplification of XOR of AND to not allocate new rtx before
+ committing to a simplification.
+
2015-02-04 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/aarch64/aarch64-ldpstp.md: Use std::swap instead of
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 5c9e3bf..bea9ec3 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -2724,12 +2724,31 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
HOST_WIDE_INT bval = INTVAL (b);
HOST_WIDE_INT cval = INTVAL (c);
- rtx na_c
- = simplify_binary_operation (AND, mode,
- simplify_gen_unary (NOT, mode, a, mode),
- c);
+ /* Instead of computing ~A&C, we compute its negated value,
+ ~(A|~C). If it yields -1, ~A&C is zero, so we can
+ optimize for sure. If it does not simplify, we still try
+ to compute ~A&C below, but since that always allocates
+ RTL, we don't try that before committing to returning a
+ simplified expression. */
+ rtx n_na_c = simplify_binary_operation (IOR, mode, a,
+ GEN_INT (~cval));
+
if ((~cval & bval) == 0)
{
+ rtx na_c = NULL_RTX;
+ if (n_na_c)
+ na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
+ else
+ {
+ /* If ~A does not simplify, don't bother: we don't
+ want to simplify 2 operations into 3, and if na_c
+ were to simplify with na, n_na_c would have
+ simplified as well. */
+ rtx na = simplify_unary_operation (NOT, mode, a, mode);
+ if (na)
+ na_c = simplify_gen_binary (AND, mode, na, c);
+ }
+
/* Try to simplify ~A&C | ~B&C. */
if (na_c != NULL_RTX)
return simplify_gen_binary (IOR, mode, na_c,
@@ -2738,7 +2757,7 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
else
{
/* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */
- if (na_c == const0_rtx)
+ if (n_na_c == CONSTM1_RTX (mode))
{
rtx a_nc_b = simplify_gen_binary (AND, mode, a,
gen_int_mode (~cval & bval,