Hi,

The patch enhances ifcvt to allow_cc_mode if HAVE_cbranchcc4.

Bootstrap and no make check regression on X86-64.
Will add new test cases after ccmp is enabled.

Ok for trunk?

Thanks!
-Zhenqiang

ChangeLog:
2014-10-29  Zhenqiang Chen  <zhenqiang.c...@arm.com>

        * ifcvt.c (noce_emit_cmove, noce_get_alt_condition,
noce_get_condition):
        Allow CC mode if HAVE_cbranchcc4.

diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index a28f5c1..5cd0ac0 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -1441,10 +1441,17 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx
x, enum rtx_code code,
       end_sequence ();
     }
 
-  /* Don't even try if the comparison operands are weird.  */
+  /* Don't even try if the comparison operands are weird
+     except that the target supports cbranchcc4.  */
   if (! general_operand (cmp_a, GET_MODE (cmp_a))
       || ! general_operand (cmp_b, GET_MODE (cmp_b)))
-    return NULL_RTX;
+    {
+#if HAVE_cbranchcc4
+      if (GET_MODE_CLASS (GET_MODE (cmp_a)) != MODE_CC
+         || cmp_b != const0_rtx)
+#endif
+       return NULL_RTX;
+    }
 
 #if HAVE_conditional_move
   unsignedp = (code == LTU || code == GEU
@@ -1770,6 +1777,11 @@ noce_get_alt_condition (struct noce_if_info *if_info,
rtx target,
   rtx cond, set;
   rtx_insn *insn;
   int reverse;
+  int allow_cc_mode = false;
+#if HAVE_cbranchcc4
+  allow_cc_mode = true;
+#endif
+
 
   /* If target is already mentioned in the known condition, return it.  */
   if (reg_mentioned_p (target, if_info->cond))
@@ -1891,7 +1903,7 @@ noce_get_alt_condition (struct noce_if_info *if_info,
rtx target,
     }
 
   cond = canonicalize_condition (if_info->jump, cond, reverse,
-                                earliest, target, false, true);
+                                earliest, target, allow_cc_mode, true);
   if (! cond || ! reg_mentioned_p (target, cond))
     return NULL;
 
@@ -2347,6 +2359,10 @@ noce_get_condition (rtx_insn *jump, rtx_insn
**earliest, bool then_else_reversed
 {
   rtx cond, set, tmp;
   bool reverse;
+  int allow_cc_mode = false;
+#if HAVE_cbranchcc4
+  allow_cc_mode = true;
+#endif
 
   if (! any_condjump_p (jump))
     return NULL_RTX;
@@ -2383,7 +2399,7 @@ noce_get_condition (rtx_insn *jump, rtx_insn
**earliest, bool then_else_reversed
   /* Otherwise, fall back on canonicalize_condition to do the dirty
      work of manipulating MODE_CC values and COMPARE rtx codes.  */
   tmp = canonicalize_condition (jump, cond, reverse, earliest,
-                               NULL_RTX, false, true);
+                               NULL_RTX, allow_cc_mode, true);
 
   /* We don't handle side-effects in the condition, like handling
      REG_INC notes and making sure no duplicate conditions are emitted.  */


> -----Original Message-----
> From: Richard Henderson [mailto:r...@redhat.com]
> Sent: Tuesday, October 28, 2014 12:03 AM
> To: Zhenqiang Chen
> Cc: gcc-patches@gcc.gnu.org
> Subject: Re: [Ping] [PATCH, 10/10] aarch64: Handle ccmp in ifcvt to make
it
> work with cmov
> 
> On 10/27/2014 12:50 AM, Zhenqiang Chen wrote:
> > Good point. It is not ccmp special. It is cbranchcc4 related. If I
> > understand correct, without cbranchcc4, we need put the result to  a
> > tmp register and generate additional compares, which is not good for
> > performance.
> 
> It won't be an additional compare.  It is regenerating the compare at a
new
> location.  The old comparison would be deleted via dead code elimination.
> 
> That said,
> 
> > +#if HAVE_cbranchcc4
> > +  allow_cc_mode = true;
> > +#endif
> 
> does seem to be the right solution.
> 
> If a target has this, we ought to be able to reasonably expect that it's
got all
> the other patterns that this implies.  If a target is missing them,
hopefully we
> can get that sorted fairly quickly after this patch is included.
> 
> > +#if HAVE_cbranchcc4
> > +      if (!(GET_MODE_CLASS (GET_MODE (cmp_a)) == MODE_CC
> > +       || GET_MODE_CLASS (GET_MODE (cmp_b)) == MODE_CC)) #endif
> 
> This test looks weird, considering what we're looking for.
> I think a better test is
> 
>   if (GET_MODE_CLASS (GET_MODE (cmp_a)) != MODE_CC
>       || cmp_b != const0_rtx)
> 
> Accepting something like (compare (reg:CC a) (reg:CC b)) is definitely
non-
> canonical.  Even (compare (const_int 0) (reg:CC flags)) is odd.
> 
> The ifcvt.c change should go in by itself.
> The expr.c change should also be standalone.
> The ccmp.c change should probably be merged with the initial commit of
> ccmp.c.
> The aaarch64.md change should probably be merged with the patch that
> adds cbranchcc.
> 
> 
> r~




Reply via email to