committed: cris: update recent patterns. Simplify cris_select_cc_mode.

Hans-Peter Nilsson hp@axis.com
Sun Jul 5 23:21:01 GMT 2020


The code in cris_select_cc_mode for selecting CC_NZmode was
partly inconsistent with the comment and partly seemed
ambiguous.  I couldn't find a reason why I qualified selection
of CC_NZmode on the setting operation once a matching user was
spotted, so I just removed that.  The cris.c update was due to
observing the new test-case failing; the CC_NZmode compare
wasn't eliminated.

The recently re-instated adds/addu/subs/subu/bound patterns are
rewritten to replace the use of match_operator with iterators.

gcc:
	* config/cris/cris.c (cris_select_cc_mode): Always return
	CC_NZmode for matching comparisons.  Clarify comments.
	* config/cris/cris-modes.def: Clarify mode comment.
	* config/cris/cris.md (plusminus, plusminusumin, plusumin): New
	code iterators.
	(addsub, addsubbo, nd): New code iterator attributes.
	("*<addsub><su>qihi"): Rename from "*extopqihi".  Use code
	iterator constructs instead of match_operator constructs.
	("*<addsubbo><su><nd><mode>si<setnz>"): Similar from
	"*extop<mode>si<setnz>".
	("*add<su>qihi_swap"): Similar from "*addxqihi_swap".
	("*<addsubbo><su><nd><mode>si<setnz>_swap"): Similar from
	"*extop<mode>si<setnz>_swap".

gcc/testsuite:
	* gcc.target/cris/pr93372-39.c: New test.
---
 gcc/config/cris/cris-modes.def             |  17 +++--
 gcc/config/cris/cris.c                     |  16 +----
 gcc/config/cris/cris.md                    | 105 ++++++++++++++++-------------
 gcc/testsuite/gcc.target/cris/pr93372-39.c |  19 ++++++
 4 files changed, 90 insertions(+), 67 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/cris/pr93372-39.c

diff --git a/gcc/config/cris/cris-modes.def b/gcc/config/cris/cris-modes.def
index 1aaf12a0f5b..874e4c19657 100644
--- a/gcc/config/cris/cris-modes.def
+++ b/gcc/config/cris/cris-modes.def
@@ -25,9 +25,10 @@ along with GCC; see the file COPYING3.  If not see
    have ordinary compares and incidental condition-code settings from
    preceding instructions, setting a subset of N, Z, V and C to usable
    values, from the perspective of comparing the result against zero
-   (fpcraz).  The two subsets meaningful to gcc are all of N, Z, V, C
-   versus just N, Z; some CC-users care only about N and/or Z and some
-   that care about at least one of those flags together with V and/or C.
+   (referred to below as "fpcraz").  The two subsets meaningful to gcc are
+   all of N, Z, V, C versus just N, Z; some CC-users care only about N
+   and/or Z and some that care about at least one of those flags together
+   with V and/or C.
 
    The plain "CC_MODE (CC)" (which is always present in gcc), is used to
    reflect the "unoptimized" state, where the CC-setter is a compare
@@ -37,9 +38,13 @@ along with GCC; see the file COPYING3.  If not see
    or if optimization of CC-setter and CC-users, when CCmode setters can
    be changed or replaced by either CC_NZmode or CC_NZVCmode.  To wit, all
    users that require CC_NZVCmode must match only that mode at any time.
-   All other users must match all CCmodes.  All setters that set only
-   CC_NZmode must set only that mode.  All other setters must match
-   setting all CCmodes.  */
+   All other users must match all of CCmode, CC_NZmode, and CC_NZVCmode.
+   All setters that set only CC_NZmode must match setting only that mode.
+   All other setters must match setting all of CCmode, CC_NZmode, and
+   CC_NZVCmode.
+
+   There's also other modes (i.e. CC_ZnNmode) with a separate set of
+   setters and users not matched by the others. */
 
 /* Z and N flags only.  For a condition-code setter: only the Z and N
    flags are set to usable values, fpcraz.  For a condition-code user: the
diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c
index 2bad9393c6e..b26b9f2e883 100644
--- a/gcc/config/cris/cris.c
+++ b/gcc/config/cris/cris.c
@@ -1530,21 +1530,11 @@ cris_select_cc_mode (enum rtx_code op, rtx x, rtx y)
   if (GET_MODE_CLASS (GET_MODE (x)) != MODE_INT || y != const0_rtx)
     return CCmode;
 
-  /* If we have a comparison that doesn't have to look at V or C, check
-     operand x; if it's a valid operator, return CC_NZmode, else CCmode,
-     so we only use CC_NZmode for the cases where we don't actually have
-     both V and C valid.  */
+  /* If we have a comparison that doesn't have to look at V or C, return
+     CC_NZmode.  */
   if (op == EQ || op ==  NE || op ==  GTU || op ==  LEU
       || op ==  LT || op ==  GE)
-    {
-      enum rtx_code e = GET_CODE (x);
-
-    /* Mentioning the rtx_code here is required but not sufficient: the
-       insn also needs to be decorated with <setnz> (and the
-       anonymization prefix <anz> for a named pattern).  */
-      return e == PLUS || e == MINUS || e == MULT || e == NOT || e == NEG
-	? CC_NZmode : CCmode;
-    }
+    return CC_NZmode;
 
   /* We should only get here for comparison operators.  */
   gcc_assert (op ==  GEU || op ==  LTU || op ==  GT || op ==  LE);
diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md
index e700819d510..ae6a27f5f2c 100644
--- a/gcc/config/cris/cris.md
+++ b/gcc/config/cris/cris.md
@@ -183,6 +183,25 @@ (define_code_iterator szext [sign_extend zero_extend])
 (define_code_attr u [(sign_extend "") (zero_extend "u")])
 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
 
+;; For extended-operand variants.
+(define_code_iterator plusminus [plus minus])
+(define_code_attr addsub [(plus "add") (minus "sub")])
+
+;; Similar, other cases also matching bound/umin.
+(define_code_iterator plusminusumin [plus minus umin])
+
+;; Ditto, commutative operators (i.e. not minus).
+(define_code_iterator plusumin [plus umin])
+
+;; The addsubbo and nd code-attributes form a hack.  We need to output
+;; "addu.b", "subu.b" but "bound.b" (no "u"-suffix) which means we'd
+;; need to refer to one iterator from the next.  But, that can't be
+;; done.  Instead output the "u" for unsigned as the "u" in "bound",
+;; i.e. the mnemonic as three parts including the extend-letter, and
+;; with an empty third part for "add" and "sub".
+(define_code_attr addsubbo [(plus "add") (minus "sub") (umin "bo")])
+(define_code_attr nd [(plus "") (minus "") (umin "nd")])
+
 ;; For the shift variants.
 (define_code_iterator shift [ashiftrt lshiftrt ashift])
 (define_code_iterator shiftrt [ashiftrt lshiftrt])
@@ -1113,42 +1132,37 @@ (define_insn "*sub<mode>3<setnz>"
 ;; QImode to HImode
 ;; FIXME: GCC should widen.
 
-(define_insn "*extopqihi"
+(define_insn "*<addsub><su>qihi"
   [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
-	(match_operator:HI
-	 3 "cris_additive_operand_extend_operator"
-	 [(match_operand:HI 1 "register_operand" "0,0,0,r")
-	  (match_operator:HI
-	   4 "cris_extend_operator"
-	   [(match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To")])]))
+	(plusminus:HI
+	 (match_operand:HI 1 "register_operand" "0,0,0,r")
+	 (szext:HI (match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To"))))
    (clobber (reg:CC CRIS_CC0_REGNUM))]
   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
-   && (operands[1] != frame_pointer_rtx || GET_CODE (operands[3]) != PLUS)"
+   && (operands[1] != frame_pointer_rtx || <plusminus:CODE> != PLUS)"
   "@
-   %x3%E4.%m4 %2,%0
-   %x3%E4.%m4 %2,%0
-   %x3%E4.%m4 %2,%0
-   %x3%E4.%m4 %2,%1,%0"
+   <addsub><su>.b %2,%0
+   <addsub><su>.b %2,%0
+   <addsub><su>.b %2,%0
+   <addsub><su>.b %2,%1,%0"
   [(set_attr "slottable" "yes,yes,no,no")
    (set_attr "cc" "clobber")])
 
-(define_insn "*extop<mode>si<setnz>"
+;; FIXME: bound is actually also <setnzvc>, but is so rarely used in this
+;; form that it's not worthwhile to make that distinction.
+(define_insn "*<addsubbo><su><nd><mode>si<setnz>"
   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
-	(match_operator:SI
-	 3 "cris_operand_extend_operator"
-	 [(match_operand:SI 1 "register_operand" "0,0,0,r")
-	  (match_operator:SI
-	   4 "cris_extend_operator"
-	   [(match_operand:BW 2 "nonimmediate_operand" "r,Q>,m,!To")])]))
-   (clobber (reg:CC CRIS_CC0_REGNUM))]
-  "(GET_CODE (operands[3]) != UMIN || GET_CODE (operands[4]) == ZERO_EXTEND)
-   && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
-   && (operands[1] != frame_pointer_rtx || GET_CODE (operands[3]) != PLUS)"
+	(plusminusumin:SI
+	 (match_operand:SI 1 "register_operand" "0,0,0,r")
+	 (szext:SI (match_operand:BW 2 "nonimmediate_operand" "r,Q>,m,!To"))))
+   (clobber (reg:CC CRIS_CC0_REGNUM))]
+  "(<plusminusumin:CODE> != UMIN || <szext:CODE> == ZERO_EXTEND)
+   && (operands[1] != frame_pointer_rtx || <plusminusumin:CODE> != PLUS)"
   "@
-   %x3%E4<m> %2,%0
-   %x3%E4<m> %2,%0
-   %x3%E4<m> %2,%0
-   %x3%E4<m> %2,%1,%0"
+   <addsubbo><su><nd><m> %2,%0
+   <addsubbo><su><nd><m> %2,%0
+   <addsubbo><su><nd><m> %2,%0
+   <addsubbo><su><nd><m> %2,%1,%0"
   [(set_attr "slottable" "yes,yes,no,no")])
 

 ;; We may have swapped operands for add or bound.
@@ -1156,39 +1170,34 @@ (define_insn "*extop<mode>si<setnz>"
 
 ;; QImode to HImode
 
-(define_insn "*addxqihi_swap"
+(define_insn "*add<su>qihi_swap"
   [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
 	(plus:HI
-	 (match_operator:HI
-	  3 "cris_extend_operator"
-	  [(match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To")])
+	 (szext:HI (match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To"))
 	 (match_operand:HI 1 "register_operand" "0,0,0,r")))
    (clobber (reg:CC CRIS_CC0_REGNUM))]
   "operands[1] != frame_pointer_rtx"
   "@
-   add%e3.b %2,%0
-   add%e3.b %2,%0
-   add%e3.b %2,%0
-   add%e3.b %2,%1,%0"
+   add<su>.b %2,%0
+   add<su>.b %2,%0
+   add<su>.b %2,%0
+   add<su>.b %2,%1,%0"
   [(set_attr "slottable" "yes,yes,no,no")
    (set_attr "cc" "clobber")])
 
-(define_insn "*extop<mode>si<setnz>_swap"
+(define_insn "*<addsubbo><su><nd><mode>si<setnz>_swap"
   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
-	(match_operator:SI
-	 4 "cris_plus_or_bound_operator"
-	 [(match_operator:SI
-	   3 "cris_extend_operator"
-	   [(match_operand:BW 2 "nonimmediate_operand" "r,Q>,m,!To")])
-	  (match_operand:SI 1 "register_operand" "0,0,0,r")]))
-   (clobber (reg:CC CRIS_CC0_REGNUM))]
-  "(GET_CODE (operands[4]) != UMIN || GET_CODE (operands[3]) == ZERO_EXTEND)
+	(plusumin:SI
+	 (szext:SI (match_operand:BW 2 "nonimmediate_operand" "r,Q>,m,!To"))
+	 (match_operand:SI 1 "register_operand" "0,0,0,r")))
+   (clobber (reg:CC CRIS_CC0_REGNUM))]
+  "(<plusumin:CODE> != UMIN || <szext:CODE> == ZERO_EXTEND)
    && operands[1] != frame_pointer_rtx"
   "@
-   %x4%E3<m> %2,%0
-   %x4%E3<m> %2,%0
-   %x4%E3<m> %2,%0
-   %x4%E3<m> %2,%1,%0"
+   <addsubbo><su><nd><m> %2,%0
+   <addsubbo><su><nd><m> %2,%0
+   <addsubbo><su><nd><m> %2,%0
+   <addsubbo><su><nd><m> %2,%1,%0"
   [(set_attr "slottable" "yes,yes,no,no")])
 

 ;; This is the special case when we use what corresponds to the
diff --git a/gcc/testsuite/gcc.target/cris/pr93372-39.c b/gcc/testsuite/gcc.target/cris/pr93372-39.c
new file mode 100644
index 00000000000..6cc387fd794
--- /dev/null
+++ b/gcc/testsuite/gcc.target/cris/pr93372-39.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not {\tcmp|\ttest|\tmovu|\tmovs} } } */
+/* { dg-final { scan-assembler-times "\tbound.b" 1 } } */
+/* { dg-final { scan-assembler-times "\tbound.w" 1 } } */
+
+unsigned int ub (unsigned int a, unsigned char *b, int *c)
+{
+  unsigned int d = a < *b ? a : *b;
+  *c = d == 0;
+  return d;
+}
+
+unsigned int us (unsigned int a, unsigned short *b, int *c)
+{
+  unsigned int d = a < *b ? a : *b;
+  *c = d == 0;
+  return d;
+}
-- 
2.11.0


More information about the Gcc-patches mailing list