diff options
author | Hans-Peter Nilsson <hp@axis.com> | 2020-07-06 01:10:54 +0200 |
---|---|---|
committer | Hans-Peter Nilsson <hp@axis.com> | 2020-07-06 01:17:54 +0200 |
commit | 9596eccb9c64faa13750692b46dd0779aac0d57c (patch) | |
tree | ebcde04d5354812ffed4ce05c1e54f2a5f8cdab3 | |
parent | 65f8403f1a99f965ad3ed36adc4f889cf95ee1eb (diff) | |
download | gcc-9596eccb9c64faa13750692b46dd0779aac0d57c.zip gcc-9596eccb9c64faa13750692b46dd0779aac0d57c.tar.gz gcc-9596eccb9c64faa13750692b46dd0779aac0d57c.tar.bz2 |
cris: update recent patterns. Simplify cris_select_cc_mode.
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.
-rw-r--r-- | gcc/config/cris/cris-modes.def | 17 | ||||
-rw-r--r-- | gcc/config/cris/cris.c | 16 | ||||
-rw-r--r-- | gcc/config/cris/cris.md | 105 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/cris/pr93372-39.c | 19 |
4 files changed, 90 insertions, 67 deletions
diff --git a/gcc/config/cris/cris-modes.def b/gcc/config/cris/cris-modes.def index 1aaf12a..874e4c1 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 2bad939..b26b9f2 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 e700819..ae6a27f 100644 --- a/gcc/config/cris/cris.md +++ b/gcc/config/cris/cris.md @@ -183,6 +183,25 @@ (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 @@ ;; 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 @@ ;; 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 0000000..6cc387f --- /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; +} |