This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Improve things for PR71724, in combine/if_then_else_cond
- From: Bernd Schmidt <bschmidt at redhat dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Segher Boessenkool <segher at kernel dot crashing dot org>
- Date: Fri, 20 Jan 2017 13:33:59 +0100
- Subject: Improve things for PR71724, in combine/if_then_else_cond
- Authentication-results: sourceware.org; auth=none
The PR is about infinite recursion in combine_simplify_rtx, because
if_then_else_cond does strange things to an expression, and we end up
simplifying something to itself. The patch below tries to address this
by improving that function a little. As stated in the PR, the situation
is that we have
(plus:SI (if_then_else:SI (eq (reg:CC 185)
(const_int 0 [0]))
(reg:SI 165)
(reg:SI 174 [ t9.0_1+4 ]))
(reg:SI 165))
Reg 165 is known to be zero or one, so it gets turned into a condition,
and we have two different conditions on the operands. That causes us to
fail to make the fairly obvious transformation to
cond = reg:CC 185
true_rtx = (plus r165 r165)
false_rtx = (plus r174 r165)
So, when looking for situations where we have only one condition, we can
try to undo the conversion of a plain REG into a condition, on the
grounds that this is probably less helpful.
This seems to cure the testcase, but Segher also has a patch in the PR
that looks like a good and more direct approach. IMO both should be
applied. This one was bootstrapped and tested on x86_64-linux. Ok?
Bernd
PR rtl-optimization/71724
* combine.c (if_then_else_cond): Look for situations where it is
beneficial to undo the work of one of the recursive calls.
Index: gcc/combine.c
===================================================================
--- gcc/combine.c (revision 244528)
+++ gcc/combine.c (working copy)
@@ -9044,11 +9044,31 @@ if_then_else_cond (rtx x, rtx *ptrue, rt
the same value, compute the new true and false values. */
else if (BINARY_P (x))
{
- cond0 = if_then_else_cond (XEXP (x, 0), &true0, &false0);
- cond1 = if_then_else_cond (XEXP (x, 1), &true1, &false1);
+ rtx op0 = XEXP (x, 0);
+ rtx op1 = XEXP (x, 1);
+ cond0 = if_then_else_cond (op0, &true0, &false0);
+ cond1 = if_then_else_cond (op1, &true1, &false1);
+
+ if ((cond0 != 0 && cond1 != 0 && !rtx_equal_p (cond0, cond1))
+ && (REG_P (op0) || REG_P (op1)))
+ {
+ /* Try to enable a simplification by undoing work done by
+ if_then_else_cond if it converted a REG into something more
+ complex. */
+ if (REG_P (op0))
+ {
+ cond0 = 0;
+ true0 = false0 = op0;
+ }
+ else
+ {
+ cond1 = 0;
+ true1 = false1 = op1;
+ }
+ }
if ((cond0 != 0 || cond1 != 0)
- && ! (cond0 != 0 && cond1 != 0 && ! rtx_equal_p (cond0, cond1)))
+ && ! (cond0 != 0 && cond1 != 0 && !rtx_equal_p (cond0, cond1)))
{
/* If if_then_else_cond returned zero, then true/false are the
same rtl. We must copy one of them to prevent invalid rtl