public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: "Maciej W. Rozycki" <macro@embecosm.com>
To: gcc-patches@gcc.gnu.org
Cc: Andrew Waterman <andrew@sifive.com>,
	Jim Wilson <jim.wilson.gcc@gmail.com>,
	 Kito Cheng <kito.cheng@gmail.com>,
	Palmer Dabbelt <palmer@dabbelt.com>
Subject: [PATCH 26/44] RISC-V: Add `movMODEcc' implementation for generic targets
Date: Sun, 19 Nov 2023 05:40:48 +0000 (GMT)	[thread overview]
Message-ID: <alpine.DEB.2.20.2311181833450.5892@tpp.orcam.me.uk> (raw)
In-Reply-To: <alpine.DEB.2.20.2311171315580.5892@tpp.orcam.me.uk>

Provide RTL expansion of conditional-move operations for generic targets 
using a suitable sequence of base integer machine instructions according 
to cost evaluation by if-conversion.  Add `-mmovcc' command line option 
to enable this transformation, off by default.

For the generic sequences small immediates as per the `arith_operand' 
predicate are cost-equivalent to registers as we can use them as input, 
alternative to a register, to the respective AND[I] machine operations, 
however we need to reject immediates fulfilling `lui_operand', because 
they would require reloading into a register, making the operation more 
costly.  Therefore add `movcc_operand' predicate and use it accordingly.

There is a need to adjust zbs-bext-02.c, which can also serve as emitted 
code example, because with certain compilation options an AND operation 
can now legitimately appear in output despite BEXT having been produced 
as expected, such as with `-march=rv64gc -O2':

foo:
	mv	a3,a0
	li	a5,0
	mv	a0,a1
	li	a2,64
	li	a1,1
.L3:
	sll	a4,a1,a5
	and	a4,a4,a3
	addiw	a5,a5,1
	beq	a4,zero,.L2
	addiw	a0,a0,1
.L2:
	bne	a5,a2,.L3
	ret

vs `-march=rv64gc_zbs -O2':

foo:
	mv	a4,a0
	li	a5,0
	mv	a0,a1
	li	a3,64
.L3:
	bext	a2,a4,a5
	beq	a2,zero,.L2
	addiw	a0,a0,1
.L2:
	addiw	a5,a5,1
	bne	a5,a3,.L3
	ret

and then with `-march=rv64gc -mmovcc -mbranch-cost=7':

foo:
	mv	a6,a0
	li	a4,0
	mv	a0,a1
	li	a7,1
	li	a1,64
.L3:
	sll	a5,a7,a4
	and	a5,a5,a6
	snez	a5,a5
	neg	a5,a5
	not	a2,a5
	addiw	a3,a0,1
	and	a5,a5,a3
	and	a0,a2,a0
	addiw	a4,a4,1
	or	a0,a5,a0
	bne	a4,a1,.L3
	ret

vs `-march=rv64gc_zbs -mmovcc -mbranch-cost=7':

foo:
	mv	a6,a0
	li	a4,0
	mv	a0,a1
	li	a1,64
.L3:
	bext	a5,a6,a4
	neg	a5,a5
	not	a2,a5
	addiw	a3,a0,1
	and	a5,a5,a3
	and	a0,a2,a0
	addiw	a4,a4,1
	or	a0,a5,a0
	bne	a4,a1,.L3
	ret

However BEXT is supposed to replace an SLL operation so adjust the test 
case to reject SLL rather than AND, letting the test case pass even with 
`/-mmovcc/-mbranch-cost=7' specified as DejaGNU test flags (and in the 
absence of target-specific conditional-move operations enabled either by 
default or with other test flags).

	gcc/
	* config/riscv/predicates.md (movcc_operand): New predicate.
	* config/riscv/riscv.cc (riscv_expand_conditional_move): Handle
	generic targets.
	* config/riscv/riscv.md (mov<mode>cc): Likewise.
	* config/riscv/riscv.opt (mmovcc): New option.
	* doc/invoke.texi (Option Summary): Document it.

	gcc/testsuite/
	* gcc.target/riscv/zbs-bext-02.c: Adjust to reject SLL rather 
	than AND.
---
 gcc/config/riscv/predicates.md               |    6 +++
 gcc/config/riscv/riscv.cc                    |   41 ++++++++++++++++++++++-----
 gcc/config/riscv/riscv.md                    |    7 ++--
 gcc/config/riscv/riscv.opt                   |    4 ++
 gcc/doc/invoke.texi                          |    9 +++++
 gcc/testsuite/gcc.target/riscv/zbs-bext-02.c |    2 -
 6 files changed, 58 insertions(+), 11 deletions(-)

gcc-riscv-movcc.diff
Index: gcc/gcc/config/riscv/predicates.md
===================================================================
--- gcc.orig/gcc/config/riscv/predicates.md
+++ gcc/gcc/config/riscv/predicates.md
@@ -41,6 +41,12 @@
   (ior (match_operand 0 "arith_operand")
        (match_operand 0 "lui_operand")))
 
+(define_predicate "movcc_operand"
+  (if_then_else (match_test "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV
+			     || TARGET_ZICOND_LIKE")
+		(match_operand 0 "sfb_alu_operand")
+		(match_operand 0 "arith_operand")))
+
 (define_predicate "const_csr_operand"
   (and (match_code "const_int")
        (match_test "IN_RANGE (INTVAL (op), 0, 31)")))
Index: gcc/gcc/config/riscv/riscv.cc
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.cc
+++ gcc/gcc/config/riscv/riscv.cc
@@ -4099,7 +4099,9 @@ riscv_expand_conditional_move (rtx dest,
   rtx op0 = XEXP (op, 0);
   rtx op1 = XEXP (op, 1);
 
-  if ((TARGET_ZICOND_LIKE && GET_MODE_CLASS (mode) == MODE_INT)
+  if (((TARGET_ZICOND_LIKE
+	|| (arith_operand (cons, mode) && arith_operand (alt, mode)))
+       && (GET_MODE_CLASS (mode) == MODE_INT))
       || TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
     {
       machine_mode mode0 = GET_MODE (op0);
@@ -4113,6 +4115,15 @@ riscv_expand_conditional_move (rtx dest,
 	  || (mode1 != word_mode && mode1 != VOIDmode))
 	return false;
 
+      /* In the fallback generic case use MODE rather than WORD_MODE for
+	 the output of the SCC instruction, to match the mode of the NEG
+	 operation below.  The output of SCC is 0 or 1 boolean, so it is
+	 valid for input in any scalar integer mode.  */
+      rtx tmp = gen_reg_rtx ((TARGET_ZICOND_LIKE
+			      || TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
+			     ? word_mode : mode);
+      bool invert = false;
+
       /* Canonicalize the comparison.  It must be an equality comparison
 	 of integer operands, or with SFB it can be any comparison of
 	 integer operands.  If it isn't, then emit an SCC instruction
@@ -4121,7 +4132,6 @@ riscv_expand_conditional_move (rtx dest,
 	  || !INTEGRAL_MODE_P (mode0))
 	{
 	  bool *invert_ptr = nullptr;
-	  bool invert = false;
 
 	  /* If riscv_expand_int_scc inverts the condition, then it will
 	     flip the value of INVERT.  We need to know where so that
@@ -4129,11 +4139,9 @@ riscv_expand_conditional_move (rtx dest,
 	  if (code == LE || code == LEU || code == GE || code == GEU)
 	    invert_ptr = &invert;
 
-	  /* Emit an scc like instruction into a temporary
-	     so that we can use an EQ/NE comparison.  */
-	  rtx tmp = gen_reg_rtx (word_mode);
-
-	  /* We can support both FP and integer conditional moves.  */
+	  /* Emit an SCC-like instruction into a temporary so that we can
+	     use an EQ/NE comparison.  We can support both FP and integer
+	     conditional moves.  */
 	  if (INTEGRAL_MODE_P (mode0))
 	    riscv_expand_int_scc (tmp, code, op0, op1, invert_ptr);
 	  else if (FLOAT_MODE_P (mode0)
@@ -4149,6 +4157,8 @@ riscv_expand_conditional_move (rtx dest,
 	  op0 = XEXP (op, 0);
 	  op1 = XEXP (op, 1);
 	}
+      else if (!TARGET_ZICOND_LIKE && !TARGET_SFB_ALU && !TARGET_XTHEADCONDMOV)
+	riscv_expand_int_scc (tmp, code, op0, op1, &invert);
 
       if (TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
 	{
@@ -4166,6 +4176,23 @@ riscv_expand_conditional_move (rtx dest,
 							      cons, alt)));
 	  return true;
 	}
+      else if (!TARGET_ZICOND_LIKE)
+	{
+	  if (invert)
+	    std::swap (cons, alt);
+
+	  rtx reg1 = gen_reg_rtx (mode);
+	  rtx reg2 = gen_reg_rtx (mode);
+	  rtx reg3 = gen_reg_rtx (mode);
+	  rtx reg4 = gen_reg_rtx (mode);
+
+	  riscv_emit_unary (NEG, reg1, tmp);
+	  riscv_emit_binary (AND, reg2, reg1, cons);
+	  riscv_emit_unary (NOT, reg3, reg1);
+	  riscv_emit_binary (AND, reg4, reg3, alt);
+	  riscv_emit_binary (IOR, dest, reg2, reg4);
+	  return true;
+	}
       /* 0, reg or 0, imm */
       else if (cons == CONST0_RTX (mode)
 	       && (REG_P (alt)
Index: gcc/gcc/config/riscv/riscv.md
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.md
+++ gcc/gcc/config/riscv/riscv.md
@@ -2658,9 +2658,10 @@
 (define_expand "mov<mode>cc"
   [(set (match_operand:GPR 0 "register_operand")
 	(if_then_else:GPR (match_operand 1 "comparison_operator")
-			  (match_operand:GPR 2 "sfb_alu_operand")
-			  (match_operand:GPR 3 "sfb_alu_operand")))]
-  "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV || TARGET_ZICOND_LIKE"
+			  (match_operand:GPR 2 "movcc_operand")
+			  (match_operand:GPR 3 "movcc_operand")))]
+  "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV || TARGET_ZICOND_LIKE
+   || TARGET_MOVCC"
 {
   if (riscv_expand_conditional_move (operands[0], operands[1],
 				     operands[2], operands[3]))
Index: gcc/gcc/config/riscv/riscv.opt
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.opt
+++ gcc/gcc/config/riscv/riscv.opt
@@ -460,6 +460,10 @@ misa-spec=
 Target RejectNegative Joined Enum(isa_spec_class) Var(riscv_isa_spec) Init(TARGET_DEFAULT_ISA_SPEC)
 Set the version of RISC-V ISA spec.
 
+mmovcc
+Target Var(TARGET_MOVCC)
+Enable conditional moves unconditionally.
+
 minline-atomics
 Target Var(TARGET_INLINE_SUBWORD_ATOMIC) Init(1)
 Always inline subword atomic operations.
Index: gcc/gcc/doc/invoke.texi
===================================================================
--- gcc.orig/gcc/doc/invoke.texi
+++ gcc/gcc/doc/invoke.texi
@@ -1242,6 +1242,7 @@ See RS/6000 and PowerPC Options.
 -mstack-protector-guard=@var{guard}  -mstack-protector-guard-reg=@var{reg}
 -mstack-protector-guard-offset=@var{offset}
 -mcsr-check -mno-csr-check
+-mmovcc  -mno-movcc
 -minline-atomics  -mno-inline-atomics
 -minline-strlen  -mno-inline-strlen
 -minline-strcmp  -mno-inline-strcmp
@@ -29586,6 +29587,14 @@ Do or don't use smaller but slower prolo
 library function calls.  The default is to use fast inline prologues and
 epilogues.
 
+@opindex mmovcc
+@item -mmovcc
+@itemx -mno-movcc
+Do or don't produce branchless conditional-move code sequences even with
+targets that do not have specific instructions for conditional operations.
+If enabled, sequences of ALU operations are produced using base integer
+ISA instructions where profitable.
+
 @opindex minline-atomics
 @item -minline-atomics
 @itemx -mno-inline-atomics
Index: gcc/gcc/testsuite/gcc.target/riscv/zbs-bext-02.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/zbs-bext-02.c
+++ gcc/gcc/testsuite/gcc.target/riscv/zbs-bext-02.c
@@ -15,4 +15,4 @@ foo(const long long B, int a)
 
 /* { dg-final { scan-assembler-times "bext\t" 1 } } */
 /* { dg-final { scan-assembler-not {\mbset} } } */
-/* { dg-final { scan-assembler-not {\mand} } } */
+/* { dg-final { scan-assembler-not {\msll} } } */

  parent reply	other threads:[~2023-11-19  5:40 UTC|newest]

Thread overview: 101+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
2023-11-18 16:50 ` [PATCH 13/44] RISC-V/testsuite: Add branchless cases for FP cond-move operations Maciej W. Rozycki
2023-11-18 18:03   ` Jeff Law
2023-11-19  6:27     ` Maciej W. Rozycki
2023-11-19  5:37   ` Maciej W. Rozycki
2023-11-19  5:35 ` [PATCH 01/44] testsuite: Add cases for conditional-move and conditional-add operations Maciej W. Rozycki
2023-11-19  5:52   ` Kito Cheng
2023-11-20 10:16     ` Maciej W. Rozycki
2023-11-20 12:57       ` Richard Biener
2023-11-22  1:33         ` Maciej W. Rozycki
2023-11-19  5:35 ` [PATCH 02/44] RISC-V/testsuite: Add cases for integer SFB cond-move operations Maciej W. Rozycki
2023-11-19  5:53   ` Kito Cheng
2023-11-19  5:35 ` [PATCH 03/44] RISC-V: Reorder comment on SFB patterns Maciej W. Rozycki
2023-11-19  5:53   ` Kito Cheng
2023-11-19  5:36 ` [PATCH 04/44] RISC-V: Sanitise NEED_EQ_NE_P case with `riscv_emit_int_compare' Maciej W. Rozycki
2023-11-19  5:53   ` Kito Cheng
2023-11-19  5:36 ` [PATCH 05/44] RISC-V: Fix `mode' usage in `riscv_expand_conditional_move' Maciej W. Rozycki
2023-11-19  5:54   ` Kito Cheng
2023-11-19  5:36 ` [PATCH 06/44] RISC-V: Avoid repeated GET_MODE calls " Maciej W. Rozycki
2023-11-19  5:55   ` Kito Cheng
2023-11-19  5:36 ` [PATCH 07/44] RISC-V: Use `nullptr' " Maciej W. Rozycki
2023-11-19  5:53   ` Kito Cheng
2023-11-19  5:36 ` [PATCH 08/44] RISC-V: Simplify EQ vs NE selection " Maciej W. Rozycki
2023-11-19  5:56   ` Kito Cheng
2023-11-19  5:36 ` [PATCH 09/44] RISC-V: Rework branch costing model for if-conversion Maciej W. Rozycki
2023-11-19 18:52   ` Jeff Law
2023-11-23 18:34     ` Maciej W. Rozycki
2023-11-29  1:19       ` Jeff Law
2023-11-29 12:01         ` Maciej W. Rozycki
2023-11-19  5:37 ` [PATCH 10/44] RISC-V/testsuite: Add branched cases for integer cond-move operations Maciej W. Rozycki
2023-11-19  6:44   ` Kito Cheng
2023-11-19  5:37 ` [PATCH 11/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
2023-11-19  6:47   ` Kito Cheng
2023-11-23 19:18     ` Maciej W. Rozycki
2023-11-19  5:37 ` [PATCH 12/44] RISC-V/testsuite: Add branched cases for FP " Maciej W. Rozycki
2023-11-19  6:48   ` Kito Cheng
2023-11-19  5:38 ` [PATCH 14/44] RISC-V: Also invert the cond-move condition for GEU and LEU Maciej W. Rozycki
2023-11-19  6:50   ` Kito Cheng
2023-11-19  5:38 ` [PATCH 15/44] RISC-V/testsuite: Add branched cases for GEU and LEU cond-move operations Maciej W. Rozycki
2023-11-19 17:42   ` Jeff Law
2023-11-19  5:38 ` [PATCH 16/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
2023-11-19  7:22   ` Kito Cheng
2023-11-19  5:38 ` [PATCH 17/44] RISC-V: Avoid extraneous EQ or NE operation in cond-move expansion Maciej W. Rozycki
2023-11-19 17:45   ` Jeff Law
2023-11-19  5:38 ` [PATCH 18/44] RISC-V/testsuite: Add branched cases for equality cond-move operations Maciej W. Rozycki
2023-11-19 17:45   ` Jeff Law
2023-11-19  5:39 ` [PATCH 19/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
2023-11-19 17:46   ` Jeff Law
2023-11-19  5:39 ` [PATCH 20/44] RISC-V: Also accept constants for T-Head cond-move comparison operands Maciej W. Rozycki
2023-11-19 17:48   ` Jeff Law
2023-11-19  5:39 ` [PATCH 21/44] RISC-V: Also accept constants for T-Head cond-move data input operands Maciej W. Rozycki
2023-11-19 17:50   ` Jeff Law
2023-11-19  5:40 ` [PATCH 22/44] RISC-V: Fold all the cond-move variants together Maciej W. Rozycki
2023-11-19 18:35   ` Jeff Law
2023-11-19  5:40 ` [PATCH 23/44] RISC-V/testsuite: Add branched cases for T-Head non-equality cond moves Maciej W. Rozycki
2023-11-19 17:54   ` Jeff Law
2023-11-19  5:40 ` [PATCH 24/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
2023-11-19 17:54   ` Jeff Law
2023-11-19  5:40 ` [PATCH 25/44] RISC-V: Implement `riscv_emit_unary' helper Maciej W. Rozycki
2023-11-19 17:54   ` Jeff Law
2023-11-19  5:40 ` Maciej W. Rozycki [this message]
2023-11-19 18:18   ` [PATCH 26/44] RISC-V: Add `movMODEcc' implementation for generic targets Jeff Law
2023-11-23 22:16     ` Maciej W. Rozycki
2023-11-19  5:40 ` [PATCH 27/44] RISC-V/testsuite: Add branched cases for generic integer cond moves Maciej W. Rozycki
2023-11-19 18:18   ` Jeff Law
2023-11-19  5:41 ` [PATCH 28/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
2023-11-19 18:19   ` Jeff Law
2023-11-19  5:41 ` [PATCH 29/44] RISC-V: Add `addMODEcc' implementation for generic targets Maciej W. Rozycki
2023-11-19 18:23   ` Jeff Law
2023-11-23 22:36     ` Maciej W. Rozycki
2023-11-19  5:41 ` [PATCH 30/44] RISC-V/testsuite: Add branched cases for generic integer cond adds Maciej W. Rozycki
2023-11-19 18:23   ` Jeff Law
2023-11-19  5:41 ` [PATCH 31/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
2023-11-19 18:25   ` Jeff Law
2023-11-23 22:48     ` Maciej W. Rozycki
2023-11-19  5:42 ` [PATCH 32/44] RISC-V: Only use SUBREG if applicable in `riscv_expand_float_scc' Maciej W. Rozycki
2023-11-19 18:26   ` Jeff Law
2023-11-19  5:42 ` [PATCH 33/44] RISC-V: Also allow FP conditions in `riscv_expand_conditional_move' Maciej W. Rozycki
2023-11-19 18:30   ` Jeff Law
2023-11-23 22:55     ` Maciej W. Rozycki
2023-11-19  5:42 ` [PATCH 34/44] RISC-V: Provide FP conditional-branch instructions for if-conversion Maciej W. Rozycki
2023-11-19 19:42   ` Jeff Law
2023-11-23 23:26     ` Maciej W. Rozycki
2023-11-19  5:42 ` [PATCH 35/44] RISC-V: Avoid extraneous integer comparison for FP comparisons Maciej W. Rozycki
2023-11-19 19:44   ` Jeff Law
2023-11-19  5:42 ` [PATCH 36/44] RISC-V/testsuite: Add branched cases for generic FP cond moves Maciej W. Rozycki
2023-11-19 19:45   ` Jeff Law
2023-11-19  5:43 ` [PATCH 37/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
2023-11-19 19:46   ` Jeff Law
2023-11-19  5:43 ` [PATCH 38/44] RISC-V/testsuite: Add branched cases for generic FP cond adds Maciej W. Rozycki
2023-11-19 19:46   ` Jeff Law
2023-11-19  5:43 ` [PATCH 39/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
2023-11-19 19:47   ` Jeff Law
2023-11-19  5:43 ` [PATCH 40/44] RISC-V: Handle FP NE operator via inversion in cond-operation expansion Maciej W. Rozycki
2023-11-19 19:51   ` Jeff Law
2023-11-22  1:37     ` Maciej W. Rozycki
2023-11-19  5:43 ` [PATCH 41/44] RISC-V/testsuite: Add branched cases for FP NE cond-move operations Maciej W. Rozycki
2023-11-19  5:43 ` [PATCH 42/44] " Maciej W. Rozycki
2023-11-19  5:44 ` [PATCH 43/44] RISC-V/testsuite: Add branched cases for FP NE cond-add operation Maciej W. Rozycki
2023-11-19  5:44 ` [PATCH 44/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
2023-11-19  5:52 ` [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Kito Cheng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.DEB.2.20.2311181833450.5892@tpp.orcam.me.uk \
    --to=macro@embecosm.com \
    --cc=andrew@sifive.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jim.wilson.gcc@gmail.com \
    --cc=kito.cheng@gmail.com \
    --cc=palmer@dabbelt.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).