diff mbox series

[29/44] RISC-V: Add `addMODEcc' implementation for generic targets

Message ID alpine.DEB.2.20.2311182054440.5892@tpp.orcam.me.uk
State New
Headers show
Series RISC-V: Various if-conversion fixes and improvements | expand

Commit Message

Maciej W. Rozycki Nov. 19, 2023, 5:41 a.m. UTC
Provide RTL expansion of conditional-add operations for generic targets 
using a suitable sequence of base integer machine instructions according 
to cost evaluation by if-conversion.  Use existing `-mmovcc' command 
line option to enable this transformation.

	gcc/
	* config/riscv/riscv.md (add<mode>cc): New expander.
---
 gcc/config/riscv/riscv.md |   41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

Comments

Jeff Law Nov. 19, 2023, 6:23 p.m. UTC | #1
On 11/18/23 22:41, Maciej W. Rozycki wrote:
> Provide RTL expansion of conditional-add operations for generic targets
> using a suitable sequence of base integer machine instructions according
> to cost evaluation by if-conversion.  Use existing `-mmovcc' command
> line option to enable this transformation.
> 
> 	gcc/
> 	* config/riscv/riscv.md (add<mode>cc): New expander.
Is this an improvement over what if-convert creates for a conditional 
add or is the goal to expose the sequence earlier in the pipeline rather 
than waiting for ifcvt?

Either way this is fine, just questioning slightly if really improves 
things.  I don't see any way it'd be hurting.

jeff
Maciej W. Rozycki Nov. 23, 2023, 10:36 p.m. UTC | #2
On Sun, 19 Nov 2023, Jeff Law wrote:

> Is this an improvement over what if-convert creates for a conditional add or
> is the goal to expose the sequence earlier in the pipeline rather than waiting
> for ifcvt?

 TBH I haven't ever seen if-convert eliminate a branch here without this 
pattern supplied.  Maybe I've missed something in my previous evaluation, 
but building a representative subset of the add*.c test cases from this 
patch series without the `-mmovcc' option seems to confirm my observation, 
so I consider it a new feature rather than just an improvement.  This is 
also why in the cover letter I suggested that we may consider moving this 
optimisation into if-convert proper later on, to benefit other targets.

  Maciej
diff mbox series

Patch

Index: gcc/gcc/config/riscv/riscv.md
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.md
+++ gcc/gcc/config/riscv/riscv.md
@@ -2655,6 +2655,8 @@ 
   [(set_attr "type" "branch")
    (set_attr "mode" "none")])
 
+;; Conditional move and add patterns.
+
 (define_expand "mov<mode>cc"
   [(set (match_operand:GPR 0 "register_operand")
 	(if_then_else:GPR (match_operand 1 "comparison_operator")
@@ -2670,6 +2672,45 @@ 
     FAIL;
 })
 
+(define_expand "add<mode>cc"
+  [(match_operand:GPR 0 "register_operand")
+   (match_operand     1 "comparison_operator")
+   (match_operand:GPR 2 "arith_operand")
+   (match_operand:GPR 3 "arith_operand")]
+  "TARGET_MOVCC"
+{
+  rtx cmp = operands[1];
+  rtx cmp0 = XEXP (cmp, 0);
+  rtx cmp1 = XEXP (cmp, 1);
+  machine_mode mode0 = GET_MODE (cmp0);
+
+  /* We only handle word mode integer compares for now.  */
+  if (INTEGRAL_MODE_P (mode0) && mode0 != word_mode)
+    FAIL;
+
+  enum rtx_code code = GET_CODE (cmp);
+  rtx reg0 = gen_reg_rtx (<MODE>mode);
+  rtx reg1 = gen_reg_rtx (<MODE>mode);
+  rtx reg2 = gen_reg_rtx (<MODE>mode);
+  bool invert = false;
+
+  if (INTEGRAL_MODE_P (mode0))
+    riscv_expand_int_scc (reg0, code, cmp0, cmp1, &invert);
+  else if (FLOAT_MODE_P (mode0) && fp_scc_comparison (cmp, GET_MODE (cmp)))
+    riscv_expand_float_scc (reg0, code, cmp0, cmp1);
+  else
+    FAIL;
+
+  if (invert)
+    riscv_emit_binary (PLUS, reg1, reg0, constm1_rtx);
+  else
+    riscv_emit_unary (NEG, reg1, reg0);
+  riscv_emit_binary (AND, reg2, reg1, operands[3]);
+  riscv_emit_binary (PLUS, operands[0], reg2, operands[2]);
+
+  DONE;
+})
+
 ;; Patterns for implementations that optimize short forward branches.
 
 (define_insn "*mov<GPR:mode><X:mode>cc"