On Mon, Aug 24, 2020 at 6:12 PM Jeff Law <l...@redhat.com> wrote:
> On Thu, 2020-08-06 at 12:42 +0000, Pip Cet via Gcc-patches wrote:
> > I've bootstrapped and run the test suite with the patch, without 
> > differences.
> So it looks like Richard has given you some feedback and you've got some 
> further
> work to do.  I just wanted to chime in and say thanks for tackling this.

Thanks for the encouragement!

Richard wrote:
> We should be able to test whether the rest of the parallel is suitable by 
> adding a single_set test (after testing everything else).

It seems to me the existing two checks using single_set are sufficient
to ensure this.

Revised patch attached. It bootstraps and causes no test regressions,
and it appears to work.
From 72e05ac3a570f3e6ca9e54599db1b3b4daa84e90 Mon Sep 17 00:00:00 2001
From: Pip Cet <pip...@gmail.com>
Date: Tue, 25 Aug 2020 14:23:58 +0000
Subject: [PATCH] cmpelim: handle extra clobbers

Handle extra clobbers in CC-clobbering insns when attempting to
recognize the corresponding CC-setting insn.

This is for the AVR CCmode conversion. AVR has insns like

(define_insn "andhi3"
  [(set (match_operand:HI 0 ...)
        (and:HI (match_operand:HI 1 ...)
	        (match_operand:HI 2 ...)))
   (clobber (reg:CC REG_CC))
   (clobber (match_scratch:QI 3 ...))] ...)

which can be profitably converted into CC-setting variants.

2020-08-28  Pip Cet  <pip...@gmail.com>

gcc/ChangeLog:

	* compare-elim.c (arithmetic_flags_clobber_p): Allow extra
        clobbers. (try_validate_parallel): (try_eliminate_compare):
        Likewise.
---
 gcc/compare-elim.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/gcc/compare-elim.c b/gcc/compare-elim.c
index 85f3e344074..8e5c9a05fa8 100644
--- a/gcc/compare-elim.c
+++ b/gcc/compare-elim.c
@@ -202,7 +202,7 @@ arithmetic_flags_clobber_p (rtx_insn *insn)
   if (asm_noperands (pat) >= 0)
     return false;
 
-  if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) == 2)
+  if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) >= 2)
     {
       x = XVECEXP (pat, 0, 0);
       if (GET_CODE (x) != SET)
@@ -663,6 +663,17 @@ static rtx
 try_validate_parallel (rtx set_a, rtx set_b)
 {
   rtx par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set_a, set_b));
+  if (GET_CODE (set_b) == PARALLEL)
+    {
+      int len = XVECLEN (set_b, 0);
+      rtvec v = rtvec_alloc (len);
+      RTVEC_ELT (v, 0) = set_a;
+      RTVEC_ELT (v, 1) = XVECEXP (set_b, 0, 0);
+      for (int i = 2; i < len; i++)
+	RTVEC_ELT (v, i) = XVECEXP (set_b, 0, i);
+
+      par = gen_rtx_PARALLEL (VOIDmode, v);
+    }
   rtx_insn *insn = make_insn_raw (par);
 
   if (insn_invalid_p (insn, false))
@@ -873,10 +884,13 @@ try_eliminate_compare (struct comparison *cmp)
      [(set (reg:CCM) (compare:CCM (operation) (immediate)))
       (set (reg) (operation)]  */
 
-  rtvec v = rtvec_alloc (2);
+  int len = XVECLEN (PATTERN (insn), 0);
+  rtvec v = rtvec_alloc (len);
   RTVEC_ELT (v, 0) = y;
   RTVEC_ELT (v, 1) = x;
-  
+  for (int i = 2; i < len; i++)
+    RTVEC_ELT (v, i) = XVECEXP (PATTERN (insn), 0, i);
+
   rtx pat = gen_rtx_PARALLEL (VOIDmode, v);
   
   /* Succeed if the new instruction is valid.  Note that we may have started
-- 
2.28.0

Reply via email to