public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 13/44] RISC-V/testsuite: Add branchless cases for FP cond-move operations
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
@ 2023-11-18 16:50 ` Maciej W. Rozycki
  2023-11-18 18:03   ` Jeff Law
  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
                   ` (43 subsequent siblings)
  44 siblings, 2 replies; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-18 16:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for short forward branch, T-Head, Ventana and Zicond targets and 
the ordered floating-point conditional-move operations that already work 
as expected, that if-conversion triggers via `noce_try_cmove' at the 
respective sufficiently high `-mbranch-cost=' settings that make 
branchless code sequences produced by if-conversion cheaper than their 
original branched equivalents, and that extraneous instructions such as 
SNEZ, etc. are not present in output.  Cover all ordered floating-point 
relational operations to make sure no corner case escapes.

	gcc/testsuite/
	* gcc.target/riscv/movdifge-sfb.c: New test.
	* gcc.target/riscv/movdifge-thead.c: New test.
	* gcc.target/riscv/movdifge-ventana.c: New test.
	* gcc.target/riscv/movdifge-zicond.c: New test.
	* gcc.target/riscv/movdifgt-sfb.c: New test.
	* gcc.target/riscv/movdifgt-thead.c: New test.
	* gcc.target/riscv/movdifgt-ventana.c: New test.
	* gcc.target/riscv/movdifgt-zicond.c: New test.
	* gcc.target/riscv/movdifle-sfb.c: New test.
	* gcc.target/riscv/movdifle-thead.c: New test.
	* gcc.target/riscv/movdifle-ventana.c: New test.
	* gcc.target/riscv/movdifle-zicond.c: New test.
	* gcc.target/riscv/movdiflt-sfb.c: New test.
	* gcc.target/riscv/movdiflt-thead.c: New test.
	* gcc.target/riscv/movdiflt-ventana.c: New test.
	* gcc.target/riscv/movdiflt-zicond.c: New test.
	* gcc.target/riscv/movdifne-sfb.c: New test.
	* gcc.target/riscv/movdifne-thead.c: New test.
	* gcc.target/riscv/movdifne-ventana.c: New test.
	* gcc.target/riscv/movdifne-zicond.c: New test.
	* gcc.target/riscv/movsifge-sfb.c: New test.
	* gcc.target/riscv/movsifge-thead.c: New test.
	* gcc.target/riscv/movsifge-ventana.c: New test.
	* gcc.target/riscv/movsifge-zicond.c: New test.
	* gcc.target/riscv/movsifgt-sfb.c: New test.
	* gcc.target/riscv/movsifgt-thead.c: New test.
	* gcc.target/riscv/movsifgt-ventana.c: New test.
	* gcc.target/riscv/movsifgt-zicond.c: New test.
	* gcc.target/riscv/movsifle-sfb.c: New test.
	* gcc.target/riscv/movsifle-thead.c: New test.
	* gcc.target/riscv/movsifle-ventana.c: New test.
	* gcc.target/riscv/movsifle-zicond.c: New test.
	* gcc.target/riscv/movsiflt-sfb.c: New test.
	* gcc.target/riscv/movsiflt-thead.c: New test.
	* gcc.target/riscv/movsiflt-ventana.c: New test.
	* gcc.target/riscv/movsiflt-zicond.c: New test.
	* gcc.target/riscv/movsifne-sfb.c: New test.
	* gcc.target/riscv/movsifne-thead.c: New test.
	* gcc.target/riscv/movsifne-ventana.c: New test.
	* gcc.target/riscv/movsifne-zicond.c: New test.
---
 gcc/testsuite/gcc.target/riscv/movdifge-sfb.c     |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifge-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifge-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifge-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifgt-sfb.c     |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifgt-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifgt-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifgt-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifle-sfb.c     |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifle-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifle-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifle-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdiflt-sfb.c     |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdiflt-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdiflt-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdiflt-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifne-sfb.c     |   27 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifne-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifne-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifne-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifge-sfb.c     |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifge-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifge-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifge-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifgt-sfb.c     |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifgt-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifgt-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifgt-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifle-sfb.c     |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifle-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifle-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifle-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsiflt-sfb.c     |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsiflt-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsiflt-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsiflt-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifne-sfb.c     |   27 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifne-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifne-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifne-zicond.c  |   28 ++++++++++++++++++++++
 40 files changed, 1072 insertions(+)

gcc-riscv-branch-cost-test-movccf.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifge-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifge-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	fge.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifge-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifge-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fge.d	a5,fa0,fa1
+	th.mveqz	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifge-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifge-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fge.d	a5,fa0,fa1
+	vt.maskc	a0,a0,a5
+	vt.maskcn	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifge-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifge-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fge.d	a5,fa0,fa1
+	czero.eqz	a0,a0,a5
+	czero.nez	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifgt-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifgt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	fgt.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifgt-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifgt-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fgt.d	a5,fa0,fa1
+	th.mveqz	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifgt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifgt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fgt.d	a5,fa0,fa1
+	vt.maskc	a0,a0,a5
+	vt.maskcn	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifgt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifgt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fgt.d	a5,fa0,fa1
+	czero.eqz	a0,a0,a5
+	czero.nez	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifle-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifle-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	fle.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifle-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifle-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fle.d	a5,fa0,fa1
+	th.mveqz	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifle-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifle-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fle.d	a5,fa0,fa1
+	vt.maskc	a0,a0,a5
+	vt.maskcn	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifle-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifle-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fle.d	a5,fa0,fa1
+	czero.eqz	a0,a0,a5
+	czero.nez	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiflt-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiflt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	flt.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiflt-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiflt-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	flt.d	a5,fa0,fa1
+	th.mveqz	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiflt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiflt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	flt.d	a5,fa0,fa1
+	vt.maskc	a0,a0,a5
+	vt.maskcn	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiflt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiflt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	flt.d	a5,fa0,fa1
+	czero.eqz	a0,a0,a5
+	czero.nez	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifne-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifne-sfb.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	feq.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a1,a0
+1:
+	mv	a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifne-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifne-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	th.mvnez	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifne-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifne-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	vt.maskc	a1,a1,a5
+	vt.maskcn	a0,a0,a5
+	or	a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifne-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifne-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	czero.eqz	a1,a1,a5
+	czero.nez	a0,a0,a5
+	or	a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifge-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifge-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	fge.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifge-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifge-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fge.d	a5,fa0,fa1
+	th.mveqz	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifge-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifge-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fge.d	a5,fa0,fa1
+	vt.maskc	a0,a0,a5
+	vt.maskcn	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifge-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifge-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fge.d	a5,fa0,fa1
+	czero.eqz	a0,a0,a5
+	czero.nez	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifgt-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifgt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	fgt.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifgt-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifgt-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fgt.d	a5,fa0,fa1
+	th.mveqz	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifgt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifgt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fgt.d	a5,fa0,fa1
+	vt.maskc	a0,a0,a5
+	vt.maskcn	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifgt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifgt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fgt.d	a5,fa0,fa1
+	czero.eqz	a0,a0,a5
+	czero.nez	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifle-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifle-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	fle.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifle-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifle-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fle.d	a5,fa0,fa1
+	th.mveqz	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifle-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifle-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fle.d	a5,fa0,fa1
+	vt.maskc	a0,a0,a5
+	vt.maskcn	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifle-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifle-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fle.d	a5,fa0,fa1
+	czero.eqz	a0,a0,a5
+	czero.nez	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiflt-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiflt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	flt.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiflt-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiflt-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	flt.d	a5,fa0,fa1
+	th.mveqz	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiflt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiflt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	flt.d	a5,fa0,fa1
+	vt.maskc	a0,a0,a5
+	vt.maskcn	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiflt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiflt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	flt.d	a5,fa0,fa1
+	czero.eqz	a0,a0,a5
+	czero.nez	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifne-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifne-sfb.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	feq.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a1,a0
+1:
+	mv	a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifne-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifne-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	th.mvnez	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifne-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifne-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	vt.maskc	a1,a1,a5
+	vt.maskcn	a0,a0,a5
+	or	a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifne-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifne-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	czero.eqz	a1,a1,a5
+	czero.nez	a0,a0,a5
+	or	a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 13/44] RISC-V/testsuite: Add branchless cases for FP cond-move operations
  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
  1 sibling, 1 reply; 101+ messages in thread
From: Jeff Law @ 2023-11-18 18:03 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 09:50, Maciej W. Rozycki wrote:
> Verify, for short forward branch, T-Head, Ventana and Zicond targets and
> the ordered floating-point conditional-move operations that already work
> as expected, that if-conversion triggers via `noce_try_cmove' at the
> respective sufficiently high `-mbranch-cost=' settings that make
> branchless code sequences produced by if-conversion cheaper than their
> original branched equivalents, and that extraneous instructions such as
> SNEZ, etc. are not present in output.  Cover all ordered floating-point
> relational operations to make sure no corner case escapes.
> 
> 	gcc/testsuite/
> 	* gcc.target/riscv/movdifge-sfb.c: New test.
> 	* gcc.target/riscv/movdifge-thead.c: New test.
> 	* gcc.target/riscv/movdifge-ventana.c: New test.
> 	* gcc.target/riscv/movdifge-zicond.c: New test.
> 	* gcc.target/riscv/movdifgt-sfb.c: New test.
> 	* gcc.target/riscv/movdifgt-thead.c: New test.
> 	* gcc.target/riscv/movdifgt-ventana.c: New test.
> 	* gcc.target/riscv/movdifgt-zicond.c: New test.
> 	* gcc.target/riscv/movdifle-sfb.c: New test.
> 	* gcc.target/riscv/movdifle-thead.c: New test.
> 	* gcc.target/riscv/movdifle-ventana.c: New test.
> 	* gcc.target/riscv/movdifle-zicond.c: New test.
> 	* gcc.target/riscv/movdiflt-sfb.c: New test.
> 	* gcc.target/riscv/movdiflt-thead.c: New test.
> 	* gcc.target/riscv/movdiflt-ventana.c: New test.
> 	* gcc.target/riscv/movdiflt-zicond.c: New test.
> 	* gcc.target/riscv/movdifne-sfb.c: New test.
> 	* gcc.target/riscv/movdifne-thead.c: New test.
> 	* gcc.target/riscv/movdifne-ventana.c: New test.
> 	* gcc.target/riscv/movdifne-zicond.c: New test.
> 	* gcc.target/riscv/movsifge-sfb.c: New test.
> 	* gcc.target/riscv/movsifge-thead.c: New test.
> 	* gcc.target/riscv/movsifge-ventana.c: New test.
> 	* gcc.target/riscv/movsifge-zicond.c: New test.
> 	* gcc.target/riscv/movsifgt-sfb.c: New test.
> 	* gcc.target/riscv/movsifgt-thead.c: New test.
> 	* gcc.target/riscv/movsifgt-ventana.c: New test.
> 	* gcc.target/riscv/movsifgt-zicond.c: New test.
> 	* gcc.target/riscv/movsifle-sfb.c: New test.
> 	* gcc.target/riscv/movsifle-thead.c: New test.
> 	* gcc.target/riscv/movsifle-ventana.c: New test.
> 	* gcc.target/riscv/movsifle-zicond.c: New test.
> 	* gcc.target/riscv/movsiflt-sfb.c: New test.
> 	* gcc.target/riscv/movsiflt-thead.c: New test.
> 	* gcc.target/riscv/movsiflt-ventana.c: New test.
> 	* gcc.target/riscv/movsiflt-zicond.c: New test.
> 	* gcc.target/riscv/movsifne-sfb.c: New test.
> 	* gcc.target/riscv/movsifne-thead.c: New test.
> 	* gcc.target/riscv/movsifne-ventana.c: New test.
> 	* gcc.target/riscv/movsifne-zicond.c: New test.
Is this dependent on any of the other patches in this series?  Or is it 
independent and ready to go as-is?  I ask becuase it's marked as 13/44 
and I haven't seen the other 43 patches in the series :-)

If it's independent and been tested, then it's OK for the trunk.  I'll 
trust your regexps :-)

jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements
@ 2023-11-19  5:35 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
                   ` (44 more replies)
  0 siblings, 45 replies; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:35 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Hi,

 This patch series has come out from a simple change to add generic 
conditional-move and conditional-add expansions for a yet-out-of-tree 
target, which has relatively expensive branches and no conditional 
operations beyond the base architecture conditional-set instructions.  At 
one point I have concluded it may make sense to release this code to the 
general public, especially as some of the conditional execution sequences 
will trigger for targets we already have support for.  Naturally as a part 
of a proper upstream submission I chose to add suitable test cases.

 Now these test cases triggered a lot of issues in our existing code and 
as I fixed them what was supposed to be a couple of patches has turned 
into this humongous patch series, including a branch costing model rework.  
Oh well.

 Please see individual change descriptions for the details.  The overall 
patch series structure is as follows:

- 01-02 add test cases covering the existing state that won't change 
  throughout the patch series,

- 03-08 make small preparatory clean-ups that do not change semantics,

- 09-13 implement a branch cost model rework and add the associated test 
  cases,

- 14-24 make various improvements for integer conditional operations and 
  add the associated test cases,

- 25-28 add generic `movMODEcc' support and the associated test cases,

- 29-31 add generic `addMODEcc' support and the associated test cases,

- 32-44 make various improvements for floating-point conditional 
  operations and add the associated test cases.

There is potential here for middle end improvement, in particular branch 
costing is already documented in if-cvt.cc to be intended to consistently 
use BRANCH_COST, and then the generic conditional-move and conditional-add 
sequences could I suppose be emitted there in a target-agnostic way rather 
than being supplied by the backend.  This I suppose could be investigated 
in the future if the RISC-V approach turned out potentially useful for 
other targets.

 This has been so far verified as follows, using SiFive HiFive Unmatched 
hardware and the `riscv64-linux-gnu' target:

- New target test cases have been run with `-mtune=sifive-5-series',
  `-mtune=sifive-5-series/-march=rv32gc/-mabi=ilp32d' and 
  `-mtune=sifive-5-series/-mmovcc/-mbranch-cost=8' DejaGNU board options.

- The C language test suite has been run at significant points in the 
  patch series with `-mtune=sifive-5-series' and (past 26/44) also with 
  `-mtune=sifive-5-series/-mmovcc/-mbranch-cost=8', and selectively with 
  `-mtune=sifive-7-series' and
  `-mtune=sifive-7-series/-mmovcc/-mbranch-cost=8' DejaGNU board options.

Since this is huge and every test iteration takes a couple of hours I will 
continue running testing and may investigate running QEMU testing for the 
features the Unmatched does not support such as Zicond.  I don't expect 
real issues however.

 There are a bunch of issues triggered with `-mmovcc/-mbranch-cost=8' or 
with lone `-mbranch-cost=8' even and the vector test cases, which are 
either due to match patterns expecting an assembly label that has been 
reordered or are similar to PR target/112092 and which are not a problem 
with this patch series, but rather one with the vector testsuite or code.

 Any questions, comments, or concerns?  Otherwise OK to apply?

  Maciej

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 01/44] testsuite: Add cases for conditional-move and conditional-add operations
  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-19  5:35 ` Maciej W. Rozycki
  2023-11-19  5:52   ` Kito Cheng
  2023-11-19  5:35 ` [PATCH 02/44] RISC-V/testsuite: Add cases for integer SFB cond-move operations Maciej W. Rozycki
                   ` (42 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:35 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Add generic execution tests for expressions that are expected to expand 
to conditional-move and conditional-add operations where supported.  To 
ensure no corner case escapes all relational operators are extensively 
covered for integer comparisons and all ordered operators are covered 
for floating-point comparisons.  Unordered operators are not covered at 
this point as they'd require a different input data set.

	gcc/testsuite/
	* gcc.dg/torture/addieq.c: New test.
	* gcc.dg/torture/addifeq.c: New test.
	* gcc.dg/torture/addifge.c: New test.
	* gcc.dg/torture/addifgt.c: New test.
	* gcc.dg/torture/addifle.c: New test.
	* gcc.dg/torture/addiflt.c: New test.
	* gcc.dg/torture/addifne.c: New test.
	* gcc.dg/torture/addige.c: New test.
	* gcc.dg/torture/addigeu.c: New test.
	* gcc.dg/torture/addigt.c: New test.
	* gcc.dg/torture/addigtu.c: New test.
	* gcc.dg/torture/addile.c: New test.
	* gcc.dg/torture/addileu.c: New test.
	* gcc.dg/torture/addilt.c: New test.
	* gcc.dg/torture/addiltu.c: New test.
	* gcc.dg/torture/addine.c: New test.
	* gcc.dg/torture/addleq.c: New test.
	* gcc.dg/torture/addlfeq.c: New test.
	* gcc.dg/torture/addlfge.c: New test.
	* gcc.dg/torture/addlfgt.c: New test.
	* gcc.dg/torture/addlfle.c: New test.
	* gcc.dg/torture/addlflt.c: New test.
	* gcc.dg/torture/addlfne.c: New test.
	* gcc.dg/torture/addlge.c: New test.
	* gcc.dg/torture/addlgeu.c: New test.
	* gcc.dg/torture/addlgt.c: New test.
	* gcc.dg/torture/addlgtu.c: New test.
	* gcc.dg/torture/addlle.c: New test.
	* gcc.dg/torture/addlleu.c: New test.
	* gcc.dg/torture/addllt.c: New test.
	* gcc.dg/torture/addlltu.c: New test.
	* gcc.dg/torture/addlne.c: New test.
	* gcc.dg/torture/movieq.c: New test.
	* gcc.dg/torture/movifeq.c: New test.
	* gcc.dg/torture/movifge.c: New test.
	* gcc.dg/torture/movifgt.c: New test.
	* gcc.dg/torture/movifle.c: New test.
	* gcc.dg/torture/moviflt.c: New test.
	* gcc.dg/torture/movifne.c: New test.
	* gcc.dg/torture/movige.c: New test.
	* gcc.dg/torture/movigeu.c: New test.
	* gcc.dg/torture/movigt.c: New test.
	* gcc.dg/torture/movigtu.c: New test.
	* gcc.dg/torture/movile.c: New test.
	* gcc.dg/torture/movileu.c: New test.
	* gcc.dg/torture/movilt.c: New test.
	* gcc.dg/torture/moviltu.c: New test.
	* gcc.dg/torture/movine.c: New test.
	* gcc.dg/torture/movleq.c: New test.
	* gcc.dg/torture/movlfeq.c: New test.
	* gcc.dg/torture/movlfge.c: New test.
	* gcc.dg/torture/movlfgt.c: New test.
	* gcc.dg/torture/movlfle.c: New test.
	* gcc.dg/torture/movlflt.c: New test.
	* gcc.dg/torture/movlfne.c: New test.
	* gcc.dg/torture/movlge.c: New test.
	* gcc.dg/torture/movlgeu.c: New test.
	* gcc.dg/torture/movlgt.c: New test.
	* gcc.dg/torture/movlgtu.c: New test.
	* gcc.dg/torture/movlle.c: New test.
	* gcc.dg/torture/movlleu.c: New test.
	* gcc.dg/torture/movllt.c: New test.
	* gcc.dg/torture/movlltu.c: New test.
	* gcc.dg/torture/movlne.c: New test.
---
 gcc/testsuite/gcc.dg/torture/addieq.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addifeq.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addifge.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addifgt.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addifle.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addiflt.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addifne.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addige.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addigeu.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addigt.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addigtu.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addile.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addileu.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addilt.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addiltu.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addine.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addleq.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addlfeq.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addlfge.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addlfgt.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addlfle.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addlflt.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addlfne.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addlge.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addlgeu.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addlgt.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addlgtu.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addlle.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addlleu.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addllt.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addlltu.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/addlne.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movieq.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movifeq.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movifge.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movifgt.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movifle.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/moviflt.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movifne.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movige.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movigeu.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movigt.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movigtu.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movile.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movileu.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movilt.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/moviltu.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movine.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movleq.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movlfeq.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movlfge.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movlfgt.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movlfle.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movlflt.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movlfne.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movlge.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movlgeu.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movlgt.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movlgtu.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movlle.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movlleu.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movllt.c  |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movlltu.c |   31 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/torture/movlne.c  |   31 +++++++++++++++++++++++++++++++
 64 files changed, 1984 insertions(+)

gcc-test-movcc.diff
Index: gcc/gcc/testsuite/gcc.dg/torture/addieq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addieq.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addieq (-1, -1, 12, 23) != 35)
+    return 1;
+  if (addieq (-1, 3, 12, 23) != 12)
+    return 1;
+  if (addieq (1, 3, 12, 23) != 12)
+    return 1;
+  if (addieq (3, 3, 12, 23) != 35)
+    return 1;
+  if (addieq (5, 3, 12, 23) != 12)
+    return 1;
+  if (addieq (3, -1, 12, 23) != 12)
+    return 1;
+  if (addieq (3, 1, 12, 23) != 12)
+    return 1;
+  if (addieq (3, 5, 12, 23) != 12)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addifeq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addifeq.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addifeq (-1.0, -1.0, 12, 23) != 35)
+    return 1;
+  if (addifeq (-1.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (addifeq (1.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (addifeq (3.0, 3.0, 12, 23) != 35)
+    return 1;
+  if (addifeq (5.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (addifeq (3.0, -1.0, 12, 23) != 12)
+    return 1;
+  if (addifeq (3.0, 1.0, 12, 23) != 12)
+    return 1;
+  if (addifeq (3.0, 5.0, 12, 23) != 12)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addifge.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addifge.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addifge (-1.0, -1.0, 12, 23) != 35)
+    return 1;
+  if (addifge (-1.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (addifge (1.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (addifge (3.0, 3.0, 12, 23) != 35)
+    return 1;
+  if (addifge (5.0, 3.0, 12, 23) != 35)
+    return 1;
+  if (addifge (3.0, -1.0, 12, 23) != 35)
+    return 1;
+  if (addifge (3.0, 1.0, 12, 23) != 35)
+    return 1;
+  if (addifge (3.0, 5.0, 12, 23) != 12)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addifgt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addifgt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addifgt (-1.0, -1.0, 12, 23) != 12)
+    return 1;
+  if (addifgt (-1.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (addifgt (1.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (addifgt (3.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (addifgt (5.0, 3.0, 12, 23) != 35)
+    return 1;
+  if (addifgt (3.0, -1.0, 12, 23) != 35)
+    return 1;
+  if (addifgt (3.0, 1.0, 12, 23) != 35)
+    return 1;
+  if (addifgt (3.0, 5.0, 12, 23) != 12)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addifle.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addifle.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addifle (-1.0, -1.0, 12, 23) != 35)
+    return 1;
+  if (addifle (-1.0, 3.0, 12, 23) != 35)
+    return 1;
+  if (addifle (1.0, 3.0, 12, 23) != 35)
+    return 1;
+  if (addifle (3.0, 3.0, 12, 23) != 35)
+    return 1;
+  if (addifle (5.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (addifle (3.0, -1.0, 12, 23) != 12)
+    return 1;
+  if (addifle (3.0, 1.0, 12, 23) != 12)
+    return 1;
+  if (addifle (3.0, 5.0, 12, 23) != 35)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addiflt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addiflt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addiflt (-1.0, -1.0, 12, 23) != 12)
+    return 1;
+  if (addiflt (-1.0, 3.0, 12, 23) != 35)
+    return 1;
+  if (addiflt (1.0, 3.0, 12, 23) != 35)
+    return 1;
+  if (addiflt (3.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (addiflt (5.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (addiflt (3.0, -1.0, 12, 23) != 12)
+    return 1;
+  if (addiflt (3.0, 1.0, 12, 23) != 12)
+    return 1;
+  if (addiflt (3.0, 5.0, 12, 23) != 35)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addifne.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addifne.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addifne (-1.0, -1.0, 12, 23) != 12)
+    return 1;
+  if (addifne (-1.0, 3.0, 12, 23) != 35)
+    return 1;
+  if (addifne (1.0, 3.0, 12, 23) != 35)
+    return 1;
+  if (addifne (3.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (addifne (5.0, 3.0, 12, 23) != 35)
+    return 1;
+  if (addifne (3.0, -1.0, 12, 23) != 35)
+    return 1;
+  if (addifne (3.0, 1.0, 12, 23) != 35)
+    return 1;
+  if (addifne (3.0, 5.0, 12, 23) != 35)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addige.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addige.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addige (-1, -1, 12, 23) != 35)
+    return 1;
+  if (addige (-1, 3, 12, 23) != 12)
+    return 1;
+  if (addige (1, 3, 12, 23) != 12)
+    return 1;
+  if (addige (3, 3, 12, 23) != 35)
+    return 1;
+  if (addige (5, 3, 12, 23) != 35)
+    return 1;
+  if (addige (3, -1, 12, 23) != 35)
+    return 1;
+  if (addige (3, 1, 12, 23) != 35)
+    return 1;
+  if (addige (3, 5, 12, 23) != 12)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addigeu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addigeu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned int int_t;
+
+__attribute__ ((noinline)) int_t
+addigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addigeu (-1, -1, 12, 23) != 35)
+    return 1;
+  if (addigeu (-1, 3, 12, 23) != 35)
+    return 1;
+  if (addigeu (1, 3, 12, 23) != 12)
+    return 1;
+  if (addigeu (3, 3, 12, 23) != 35)
+    return 1;
+  if (addigeu (5, 3, 12, 23) != 35)
+    return 1;
+  if (addigeu (3, -1, 12, 23) != 12)
+    return 1;
+  if (addigeu (3, 1, 12, 23) != 35)
+    return 1;
+  if (addigeu (3, 5, 12, 23) != 12)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addigt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addigt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addigt (-1, -1, 12, 23) != 12)
+    return 1;
+  if (addigt (-1, 3, 12, 23) != 12)
+    return 1;
+  if (addigt (1, 3, 12, 23) != 12)
+    return 1;
+  if (addigt (3, 3, 12, 23) != 12)
+    return 1;
+  if (addigt (5, 3, 12, 23) != 35)
+    return 1;
+  if (addigt (3, -1, 12, 23) != 35)
+    return 1;
+  if (addigt (3, 1, 12, 23) != 35)
+    return 1;
+  if (addigt (3, 5, 12, 23) != 12)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addigtu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addigtu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned int int_t;
+
+__attribute__ ((noinline)) int_t
+addigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addigtu (-1, -1, 12, 23) != 12)
+    return 1;
+  if (addigtu (-1, 3, 12, 23) != 35)
+    return 1;
+  if (addigtu (1, 3, 12, 23) != 12)
+    return 1;
+  if (addigtu (3, 3, 12, 23) != 12)
+    return 1;
+  if (addigtu (5, 3, 12, 23) != 35)
+    return 1;
+  if (addigtu (3, -1, 12, 23) != 12)
+    return 1;
+  if (addigtu (3, 1, 12, 23) != 35)
+    return 1;
+  if (addigtu (3, 5, 12, 23) != 12)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addile.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addile.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addile (-1, -1, 12, 23) != 35)
+    return 1;
+  if (addile (-1, 3, 12, 23) != 35)
+    return 1;
+  if (addile (1, 3, 12, 23) != 35)
+    return 1;
+  if (addile (3, 3, 12, 23) != 35)
+    return 1;
+  if (addile (5, 3, 12, 23) != 12)
+    return 1;
+  if (addile (3, -1, 12, 23) != 12)
+    return 1;
+  if (addile (3, 1, 12, 23) != 12)
+    return 1;
+  if (addile (3, 5, 12, 23) != 35)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addileu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addileu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned int int_t;
+
+__attribute__ ((noinline)) int_t
+addileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addileu (-1, -1, 12, 23) != 35)
+    return 1;
+  if (addileu (-1, 3, 12, 23) != 12)
+    return 1;
+  if (addileu (1, 3, 12, 23) != 35)
+    return 1;
+  if (addileu (3, 3, 12, 23) != 35)
+    return 1;
+  if (addileu (5, 3, 12, 23) != 12)
+    return 1;
+  if (addileu (3, -1, 12, 23) != 35)
+    return 1;
+  if (addileu (3, 1, 12, 23) != 12)
+    return 1;
+  if (addileu (3, 5, 12, 23) != 35)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addilt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addilt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addilt (-1, -1, 12, 23) != 12)
+    return 1;
+  if (addilt (-1, 3, 12, 23) != 35)
+    return 1;
+  if (addilt (1, 3, 12, 23) != 35)
+    return 1;
+  if (addilt (3, 3, 12, 23) != 12)
+    return 1;
+  if (addilt (5, 3, 12, 23) != 12)
+    return 1;
+  if (addilt (3, -1, 12, 23) != 12)
+    return 1;
+  if (addilt (3, 1, 12, 23) != 12)
+    return 1;
+  if (addilt (3, 5, 12, 23) != 35)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addiltu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addiltu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned int int_t;
+
+__attribute__ ((noinline)) int_t
+addiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addiltu (-1, -1, 12, 23) != 12)
+    return 1;
+  if (addiltu (-1, 3, 12, 23) != 12)
+    return 1;
+  if (addiltu (1, 3, 12, 23) != 35)
+    return 1;
+  if (addiltu (3, 3, 12, 23) != 12)
+    return 1;
+  if (addiltu (5, 3, 12, 23) != 12)
+    return 1;
+  if (addiltu (3, -1, 12, 23) != 35)
+    return 1;
+  if (addiltu (3, 1, 12, 23) != 12)
+    return 1;
+  if (addiltu (3, 5, 12, 23) != 35)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addine.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addine.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+addine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addine (-1, -1, 12, 23) != 12)
+    return 1;
+  if (addine (-1, 3, 12, 23) != 35)
+    return 1;
+  if (addine (1, 3, 12, 23) != 35)
+    return 1;
+  if (addine (3, 3, 12, 23) != 12)
+    return 1;
+  if (addine (5, 3, 12, 23) != 35)
+    return 1;
+  if (addine (3, -1, 12, 23) != 35)
+    return 1;
+  if (addine (3, 1, 12, 23) != 35)
+    return 1;
+  if (addine (3, 5, 12, 23) != 35)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addleq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addleq.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addleq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addleq (-1L, -1L, 12L, 23L) != 35L)
+    return 1;
+  if (addleq (-1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addleq (1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addleq (3L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addleq (5L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addleq (3L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (addleq (3L, 1L, 12L, 23L) != 12L)
+    return 1;
+  if (addleq (3L, 5L, 12L, 23L) != 12L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addlfeq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addlfeq.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlfeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addlfeq (-1.0, -1.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfeq (-1.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlfeq (1.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlfeq (3.0, 3.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfeq (5.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlfeq (3.0, -1.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlfeq (3.0, 1.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlfeq (3.0, 5.0, 12L, 23L) != 12L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addlfge.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addlfge.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlfge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addlfge (-1.0, -1.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfge (-1.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlfge (1.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlfge (3.0, 3.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfge (5.0, 3.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfge (3.0, -1.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfge (3.0, 1.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfge (3.0, 5.0, 12L, 23L) != 12L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addlfgt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addlfgt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlfgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addlfgt (-1.0, -1.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlfgt (-1.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlfgt (1.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlfgt (3.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlfgt (5.0, 3.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfgt (3.0, -1.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfgt (3.0, 1.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfgt (3.0, 5.0, 12L, 23L) != 12L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addlfle.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addlfle.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlfle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addlfle (-1.0, -1.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfle (-1.0, 3.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfle (1.0, 3.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfle (3.0, 3.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfle (5.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlfle (3.0, -1.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlfle (3.0, 1.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlfle (3.0, 5.0, 12L, 23L) != 35L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addlflt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addlflt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addlflt (-1.0, -1.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlflt (-1.0, 3.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlflt (1.0, 3.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlflt (3.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlflt (5.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlflt (3.0, -1.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlflt (3.0, 1.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlflt (3.0, 5.0, 12L, 23L) != 35L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addlfne.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addlfne.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlfne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addlfne (-1.0, -1.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlfne (-1.0, 3.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfne (1.0, 3.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfne (3.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (addlfne (5.0, 3.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfne (3.0, -1.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfne (3.0, 1.0, 12L, 23L) != 35L)
+    return 1;
+  if (addlfne (3.0, 5.0, 12L, 23L) != 35L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addlge.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addlge.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlge (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addlge (-1L, -1L, 12L, 23L) != 35L)
+    return 1;
+  if (addlge (-1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addlge (1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addlge (3L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addlge (5L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addlge (3L, -1L, 12L, 23L) != 35L)
+    return 1;
+  if (addlge (3L, 1L, 12L, 23L) != 35L)
+    return 1;
+  if (addlge (3L, 5L, 12L, 23L) != 12L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addlgeu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addlgeu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned long int_t;
+
+__attribute__ ((noinline)) int_t
+addlgeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addlgeu (-1L, -1L, 12L, 23L) != 35L)
+    return 1;
+  if (addlgeu (-1L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addlgeu (1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addlgeu (3L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addlgeu (5L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addlgeu (3L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (addlgeu (3L, 1L, 12L, 23L) != 35L)
+    return 1;
+  if (addlgeu (3L, 5L, 12L, 23L) != 12L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addlgt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addlgt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlgt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addlgt (-1L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (addlgt (-1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addlgt (1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addlgt (3L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addlgt (5L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addlgt (3L, -1L, 12L, 23L) != 35L)
+    return 1;
+  if (addlgt (3L, 1L, 12L, 23L) != 35L)
+    return 1;
+  if (addlgt (3L, 5L, 12L, 23L) != 12L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addlgtu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addlgtu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned long int_t;
+
+__attribute__ ((noinline)) int_t
+addlgtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addlgtu (-1L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (addlgtu (-1L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addlgtu (1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addlgtu (3L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addlgtu (5L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addlgtu (3L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (addlgtu (3L, 1L, 12L, 23L) != 35L)
+    return 1;
+  if (addlgtu (3L, 5L, 12L, 23L) != 12L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addlle.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addlle.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlle (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addlle (-1L, -1L, 12L, 23L) != 35L)
+    return 1;
+  if (addlle (-1L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addlle (1L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addlle (3L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addlle (5L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addlle (3L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (addlle (3L, 1L, 12L, 23L) != 12L)
+    return 1;
+  if (addlle (3L, 5L, 12L, 23L) != 35L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addlleu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addlleu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned long int_t;
+
+__attribute__ ((noinline)) int_t
+addlleu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addlleu (-1L, -1L, 12L, 23L) != 35L)
+    return 1;
+  if (addlleu (-1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addlleu (1L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addlleu (3L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addlleu (5L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addlleu (3L, -1L, 12L, 23L) != 35L)
+    return 1;
+  if (addlleu (3L, 1L, 12L, 23L) != 12L)
+    return 1;
+  if (addlleu (3L, 5L, 12L, 23L) != 35L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addllt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addllt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addllt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addllt (-1L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (addllt (-1L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addllt (1L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addllt (3L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addllt (5L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addllt (3L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (addllt (3L, 1L, 12L, 23L) != 12L)
+    return 1;
+  if (addllt (3L, 5L, 12L, 23L) != 35L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addlltu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addlltu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned long int_t;
+
+__attribute__ ((noinline)) int_t
+addlltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addlltu (-1L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (addlltu (-1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addlltu (1L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addlltu (3L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addlltu (5L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addlltu (3L, -1L, 12L, 23L) != 35L)
+    return 1;
+  if (addlltu (3L, 1L, 12L, 23L) != 12L)
+    return 1;
+  if (addlltu (3L, 5L, 12L, 23L) != 35L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/addlne.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/addlne.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+addlne (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y + z : y;
+}
+
+int
+main (void)
+{
+  if (addlne (-1L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (addlne (-1L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addlne (1L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addlne (3L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (addlne (5L, 3L, 12L, 23L) != 35L)
+    return 1;
+  if (addlne (3L, -1L, 12L, 23L) != 35L)
+    return 1;
+  if (addlne (3L, 1L, 12L, 23L) != 35L)
+    return 1;
+  if (addlne (3L, 5L, 12L, 23L) != 35L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movieq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movieq.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movieq (-1, -1, 12, 23) != 12)
+    return 1;
+  if (movieq (-1, 3, 12, 23) != 23)
+    return 1;
+  if (movieq (1, 3, 12, 23) != 23)
+    return 1;
+  if (movieq (3, 3, 12, 23) != 12)
+    return 1;
+  if (movieq (5, 3, 12, 23) != 23)
+    return 1;
+  if (movieq (3, -1, 12, 23) != 23)
+    return 1;
+  if (movieq (3, 1, 12, 23) != 23)
+    return 1;
+  if (movieq (3, 5, 12, 23) != 23)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movifeq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movifeq.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movifeq (-1.0, -1.0, 12, 23) != 12)
+    return 1;
+  if (movifeq (-1.0, 3.0, 12, 23) != 23)
+    return 1;
+  if (movifeq (1.0, 3.0, 12, 23) != 23)
+    return 1;
+  if (movifeq (3.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (movifeq (5.0, 3.0, 12, 23) != 23)
+    return 1;
+  if (movifeq (3.0, -1.0, 12, 23) != 23)
+    return 1;
+  if (movifeq (3.0, 1.0, 12, 23) != 23)
+    return 1;
+  if (movifeq (3.0, 5.0, 12, 23) != 23)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movifge.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movifge.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movifge (-1.0, -1.0, 12, 23) != 12)
+    return 1;
+  if (movifge (-1.0, 3.0, 12, 23) != 23)
+    return 1;
+  if (movifge (1.0, 3.0, 12, 23) != 23)
+    return 1;
+  if (movifge (3.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (movifge (5.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (movifge (3.0, -1.0, 12, 23) != 12)
+    return 1;
+  if (movifge (3.0, 1.0, 12, 23) != 12)
+    return 1;
+  if (movifge (3.0, 5.0, 12, 23) != 23)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movifgt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movifgt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movifgt (-1.0, -1.0, 12, 23) != 23)
+    return 1;
+  if (movifgt (-1.0, 3.0, 12, 23) != 23)
+    return 1;
+  if (movifgt (1.0, 3.0, 12, 23) != 23)
+    return 1;
+  if (movifgt (3.0, 3.0, 12, 23) != 23)
+    return 1;
+  if (movifgt (5.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (movifgt (3.0, -1.0, 12, 23) != 12)
+    return 1;
+  if (movifgt (3.0, 1.0, 12, 23) != 12)
+    return 1;
+  if (movifgt (3.0, 5.0, 12, 23) != 23)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movifle.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movifle.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movifle (-1.0, -1.0, 12, 23) != 12)
+    return 1;
+  if (movifle (-1.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (movifle (1.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (movifle (3.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (movifle (5.0, 3.0, 12, 23) != 23)
+    return 1;
+  if (movifle (3.0, -1.0, 12, 23) != 23)
+    return 1;
+  if (movifle (3.0, 1.0, 12, 23) != 23)
+    return 1;
+  if (movifle (3.0, 5.0, 12, 23) != 12)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/moviflt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/moviflt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+moviflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+int
+main (void)
+{
+  if (moviflt (-1.0, -1.0, 12, 23) != 23)
+    return 1;
+  if (moviflt (-1.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (moviflt (1.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (moviflt (3.0, 3.0, 12, 23) != 23)
+    return 1;
+  if (moviflt (5.0, 3.0, 12, 23) != 23)
+    return 1;
+  if (moviflt (3.0, -1.0, 12, 23) != 23)
+    return 1;
+  if (moviflt (3.0, 1.0, 12, 23) != 23)
+    return 1;
+  if (moviflt (3.0, 5.0, 12, 23) != 12)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movifne.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movifne.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movifne (-1.0, -1.0, 12, 23) != 23)
+    return 1;
+  if (movifne (-1.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (movifne (1.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (movifne (3.0, 3.0, 12, 23) != 23)
+    return 1;
+  if (movifne (5.0, 3.0, 12, 23) != 12)
+    return 1;
+  if (movifne (3.0, -1.0, 12, 23) != 12)
+    return 1;
+  if (movifne (3.0, 1.0, 12, 23) != 12)
+    return 1;
+  if (movifne (3.0, 5.0, 12, 23) != 12)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movige.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movige.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movige (-1, -1, 12, 23) != 12)
+    return 1;
+  if (movige (-1, 3, 12, 23) != 23)
+    return 1;
+  if (movige (1, 3, 12, 23) != 23)
+    return 1;
+  if (movige (3, 3, 12, 23) != 12)
+    return 1;
+  if (movige (5, 3, 12, 23) != 12)
+    return 1;
+  if (movige (3, -1, 12, 23) != 12)
+    return 1;
+  if (movige (3, 1, 12, 23) != 12)
+    return 1;
+  if (movige (3, 5, 12, 23) != 23)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movigeu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movigeu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned int int_t;
+
+__attribute__ ((noinline)) int_t
+movigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movigeu (-1, -1, 12, 23) != 12)
+    return 1;
+  if (movigeu (-1, 3, 12, 23) != 12)
+    return 1;
+  if (movigeu (1, 3, 12, 23) != 23)
+    return 1;
+  if (movigeu (3, 3, 12, 23) != 12)
+    return 1;
+  if (movigeu (5, 3, 12, 23) != 12)
+    return 1;
+  if (movigeu (3, -1, 12, 23) != 23)
+    return 1;
+  if (movigeu (3, 1, 12, 23) != 12)
+    return 1;
+  if (movigeu (3, 5, 12, 23) != 23)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movigt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movigt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movigt (-1, -1, 12, 23) != 23)
+    return 1;
+  if (movigt (-1, 3, 12, 23) != 23)
+    return 1;
+  if (movigt (1, 3, 12, 23) != 23)
+    return 1;
+  if (movigt (3, 3, 12, 23) != 23)
+    return 1;
+  if (movigt (5, 3, 12, 23) != 12)
+    return 1;
+  if (movigt (3, -1, 12, 23) != 12)
+    return 1;
+  if (movigt (3, 1, 12, 23) != 12)
+    return 1;
+  if (movigt (3, 5, 12, 23) != 23)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movigtu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movigtu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned int int_t;
+
+__attribute__ ((noinline)) int_t
+movigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movigtu (-1, -1, 12, 23) != 23)
+    return 1;
+  if (movigtu (-1, 3, 12, 23) != 12)
+    return 1;
+  if (movigtu (1, 3, 12, 23) != 23)
+    return 1;
+  if (movigtu (3, 3, 12, 23) != 23)
+    return 1;
+  if (movigtu (5, 3, 12, 23) != 12)
+    return 1;
+  if (movigtu (3, -1, 12, 23) != 23)
+    return 1;
+  if (movigtu (3, 1, 12, 23) != 12)
+    return 1;
+  if (movigtu (3, 5, 12, 23) != 23)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movile.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movile.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movile (-1, -1, 12, 23) != 12)
+    return 1;
+  if (movile (-1, 3, 12, 23) != 12)
+    return 1;
+  if (movile (1, 3, 12, 23) != 12)
+    return 1;
+  if (movile (3, 3, 12, 23) != 12)
+    return 1;
+  if (movile (5, 3, 12, 23) != 23)
+    return 1;
+  if (movile (3, -1, 12, 23) != 23)
+    return 1;
+  if (movile (3, 1, 12, 23) != 23)
+    return 1;
+  if (movile (3, 5, 12, 23) != 12)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movileu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movileu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned int int_t;
+
+__attribute__ ((noinline)) int_t
+movileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movileu (-1, -1, 12, 23) != 12)
+    return 1;
+  if (movileu (-1, 3, 12, 23) != 23)
+    return 1;
+  if (movileu (1, 3, 12, 23) != 12)
+    return 1;
+  if (movileu (3, 3, 12, 23) != 12)
+    return 1;
+  if (movileu (5, 3, 12, 23) != 23)
+    return 1;
+  if (movileu (3, -1, 12, 23) != 12)
+    return 1;
+  if (movileu (3, 1, 12, 23) != 23)
+    return 1;
+  if (movileu (3, 5, 12, 23) != 12)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movilt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movilt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movilt (-1, -1, 12, 23) != 23)
+    return 1;
+  if (movilt (-1, 3, 12, 23) != 12)
+    return 1;
+  if (movilt (1, 3, 12, 23) != 12)
+    return 1;
+  if (movilt (3, 3, 12, 23) != 23)
+    return 1;
+  if (movilt (5, 3, 12, 23) != 23)
+    return 1;
+  if (movilt (3, -1, 12, 23) != 23)
+    return 1;
+  if (movilt (3, 1, 12, 23) != 23)
+    return 1;
+  if (movilt (3, 5, 12, 23) != 12)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/moviltu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/moviltu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned int int_t;
+
+__attribute__ ((noinline)) int_t
+moviltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+int
+main (void)
+{
+  if (moviltu (-1, -1, 12, 23) != 23)
+    return 1;
+  if (moviltu (-1, 3, 12, 23) != 23)
+    return 1;
+  if (moviltu (1, 3, 12, 23) != 12)
+    return 1;
+  if (moviltu (3, 3, 12, 23) != 23)
+    return 1;
+  if (moviltu (5, 3, 12, 23) != 23)
+    return 1;
+  if (moviltu (3, -1, 12, 23) != 12)
+    return 1;
+  if (moviltu (3, 1, 12, 23) != 23)
+    return 1;
+  if (moviltu (3, 5, 12, 23) != 12)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movine.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movine.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef int int_t;
+
+__attribute__ ((noinline)) int_t
+movine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movine (-1, -1, 12, 23) != 23)
+    return 1;
+  if (movine (-1, 3, 12, 23) != 12)
+    return 1;
+  if (movine (1, 3, 12, 23) != 12)
+    return 1;
+  if (movine (3, 3, 12, 23) != 23)
+    return 1;
+  if (movine (5, 3, 12, 23) != 12)
+    return 1;
+  if (movine (3, -1, 12, 23) != 12)
+    return 1;
+  if (movine (3, 1, 12, 23) != 12)
+    return 1;
+  if (movine (3, 5, 12, 23) != 12)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movleq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movleq.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movleq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movleq (-1L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (movleq (-1L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movleq (1L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movleq (3L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movleq (5L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movleq (3L, -1L, 12L, 23L) != 23L)
+    return 1;
+  if (movleq (3L, 1L, 12L, 23L) != 23L)
+    return 1;
+  if (movleq (3L, 5L, 12L, 23L) != 23L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movlfeq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movlfeq.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlfeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movlfeq (-1.0, -1.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfeq (-1.0, 3.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlfeq (1.0, 3.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlfeq (3.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfeq (5.0, 3.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlfeq (3.0, -1.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlfeq (3.0, 1.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlfeq (3.0, 5.0, 12L, 23L) != 23L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movlfge.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movlfge.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlfge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movlfge (-1.0, -1.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfge (-1.0, 3.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlfge (1.0, 3.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlfge (3.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfge (5.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfge (3.0, -1.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfge (3.0, 1.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfge (3.0, 5.0, 12L, 23L) != 23L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movlfgt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movlfgt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlfgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movlfgt (-1.0, -1.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlfgt (-1.0, 3.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlfgt (1.0, 3.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlfgt (3.0, 3.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlfgt (5.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfgt (3.0, -1.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfgt (3.0, 1.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfgt (3.0, 5.0, 12L, 23L) != 23L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movlfle.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movlfle.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlfle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movlfle (-1.0, -1.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfle (-1.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfle (1.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfle (3.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfle (5.0, 3.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlfle (3.0, -1.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlfle (3.0, 1.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlfle (3.0, 5.0, 12L, 23L) != 12L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movlflt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movlflt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movlflt (-1.0, -1.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlflt (-1.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlflt (1.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlflt (3.0, 3.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlflt (5.0, 3.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlflt (3.0, -1.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlflt (3.0, 1.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlflt (3.0, 5.0, 12L, 23L) != 12L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movlfne.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movlfne.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlfne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movlfne (-1.0, -1.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlfne (-1.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfne (1.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfne (3.0, 3.0, 12L, 23L) != 23L)
+    return 1;
+  if (movlfne (5.0, 3.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfne (3.0, -1.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfne (3.0, 1.0, 12L, 23L) != 12L)
+    return 1;
+  if (movlfne (3.0, 5.0, 12L, 23L) != 12L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movlge.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movlge.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlge (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movlge (-1L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (movlge (-1L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movlge (1L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movlge (3L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movlge (5L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movlge (3L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (movlge (3L, 1L, 12L, 23L) != 12L)
+    return 1;
+  if (movlge (3L, 5L, 12L, 23L) != 23L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movlgeu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movlgeu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned long int_t;
+
+__attribute__ ((noinline)) int_t
+movlgeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movlgeu (-1L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (movlgeu (-1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movlgeu (1L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movlgeu (3L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movlgeu (5L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movlgeu (3L, -1L, 12L, 23L) != 23L)
+    return 1;
+  if (movlgeu (3L, 1L, 12L, 23L) != 12L)
+    return 1;
+  if (movlgeu (3L, 5L, 12L, 23L) != 23L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movlgt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movlgt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlgt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movlgt (-1L, -1L, 12L, 23L) != 23L)
+    return 1;
+  if (movlgt (-1L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movlgt (1L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movlgt (3L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movlgt (5L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movlgt (3L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (movlgt (3L, 1L, 12L, 23L) != 12L)
+    return 1;
+  if (movlgt (3L, 5L, 12L, 23L) != 23L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movlgtu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movlgtu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned long int_t;
+
+__attribute__ ((noinline)) int_t
+movlgtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movlgtu (-1L, -1L, 12L, 23L) != 23L)
+    return 1;
+  if (movlgtu (-1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movlgtu (1L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movlgtu (3L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movlgtu (5L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movlgtu (3L, -1L, 12L, 23L) != 23L)
+    return 1;
+  if (movlgtu (3L, 1L, 12L, 23L) != 12L)
+    return 1;
+  if (movlgtu (3L, 5L, 12L, 23L) != 23L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movlle.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movlle.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlle (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movlle (-1L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (movlle (-1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movlle (1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movlle (3L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movlle (5L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movlle (3L, -1L, 12L, 23L) != 23L)
+    return 1;
+  if (movlle (3L, 1L, 12L, 23L) != 23L)
+    return 1;
+  if (movlle (3L, 5L, 12L, 23L) != 12L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movlleu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movlleu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned long int_t;
+
+__attribute__ ((noinline)) int_t
+movlleu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movlleu (-1L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (movlleu (-1L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movlleu (1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movlleu (3L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movlleu (5L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movlleu (3L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (movlleu (3L, 1L, 12L, 23L) != 23L)
+    return 1;
+  if (movlleu (3L, 5L, 12L, 23L) != 12L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movllt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movllt.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movllt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movllt (-1L, -1L, 12L, 23L) != 23L)
+    return 1;
+  if (movllt (-1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movllt (1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movllt (3L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movllt (5L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movllt (3L, -1L, 12L, 23L) != 23L)
+    return 1;
+  if (movllt (3L, 1L, 12L, 23L) != 23L)
+    return 1;
+  if (movllt (3L, 5L, 12L, 23L) != 12L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movlltu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movlltu.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef unsigned long int_t;
+
+__attribute__ ((noinline)) int_t
+movlltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movlltu (-1L, -1L, 12L, 23L) != 23L)
+    return 1;
+  if (movlltu (-1L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movlltu (1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movlltu (3L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movlltu (5L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movlltu (3L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (movlltu (3L, 1L, 12L, 23L) != 23L)
+    return 1;
+  if (movlltu (3L, 5L, 12L, 23L) != 12L)
+    return 1;
+  return 0;
+}
Index: gcc/gcc/testsuite/gcc.dg/torture/movlne.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/torture/movlne.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+typedef long int_t;
+
+__attribute__ ((noinline)) int_t
+movlne (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+int
+main (void)
+{
+  if (movlne (-1L, -1L, 12L, 23L) != 23L)
+    return 1;
+  if (movlne (-1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movlne (1L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movlne (3L, 3L, 12L, 23L) != 23L)
+    return 1;
+  if (movlne (5L, 3L, 12L, 23L) != 12L)
+    return 1;
+  if (movlne (3L, -1L, 12L, 23L) != 12L)
+    return 1;
+  if (movlne (3L, 1L, 12L, 23L) != 12L)
+    return 1;
+  if (movlne (3L, 5L, 12L, 23L) != 12L)
+    return 1;
+  return 0;
+}

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 02/44] RISC-V/testsuite: Add cases for integer SFB cond-move operations
  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-19  5:35 ` [PATCH 01/44] testsuite: Add cases for conditional-move and conditional-add operations Maciej W. Rozycki
@ 2023-11-19  5:35 ` 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
                   ` (41 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:35 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for short forward branch targets and the conditional-move 
operations that already work as expected, that if-conversion triggers 
via `noce_try_cmove' already at `-mbranch-cost=1' and that extraneous 
instructions such as SNEZ, etc. are not present in output.  Cover all 
integer relational operations to make sure no corner case escapes.

	gcc/testsuite/
	* gcc.target/riscv/movdieq-sfb.c: New test.
	* gcc.target/riscv/movdige-sfb.c: New test.
	* gcc.target/riscv/movdigeu-sfb.c: New test.
	* gcc.target/riscv/movdigt-sfb.c: New test.
	* gcc.target/riscv/movdigtu-sfb.c: New test.
	* gcc.target/riscv/movdile-sfb.c: New test.
	* gcc.target/riscv/movdileu-sfb.c: New test.
	* gcc.target/riscv/movdilt-sfb.c: New test.
	* gcc.target/riscv/movdiltu-sfb.c: New test.
	* gcc.target/riscv/movdine-sfb.c: New test.
	* gcc.target/riscv/movsieq-sfb.c: New test.
	* gcc.target/riscv/movsige-sfb.c: New test.
	* gcc.target/riscv/movsigeu-sfb.c: New test.
	* gcc.target/riscv/movsigt-sfb.c: New test.
	* gcc.target/riscv/movsigtu-sfb.c: New test.
	* gcc.target/riscv/movsile-sfb.c: New test.
	* gcc.target/riscv/movsileu-sfb.c: New test.
	* gcc.target/riscv/movsilt-sfb.c: New test.
	* gcc.target/riscv/movsiltu-sfb.c: New test.
	* gcc.target/riscv/movsine-sfb.c: New test.
---
 gcc/testsuite/gcc.target/riscv/movdieq-sfb.c  |   25 +++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdige-sfb.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdigeu-sfb.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdigt-sfb.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdigtu-sfb.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdile-sfb.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdileu-sfb.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdilt-sfb.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdiltu-sfb.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdine-sfb.c  |   25 +++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsieq-sfb.c  |   25 +++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsige-sfb.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsigeu-sfb.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsigt-sfb.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsigtu-sfb.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsile-sfb.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsileu-sfb.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsilt-sfb.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsiltu-sfb.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsine-sfb.c  |   25 +++++++++++++++++++++++++
 20 files changed, 516 insertions(+)

gcc-riscv-test-movcc.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/movdieq-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdieq-sfb.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	bne	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdige-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdige-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	blt	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdigeu-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdigeu-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	bltu	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdigt-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdigt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	ble	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdigtu-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdigtu-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	bleu	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdile-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdile-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	bgt	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|bgt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdileu-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdileu-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	bgtu	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdilt-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdilt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	bge	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiltu-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiltu-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	bgeu	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdine-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdine-sfb.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	beq	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsieq-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsieq-sfb.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	bne	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsige-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsige-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	blt	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsigeu-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsigeu-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	bltu	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsigt-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsigt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	ble	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgt|ble)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsigtu-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsigtu-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	bleu	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsile-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsile-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	bgt	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsileu-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsileu-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	bgtu	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsilt-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsilt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	bge	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiltu-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiltu-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	bgeu	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsine-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsine-sfb.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	beq	a0,a1,1f	# movcc
+	mv	a3,a2
+1:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 03/44] RISC-V: Reorder comment on SFB patterns
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (2 preceding siblings ...)
  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:35 ` 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
                   ` (40 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:35 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Our `mov<mode>cc' expander is no longer specific to short forward branch 
targets, so move its associated comment accordingly.

	gcc/
	* config/riscv/riscv.md (mov<mode>cc): Move comment on SFB 
	patterns over to...
	(*mov<GPR:mode><X:mode>cc): ... here.
---
 gcc/config/riscv/riscv.md |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

gcc-riscv-sfb-comment-move.diff
Index: gcc-master/gcc/config/riscv/riscv.md
===================================================================
--- gcc-master.orig/gcc/config/riscv/riscv.md
+++ gcc-master/gcc/config/riscv/riscv.md
@@ -2655,8 +2655,6 @@
   [(set_attr "type" "branch")
    (set_attr "mode" "none")])
 
-;; Patterns for implementations that optimize short forward branches.
-
 (define_expand "mov<mode>cc"
   [(set (match_operand:GPR 0 "register_operand")
 	(if_then_else:GPR (match_operand 1 "comparison_operator")
@@ -2671,6 +2669,8 @@
     FAIL;
 })
 
+;; Patterns for implementations that optimize short forward branches.
+
 (define_insn "*mov<GPR:mode><X:mode>cc"
   [(set (match_operand:GPR 0 "register_operand" "=r,r")
 	(if_then_else:GPR

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 04/44] RISC-V: Sanitise NEED_EQ_NE_P case with `riscv_emit_int_compare'
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (3 preceding siblings ...)
  2023-11-19  5:35 ` [PATCH 03/44] RISC-V: Reorder comment on SFB patterns Maciej W. Rozycki
@ 2023-11-19  5:36 ` 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
                   ` (39 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

For the NEED_EQ_NE_P `riscv_emit_int_compare' is documented to only emit 
EQ or NE comparisons against zero, however it does not catch incorrect 
use where a non-equality comparison has been requested and falls through 
to the general case then.  Add a safety guard to catch such a case then.

Arguably the NEED_EQ_NE_P case would best be moved into a function of 
its own, but let's leave it for a separate cleanup.

	gcc/
	* config/riscv/riscv.cc (riscv_emit_int_compare): Bail out if
	NEED_EQ_NE_P but the comparison is neither EQ nor NE.	
---
FWIW the structure of code here clearly shows the NEED_EQ_NE_P case has 
been bolted on as an afterthought rather than how this piece would look 
if written from scratch right away.  Let's defer any further cleanups at 
this stage of the development cycle though.
---
 gcc/config/riscv/riscv.cc |    1 +
 1 file changed, 1 insertion(+)

gcc-riscv-emit-int-compare-need-eq-ne.diff
Index: gcc/gcc/config/riscv/riscv.cc
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.cc
+++ gcc/gcc/config/riscv/riscv.cc
@@ -3779,6 +3779,7 @@ riscv_emit_int_compare (enum rtx_code *c
 	  *op1 = const0_rtx;
 	  return;
 	}
+      gcc_unreachable ();
     }
 
   if (splittable_const_int_operand (*op1, VOIDmode))

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 05/44] RISC-V: Fix `mode' usage in `riscv_expand_conditional_move'
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (4 preceding siblings ...)
  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:36 ` 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
                   ` (38 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

In `riscv_expand_conditional_move' `mode' is initialized right away from 
`GET_MODE (dest)', so remove needless references that refrain from using 
the local variable.

	gcc/
	* config/riscv/riscv.cc (riscv_expand_conditional_move): Use 
	`mode' for `GET_MODE (dest)' throughout.
---
 gcc/config/riscv/riscv.cc |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

gcc-riscv-expand-conditional-move-mode-dest.diff
Index: gcc/gcc/config/riscv/riscv.cc
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.cc
+++ gcc/gcc/config/riscv/riscv.cc
@@ -3999,8 +3999,8 @@ riscv_expand_conditional_move (rtx dest,
 	 arm of the conditional move.  That allows us to support more
 	 cases for extensions which are more general than SFB.  But
 	 does mean we need to force CONS into a register at this point.  */
-      cons = force_reg (GET_MODE (dest), cons);
-      emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (GET_MODE (dest),
+      cons = force_reg (mode, cons);
+      emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (mode,
 							  cond, cons, alt)));
       return true;
     }

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 06/44] RISC-V: Avoid repeated GET_MODE calls in `riscv_expand_conditional_move'
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (5 preceding siblings ...)
  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:36 ` 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
                   ` (37 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Use `mode0' and `mode1' shorthands respectively for `GET_MODE (op0)' and 
`GET_MODE (op1)' to improve code readability.

	gcc/
	* config/riscv/riscv.cc (riscv_expand_conditional_move): Use 
	`mode0' and `mode1' for `GET_MODE (op0)' and `GET_MODE (op1)'.
---
 gcc/config/riscv/riscv.cc |   11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

gcc-riscv-expand-conditional-move-mode-cmp.diff
Index: gcc/gcc/config/riscv/riscv.cc
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.cc
+++ gcc/gcc/config/riscv/riscv.cc
@@ -4007,12 +4007,15 @@ riscv_expand_conditional_move (rtx dest,
   else if (TARGET_ZICOND_LIKE
 	   && GET_MODE_CLASS (mode) == MODE_INT)
     {
+      machine_mode mode0 = GET_MODE (op0);
+      machine_mode mode1 = GET_MODE (op1);
+
       /* The comparison must be comparing WORD_MODE objects.   We must
 	 enforce that so that we don't strip away a sign_extension
 	 thinking it is unnecessary.  We might consider using
 	 riscv_extend_operands if they are not already properly extended.  */
-      if ((GET_MODE (op0) != word_mode && GET_MODE (op0) != VOIDmode)
-	  || (GET_MODE (op1) != word_mode && GET_MODE (op1) != VOIDmode))
+      if ((mode0 != word_mode && mode0 != VOIDmode)
+	  || (mode1 != word_mode && mode1 != VOIDmode))
 	return false;
 
       /* Canonicalize the comparison.  It must be an equality comparison
@@ -4032,9 +4035,9 @@ riscv_expand_conditional_move (rtx dest,
 	  rtx tmp = gen_reg_rtx (word_mode);
 
 	  /* We can support both FP and integer conditional moves.  */
-	  if (INTEGRAL_MODE_P (GET_MODE (XEXP (op, 0))))
+	  if (INTEGRAL_MODE_P (mode0))
 	    riscv_expand_int_scc (tmp, code, op0, op1, invert_ptr);
-	  else if (FLOAT_MODE_P (GET_MODE (XEXP (op, 0)))
+	  else if (FLOAT_MODE_P (mode0)
 		   && fp_scc_comparison (op, GET_MODE (op)))
 	    riscv_expand_float_scc (tmp, code, op0, op1);
 	  else

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 07/44] RISC-V: Use `nullptr' in `riscv_expand_conditional_move'
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (6 preceding siblings ...)
  2023-11-19  5:36 ` [PATCH 06/44] RISC-V: Avoid repeated GET_MODE calls " Maciej W. Rozycki
@ 2023-11-19  5:36 ` 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
                   ` (36 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Use `nullptr' for consistency rather than 0 to initialize `invert_ptr'.

	gcc/
	* config/riscv/riscv.cc (riscv_expand_conditional_move): Use 
	`nullptr' rather than 0 to initialize a pointer.
---
 gcc/config/riscv/riscv.cc |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

gcc-riscv-expand-conditional-move-nullptr.diff
Index: gcc/gcc/config/riscv/riscv.cc
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.cc
+++ gcc/gcc/config/riscv/riscv.cc
@@ -4024,7 +4024,7 @@ riscv_expand_conditional_move (rtx dest,
       if (!equality_operator (op, VOIDmode) || op1 != CONST0_RTX (mode))
 	{
 	  enum rtx_code new_code = NE;
-	  bool *invert_ptr = 0;
+	  bool *invert_ptr = nullptr;
 	  bool invert = false;
 
 	  if (code == LE || code == GE)

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 08/44] RISC-V: Simplify EQ vs NE selection in `riscv_expand_conditional_move'
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (7 preceding siblings ...)
  2023-11-19  5:36 ` [PATCH 07/44] RISC-V: Use `nullptr' " Maciej W. Rozycki
@ 2023-11-19  5:36 ` 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
                   ` (35 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Just choose between EQ and NE at `gen_rtx_fmt_ee' invocation, removing 
an extraneous variable only referred once and improving code clarity.

	gcc/
	* config/riscv/riscv.cc (riscv_expand_conditional_move): Remove 
	extraneous variable for EQ vs NE operation selection.
---
FWIW I have no idea what "We need to know where so that we can adjust it 
for our needs." refers to, but that would have to be for another change.
---
 gcc/config/riscv/riscv.cc |   12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

gcc-riscv-expand-conditional-move-new-code.diff
Index: gcc/gcc/config/riscv/riscv.cc
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.cc
+++ gcc/gcc/config/riscv/riscv.cc
@@ -4023,10 +4023,12 @@ riscv_expand_conditional_move (rtx dest,
 	 we can then use an equality comparison against zero.  */
       if (!equality_operator (op, VOIDmode) || op1 != CONST0_RTX (mode))
 	{
-	  enum rtx_code new_code = NE;
 	  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
+	     we can adjust it for our needs.  */
 	  if (code == LE || code == GE)
 	    invert_ptr = &invert;
 
@@ -4043,13 +4045,7 @@ riscv_expand_conditional_move (rtx dest,
 	  else
 	    return false;
 
-	  /* If riscv_expand_int_scc inverts the condition, then it will
-	     flip the value of INVERT.  We need to know where so that
-	     we can adjust it for our needs.  */
-	  if (invert)
-	    new_code = EQ;
-
-	  op = gen_rtx_fmt_ee (new_code, mode, tmp, const0_rtx);
+	  op = gen_rtx_fmt_ee (invert ? EQ : NE, mode, tmp, const0_rtx);
 
 	  /* We've generated a new comparison.  Update the local variables.  */
 	  code = GET_CODE (op);

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 09/44] RISC-V: Rework branch costing model for if-conversion
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (8 preceding siblings ...)
  2023-11-19  5:36 ` [PATCH 08/44] RISC-V: Simplify EQ vs NE selection " Maciej W. Rozycki
@ 2023-11-19  5:36 ` Maciej W. Rozycki
  2023-11-19 18:52   ` Jeff Law
  2023-11-19  5:37 ` [PATCH 10/44] RISC-V/testsuite: Add branched cases for integer cond-move operations Maciej W. Rozycki
                   ` (34 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

The generic branch costing model for if-conversion assumes a fixed cost 
of COSTS_N_INSNS (2) for a conditional branch, and that one half of that 
cost comes from a preceding condition-set instruction, such as with 
MODE_CC targets, and then the other half of that cost is for the actual 
branch instruction.  This is hardcoded for `if_info.original_cost' in 
`noce_find_if_block' and regardless of the cost set for branches via 
BRANCH_COST.

Then `default_max_noce_ifcvt_seq_cost' instructs if-conversion to prefer 
a branchless sequence as costly as high as triple the BRANCH_COST value 
set.  This is apparently to make up for the inability to accurately 
guess the branch penalty.

Consequently for the BRANCH_COST of 3 we commonly set for tuning, 
if-conversion will consider branchless sequences costing 3 * 3 - 2 = 7 
instruction units more than a corresponding branch sequence.  For the 
BRANCH_COST of 4 such as with `sifive-7-series' tuning this is even 
worse, at 3 * 4 - 2 = 10.  Effectively it means a branchless sequence 
will always be chosen if available, even a very inefficient one.

Rework the branch costing model to better match our architecture, 
observing in particular that we have no preparatory instructions for 
branches so that the cost of a branch is naked BRANCH_COST plus any 
extra overhead the processing of a branch's source RTX might incur.

Provide TARGET_INSN_COST and TARGET_MAX_NOCE_IFCVT_SEQ_COST handlers 
than that return suitable cost based on BRANCH_COST.  The latter hook 
usually returns a value that is lower than the cost of the corresponding 
branched sequence.  This is because we don't really want to produce a 
branchless sequence that is more expensive than the original branched 
sequence.  If this turns out too conservative for some corner case, then 
this choice might be revisited.

Then we don't want to fiddle with `noce_find_if_block' without a lot of 
cross-target verification, so add TARGET_NOCE_CONVERSION_PROFITABLE_P 
defined such that it subtracts the fixed COSTS_N_INSNS (2) cost from the 
cost of the original branched sequence supplied and instead adds actual 
branch cost calculated from the conditional branch instruction used.  It 
is then further tweaked according to simple analysis of the replacement 
branchless sequence produced so as to cancel the cost of an extraneous 
zero extend operation produced by `noce_try_store_flag_mask' as observed 
with gcc/testsuite/gcc.target/riscv/pr105314.c.

Tweak the testsuite accordingly and set `-mbranch-cost=' explicitly for 
the relevant cases so that the expected if-conversion transformation is 
made regardless of the default BRANCH_COST value of tuning in effect.  
Some of these settings will be lowered later on as deficiencies in 
branchless sequence generation have been fixed that lower their cost 
calculated by if-conversion.

	gcc/
	* config/riscv/riscv.cc (riscv_insn_cost): New function.
	(riscv_max_noce_ifcvt_seq_cost): Likewise.
	(riscv_noce_conversion_profitable_p): Likewise.
	(TARGET_INSN_COST): New macro.
	(TARGET_MAX_NOCE_IFCVT_SEQ_COST): New macro.
	(TARGET_NOCE_CONVERSION_PROFITABLE_P: New macro.

	gcc/testsuite/
	* gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c: 
	Explicitly set the branch cost.
	* gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c: 
	Likewise.
	* gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c: 
	Likewise.
	* gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c: 
	Likewise.
	* gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c: 
	Likewise.
	* gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c: 
	Likewise.
---
FWIW I don't understand why the test cases absolutely HAD to have such 
overlong names guaranteed to exceed our 80 column limit in any context.  
It's such a pain to handle.
---
 gcc/config/riscv/riscv.cc                                                             |  120 ++++++++++
 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c |    4 
 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c |    4 
 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c |    4 
 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c |    4 
 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c |    4 
 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c |    4 
 7 files changed, 132 insertions(+), 12 deletions(-)

gcc-riscv-branch-cost.diff
Index: gcc/gcc/config/riscv/riscv.cc
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.cc
+++ gcc/gcc/config/riscv/riscv.cc
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.
 #include "calls.h"
 #include "function.h"
 #include "explow.h"
+#include "ifcvt.h"
 #include "memmodel.h"
 #include "emit-rtl.h"
 #include "reload.h"
@@ -3295,6 +3296,118 @@ riscv_address_cost (rtx addr, machine_mo
   return riscv_address_insns (addr, mode, false);
 }
 
+/* Implement TARGET_INSN_COST.  We factor in the branch cost in the cost
+   calculation for conditional branches: one unit is considered the cost
+   of microarchitecture-dependent actual branch execution and therefore
+   multiplied by BRANCH_COST and any remaining units are considered fixed
+   branch overhead.  */
+
+static int
+riscv_insn_cost (rtx_insn *insn, bool speed)
+{
+  rtx x = PATTERN (insn);
+  int cost = pattern_cost (x, speed);
+
+  if (JUMP_P (insn)
+      && GET_CODE (x) == SET
+      && GET_CODE (SET_DEST (x)) == PC
+      && GET_CODE (SET_SRC (x)) == IF_THEN_ELSE)
+    cost += COSTS_N_INSNS (BRANCH_COST (speed, false) - 1);
+  return cost;
+}
+
+/* Implement TARGET_MAX_NOCE_IFCVT_SEQ_COST.  Like the default implementation,
+   but we consider cost units of branch instructions equal to cost units of
+   other instructions.  */
+
+static unsigned int
+riscv_max_noce_ifcvt_seq_cost (edge e)
+{
+  bool predictable_p = predictable_edge_p (e);
+
+  if (predictable_p)
+    {
+      if (OPTION_SET_P (param_max_rtl_if_conversion_predictable_cost))
+	return param_max_rtl_if_conversion_predictable_cost;
+    }
+  else
+    {
+      if (OPTION_SET_P (param_max_rtl_if_conversion_unpredictable_cost))
+	return param_max_rtl_if_conversion_unpredictable_cost;
+    }
+
+  return COSTS_N_INSNS (BRANCH_COST (true, predictable_p));
+}
+
+/* Implement TARGET_NOCE_CONVERSION_PROFITABLE_P.  We replace the cost of a
+   conditional branch assumed by `noce_find_if_block' at `COSTS_N_INSNS (2)'
+   by our actual conditional branch cost, observing that our branches test
+   conditions directly, so there is no preparatory extra condition-set
+   instruction.  */
+
+static bool
+riscv_noce_conversion_profitable_p (rtx_insn *seq,
+				    struct noce_if_info *if_info)
+{
+  struct noce_if_info riscv_if_info = *if_info;
+
+  riscv_if_info.original_cost -= COSTS_N_INSNS (2);
+  riscv_if_info.original_cost += insn_cost (if_info->jump, if_info->speed_p);
+
+  /* Hack alert!  When `noce_try_store_flag_mask' uses `cstore<mode>4'
+     to emit a conditional set operation on DImode output it comes up
+     with a sequence such as:
+
+     (insn 26 0 27 (set (reg:SI 140)
+             (eq:SI (reg/v:DI 137 [ c ])
+                 (const_int 0 [0]))) 302 {*seq_zero_disi}
+          (nil))
+     (insn 27 26 28 (set (reg:DI 139)
+             (zero_extend:DI (reg:SI 140))) 116 {*zero_extendsidi2_internal}
+          (nil))
+
+     because our `cstore<mode>4' pattern expands to an insn that gives
+     a SImode output.  The output of conditional set is 0 or 1 boolean,
+     so it is valid for input in any scalar integer mode and therefore
+     combine later folds the zero extend operation into an equivalent
+     conditional set operation that produces a DImode output, however
+     this redundant zero extend operation counts towards the cost of
+     the replacement sequence.  Compensate for that by incrementing the
+     cost of the original sequence as well as the maximum sequence cost
+     accordingly.  */
+  rtx last_dest = NULL_RTX;
+  for (rtx_insn *insn = seq; insn; insn = NEXT_INSN (insn))
+    {
+      if (!NONDEBUG_INSN_P (insn))
+	continue;
+
+      rtx x = PATTERN (insn);
+      if (NONJUMP_INSN_P (insn)
+	  && GET_CODE (x) == SET)
+	{
+	  rtx src = SET_SRC (x);
+	  if (last_dest != NULL_RTX
+	      && GET_CODE (src) == ZERO_EXTEND
+	      && REG_P (XEXP (src, 0))
+	      && REGNO (XEXP (src, 0)) == REGNO (last_dest))
+	    {
+	      riscv_if_info.original_cost += COSTS_N_INSNS (1);
+	      riscv_if_info.max_seq_cost += COSTS_N_INSNS (1);
+	    }
+	  last_dest = NULL_RTX;
+	  rtx dest = SET_DEST (x);
+	  if (COMPARISON_P (src)
+	      && REG_P (dest)
+	      && GET_MODE (dest) == SImode)
+	    last_dest = dest;
+	}
+      else
+	last_dest = NULL_RTX;
+    }
+
+  return default_noce_conversion_profitable_p (seq, &riscv_if_info);
+}
+
 /* Return one word of double-word value OP.  HIGH_P is true to select the
    high part or false to select the low part. */
 
@@ -9823,6 +9936,13 @@ riscv_preferred_else_value (unsigned ifn
 #define TARGET_RTX_COSTS riscv_rtx_costs
 #undef TARGET_ADDRESS_COST
 #define TARGET_ADDRESS_COST riscv_address_cost
+#undef TARGET_INSN_COST
+#define TARGET_INSN_COST riscv_insn_cost
+
+#undef TARGET_MAX_NOCE_IFCVT_SEQ_COST
+#define TARGET_MAX_NOCE_IFCVT_SEQ_COST riscv_max_noce_ifcvt_seq_cost
+#undef TARGET_NOCE_CONVERSION_PROFITABLE_P
+#define TARGET_NOCE_CONVERSION_PROFITABLE_P riscv_noce_conversion_profitable_p
 
 #undef TARGET_ASM_FILE_START
 #define TARGET_ASM_FILE_START riscv_file_start
Index: gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c
+++ gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
-/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=4" { target { rv32 } } } */
 /* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
 
 long primitiveSemantics_compare_imm_return_imm_imm_00(long a, long b) {
Index: gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c
+++ gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
-/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=4" { target { rv32 } } } */
 /* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
 
 long primitiveSemantics_compare_imm_return_imm_reg_00(long a, long b) {
Index: gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c
+++ gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
-/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=5" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=5" { target { rv32 } } } */
 /* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
 
 long primitiveSemantics_compare_imm_return_reg_reg_00(long a, long b, long c) {
Index: gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c
+++ gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
-/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=4" { target { rv32 } } } */
 /* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
 
 long primitiveSemantics_compare_reg_return_imm_imm_00(long a, long b, long c) {
Index: gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c
+++ gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
-/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=4" { target { rv32 } } } */
 /* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
 
 long primitiveSemantics_compare_reg_return_imm_reg_00(long a, long b, long c) {
Index: gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c
+++ gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
-/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=5" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=5" { target { rv32 } } } */
 /* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
 
 long primitiveSemantics_compare_reg_return_reg_reg_00(long a, long b, long c,

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 10/44] RISC-V/testsuite: Add branched cases for integer cond-move operations
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (9 preceding siblings ...)
  2023-11-19  5:36 ` [PATCH 09/44] RISC-V: Rework branch costing model for if-conversion Maciej W. Rozycki
@ 2023-11-19  5:37 ` 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
                   ` (33 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:37 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for T-Head, Ventana and Zicond targets and the integer 
conditional-move operations that already work as expected, that 
if-conversion does *not* trigger at the respective sufficiently low 
`-mbranch-cost=' settings that make original branched code sequences 
cheaper than their branchless equivalents if-conversion would emit.  
Cover all integer relational operations to make sure no corner case 
escapes.

The reason to XFAIL movdibne-thead.c and movsibne-thead.c is the 
branchless T-Head sequence:

	sub	a1,a0,a1
	th.mveqz	a2,a3,a1
	mv	a0,a2
	ret

produced rather than its original branched counterpart:

	beq	a0,a1,.L3
	mv	a0,a2
	ret
.L3:
	mv	a0,a3
	ret

at `-mbranch-cost=1', even though under this setting the latter sequence 
is obviously cheaper performance-wise.  This is because the final move 
instruction in the branchless sequence is not counted towards its cost 
and consequently the cost of both sequences works out at 8 each, making 
if-conversion prefer the branchless variant.  Use the XFAIL mark to keep 
track of these cases for future consideration.

	gcc/testsuite/
	* gcc.target/riscv/movdibeq-thead.c: New test.
	* gcc.target/riscv/movdibge-ventana.c: New test.
	* gcc.target/riscv/movdibge-zicond.c: New test.
	* gcc.target/riscv/movdibgeu-ventana.c: New test.
	* gcc.target/riscv/movdibgeu-zicond.c: New test.
	* gcc.target/riscv/movdibgt-ventana.c: New test.
	* gcc.target/riscv/movdibgt-zicond.c: New test.
	* gcc.target/riscv/movdible-ventana.c: New test.
	* gcc.target/riscv/movdible-zicond.c: New test.
	* gcc.target/riscv/movdibleu-ventana.c: New test.
	* gcc.target/riscv/movdibleu-zicond.c: New test.
	* gcc.target/riscv/movdiblt-ventana.c: New test.
	* gcc.target/riscv/movdiblt-zicond.c: New test.
	* gcc.target/riscv/movdibne-thead.c: New test.
	* gcc.target/riscv/movsibeq-thead.c: New test.
	* gcc.target/riscv/movsibge-ventana.c: New test.
	* gcc.target/riscv/movsibge-zicond.c: New test.
	* gcc.target/riscv/movsibgeu-ventana.c: New test.
	* gcc.target/riscv/movsibgeu-zicond.c: New test.
	* gcc.target/riscv/movsibgt-ventana.c: New test.
	* gcc.target/riscv/movsibgt-zicond.c: New test.
	* gcc.target/riscv/movsible-ventana.c: New test.
	* gcc.target/riscv/movsible-zicond.c: New test.
	* gcc.target/riscv/movsibleu-ventana.c: New test.
	* gcc.target/riscv/movsibleu-zicond.c: New test.
	* gcc.target/riscv/movsiblt-ventana.c: New test.
	* gcc.target/riscv/movsiblt-zicond.c: New test.
	* gcc.target/riscv/movsibne-thead.c: New test.
---
 gcc/testsuite/gcc.target/riscv/movdibeq-thead.c    |   27 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibge-ventana.c  |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibge-zicond.c   |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibgeu-ventana.c |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibgeu-zicond.c  |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibgt-ventana.c  |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibgt-zicond.c   |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdible-ventana.c  |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdible-zicond.c   |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibleu-ventana.c |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibleu-zicond.c  |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdiblt-ventana.c  |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdiblt-zicond.c   |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibne-thead.c    |   29 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibeq-thead.c    |   27 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibge-ventana.c  |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibge-zicond.c   |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibgeu-ventana.c |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibgeu-zicond.c  |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibgt-ventana.c  |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibgt-zicond.c   |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsible-ventana.c  |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsible-zicond.c   |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibleu-ventana.c |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibleu-zicond.c  |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsiblt-ventana.c  |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsiblt-zicond.c   |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibne-thead.c    |   29 +++++++++++++++++++++
 28 files changed, 784 insertions(+)

gcc-riscv-branch-cost-test-movcc-branch.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibeq-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibeq-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bne	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibge-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibge-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	blt	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibge-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibge-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	blt	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibgeu-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibgeu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bltu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibgeu-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibgeu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bltu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibgt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibgt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	ble	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibgt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibgt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	ble	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdible-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdible-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgt	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdible-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdible-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgt	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibleu-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibleu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgtu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibleu-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibleu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgtu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiblt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiblt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bge	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiblt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiblt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bge	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibne-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibne-thead.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	beq	a0,a1,.L3
+	mv	a0,a2
+	ret
+.L3:
+	mv	a0,a3
+	ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" { xfail "*-*-*" } } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" { xfail "*-*-*" } } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 { xfail "*-*-*" } } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" { xfail "*-*-*" } } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" { xfail "*-*-*" } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibeq-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibeq-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bne	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibge-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibge-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	blt	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibge-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibge-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	blt	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibgeu-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibgeu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bltu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibgeu-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibgeu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bltu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibgt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibgt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	ble	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibgt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibgt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	ble	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsible-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsible-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgt	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsible-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsible-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgt	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibleu-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibleu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgtu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibleu-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibleu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgtu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiblt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiblt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bge	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiblt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiblt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bge	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibne-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibne-thead.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	beq	a0,a1,.L3
+	mv	a0,a2
+	ret
+.L3:
+	mv	a0,a3
+	ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" { xfail "*-*-*" } } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" { xfail "*-*-*" } } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 { xfail "*-*-*" } } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" { xfail "*-*-*" } } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" { xfail "*-*-*" } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 11/44] RISC-V/testsuite: Add branchless cases for integer cond-move operations
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (10 preceding siblings ...)
  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  5:37 ` Maciej W. Rozycki
  2023-11-19  6:47   ` Kito Cheng
  2023-11-19  5:37 ` [PATCH 12/44] RISC-V/testsuite: Add branched cases for FP " Maciej W. Rozycki
                   ` (32 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:37 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for T-Head, Ventana and Zicond targets and the integer 
conditional-move operations that already work as expected, if-conversion 
to trigger via `noce_try_cmove' at the respective sufficiently high 
`-mbranch-cost=' settings that make branchless code sequences produced 
by if-conversion cheaper than their original branched equivalents, and 
that extraneous instructions such as SNEZ, etc. are not present in 
output.  Cover all integer relational operations to make sure no corner 
case escapes.

	gcc/testsuite/
	* gcc.target/riscv/movdieq-thead.c: New test.
	* gcc.target/riscv/movdige-ventana.c: New test.
	* gcc.target/riscv/movdige-zicond.c: New test.
	* gcc.target/riscv/movdigeu-ventana.c: New test.
	* gcc.target/riscv/movdigeu-zicond.c: New test.
	* gcc.target/riscv/movdigt-ventana.c: New test.
	* gcc.target/riscv/movdigt-zicond.c: New test.
	* gcc.target/riscv/movdile-ventana.c: New test.
	* gcc.target/riscv/movdile-zicond.c: New test.
	* gcc.target/riscv/movdileu-ventana.c: New test.
	* gcc.target/riscv/movdileu-zicond.c: New test.
	* gcc.target/riscv/movdilt-ventana.c: New test.
	* gcc.target/riscv/movdilt-zicond.c: New test.
	* gcc.target/riscv/movdine-thead.c: New test.
	* gcc.target/riscv/movsieq-thead.c: New test.
	* gcc.target/riscv/movsige-ventana.c: New test.
	* gcc.target/riscv/movsige-zicond.c: New test.
	* gcc.target/riscv/movsigeu-ventana.c: New test.
	* gcc.target/riscv/movsigeu-zicond.c: New test.
	* gcc.target/riscv/movsigt-ventana.c: New test.
	* gcc.target/riscv/movsigt-zicond.c: New test.
	* gcc.target/riscv/movsile-ventana.c: New test.
	* gcc.target/riscv/movsile-zicond.c: New test.
	* gcc.target/riscv/movsileu-ventana.c: New test.
	* gcc.target/riscv/movsileu-zicond.c: New test.
	* gcc.target/riscv/movsilt-ventana.c: New test.
	* gcc.target/riscv/movsilt-zicond.c: New test.
	* gcc.target/riscv/movsine-thead.c: New test.
---
 gcc/testsuite/gcc.target/riscv/movdieq-thead.c    |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdige-ventana.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdige-zicond.c   |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdigeu-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdigeu-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdigt-ventana.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdigt-zicond.c   |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdile-ventana.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdile-zicond.c   |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdileu-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdileu-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdilt-ventana.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdilt-zicond.c   |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdine-thead.c    |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsieq-thead.c    |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsige-ventana.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsige-zicond.c   |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsigeu-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsigeu-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsigt-ventana.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsigt-zicond.c   |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsile-ventana.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsile-zicond.c   |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsileu-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsileu-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsilt-ventana.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsilt-zicond.c   |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsine-thead.c    |   26 ++++++++++++++++++++
 28 files changed, 776 insertions(+)

gcc-riscv-branch-cost-test-movcc.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/movdieq-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdieq-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sub	a0,a0,a1
+	th.mvnez	a2,a3,a0
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdige-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdige-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a1,a0,a1
+	vt.maskc	a3,a3,a1
+	vt.maskcn	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdige-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdige-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a1,a0,a1
+	czero.eqz	a3,a3,a1
+	czero.nez	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdigeu-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdigeu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a1,a0,a1
+	vt.maskc	a3,a3,a1
+	vt.maskcn	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdigeu-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdigeu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a1,a0,a1
+	czero.eqz	a3,a3,a1
+	czero.nez	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdigt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdigt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a1,a0,a1
+	vt.maskcn	a3,a3,a1
+	vt.maskc	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdigt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdigt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a1,a0,a1
+	czero.nez	a3,a3,a1
+	czero.eqz	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdile-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdile-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a1,a0,a1
+	vt.maskc	a3,a3,a1
+	vt.maskcn	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdile-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdile-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a1,a0,a1
+	czero.eqz	a3,a3,a1
+	czero.nez	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdileu-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdileu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a1,a0,a1
+	vt.maskc	a3,a3,a1
+	vt.maskcn	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdileu-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdileu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a1,a0,a1
+	czero.eqz	a3,a3,a1
+	czero.nez	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdilt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdilt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a1,a0,a1
+	vt.maskcn	a3,a3,a1
+	vt.maskc	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdilt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdilt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a1,a0,a1
+	czero.nez	a3,a3,a1
+	czero.eqz	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdine-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdine-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sub	a1,a0,a1
+	th.mveqz	a2,a3,a1
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsieq-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsieq-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sub	a0,a0,a1
+	th.mvnez	a2,a3,a0
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsige-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsige-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a1,a0,a1
+	vt.maskc	a3,a3,a1
+	vt.maskcn	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsige-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsige-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a1,a0,a1
+	czero.eqz	a3,a3,a1
+	czero.nez	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsigeu-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsigeu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a1,a0,a1
+	vt.maskc	a3,a3,a1
+	vt.maskcn	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsigeu-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsigeu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a1,a0,a1
+	czero.eqz	a3,a3,a1
+	czero.nez	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsigt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsigt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a1,a0,a1
+	vt.maskcn	a3,a3,a1
+	vt.maskc	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsigt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsigt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a1,a0,a1
+	czero.nez	a3,a3,a1
+	czero.eqz	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsile-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsile-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a1,a0,a1
+	vt.maskc	a3,a3,a1
+	vt.maskcn	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsile-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsile-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a1,a0,a1
+	czero.eqz	a3,a3,a1
+	czero.nez	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsileu-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsileu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a1,a0,a1
+	vt.maskc	a3,a3,a1
+	vt.maskcn	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsileu-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsileu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a1,a0,a1
+	czero.eqz	a3,a3,a1
+	czero.nez	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsilt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsilt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a1,a0,a1
+	vt.maskcn	a3,a3,a1
+	vt.maskc	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsilt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsilt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a1,a0,a1
+	czero.nez	a3,a3,a1
+	czero.eqz	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsine-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsine-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sub	a1,a0,a1
+	th.mveqz	a2,a3,a1
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 12/44] RISC-V/testsuite: Add branched cases for FP cond-move operations
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (11 preceding siblings ...)
  2023-11-19  5:37 ` [PATCH 11/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
@ 2023-11-19  5:37 ` 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
                   ` (31 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:37 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for Ventana and Zicond targets and the ordered floating-point 
conditional-move operations that already work as expected, that 
if-conversion does *not* trigger at `-mbranch-cost=2' setting, which 
makes original branched code sequences cheaper than their branchless 
equivalents if-conversion would emit.  Cover all ordered floating-point 
relational operations to make sure no corner case escapes.

	gcc/testsuite/
	* gcc.target/riscv/movdibfge-ventana.c: New test.
	* gcc.target/riscv/movdibfge-zicond.c: New test.
	* gcc.target/riscv/movdibfgt-ventana.c: New test.
	* gcc.target/riscv/movdibfgt-zicond.c: New test.
	* gcc.target/riscv/movdibfle-ventana.c: New test.
	* gcc.target/riscv/movdibfle-zicond.c: New test.
	* gcc.target/riscv/movdibflt-ventana.c: New test.
	* gcc.target/riscv/movdibflt-zicond.c: New test.
	* gcc.target/riscv/movdibfne-ventana.c: New test.
	* gcc.target/riscv/movdibfne-zicond.c: New test.
	* gcc.target/riscv/movsibfge-ventana.c: New test.
	* gcc.target/riscv/movsibfge-zicond.c: New test.
	* gcc.target/riscv/movsibfgt-ventana.c: New test.
	* gcc.target/riscv/movsibfgt-zicond.c: New test.
	* gcc.target/riscv/movsibfle-ventana.c: New test.
	* gcc.target/riscv/movsibfle-zicond.c: New test.
	* gcc.target/riscv/movsibflt-ventana.c: New test.
	* gcc.target/riscv/movsibflt-zicond.c: New test.
	* gcc.target/riscv/movsibfne-ventana.c: New test.
	* gcc.target/riscv/movsibfne-zicond.c: New test.
---
 gcc/testsuite/gcc.target/riscv/movdibfge-ventana.c |   29 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibfge-zicond.c  |   29 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibfgt-ventana.c |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibfgt-zicond.c  |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibfle-ventana.c |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibfle-zicond.c  |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibflt-ventana.c |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibflt-zicond.c  |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibfne-ventana.c |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibfne-zicond.c  |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibfge-ventana.c |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibfge-zicond.c  |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibfgt-ventana.c |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibfgt-zicond.c  |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibfle-ventana.c |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibfle-zicond.c  |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibflt-ventana.c |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibflt-zicond.c  |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibfne-ventana.c |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibfne-zicond.c  |   30 +++++++++++++++++++++
 20 files changed, 598 insertions(+)

gcc-riscv-branch-cost-test-movccf-branch.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfge-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibfge-ventana.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	fge.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfge-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibfge-zicond.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	fge.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfgt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibfgt-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	fgt.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfgt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibfgt-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	fgt.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfle-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibfle-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	fle.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfle-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibfle-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	fle.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibflt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibflt-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	flt.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibflt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibflt-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	flt.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfne-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibfne-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	feq.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	bne	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfne-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibfne-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	feq.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	bne	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfge-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibfge-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	fge.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfge-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibfge-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	fge.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfgt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibfgt-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	fgt.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfgt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibfgt-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	fgt.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfle-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibfle-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	fle.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfle-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibfle-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	fle.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibflt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibflt-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	flt.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibflt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibflt-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	flt.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfne-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibfne-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	feq.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	bne	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfne-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibfne-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	feq.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	bne	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 13/44] RISC-V/testsuite: Add branchless cases for FP cond-move operations
  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  5:37   ` Maciej W. Rozycki
  1 sibling, 0 replies; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:37 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for short forward branch, T-Head, Ventana and Zicond targets and 
the ordered floating-point conditional-move operations that already work 
as expected, that if-conversion triggers via `noce_try_cmove' at the 
respective sufficiently high `-mbranch-cost=' settings that make 
branchless code sequences produced by if-conversion cheaper than their 
original branched equivalents, and that extraneous instructions such as 
SNEZ, etc. are not present in output.  Cover all ordered floating-point 
relational operations to make sure no corner case escapes.

	gcc/testsuite/
	* gcc.target/riscv/movdifge-sfb.c: New test.
	* gcc.target/riscv/movdifge-thead.c: New test.
	* gcc.target/riscv/movdifge-ventana.c: New test.
	* gcc.target/riscv/movdifge-zicond.c: New test.
	* gcc.target/riscv/movdifgt-sfb.c: New test.
	* gcc.target/riscv/movdifgt-thead.c: New test.
	* gcc.target/riscv/movdifgt-ventana.c: New test.
	* gcc.target/riscv/movdifgt-zicond.c: New test.
	* gcc.target/riscv/movdifle-sfb.c: New test.
	* gcc.target/riscv/movdifle-thead.c: New test.
	* gcc.target/riscv/movdifle-ventana.c: New test.
	* gcc.target/riscv/movdifle-zicond.c: New test.
	* gcc.target/riscv/movdiflt-sfb.c: New test.
	* gcc.target/riscv/movdiflt-thead.c: New test.
	* gcc.target/riscv/movdiflt-ventana.c: New test.
	* gcc.target/riscv/movdiflt-zicond.c: New test.
	* gcc.target/riscv/movdifne-sfb.c: New test.
	* gcc.target/riscv/movdifne-thead.c: New test.
	* gcc.target/riscv/movdifne-ventana.c: New test.
	* gcc.target/riscv/movdifne-zicond.c: New test.
	* gcc.target/riscv/movsifge-sfb.c: New test.
	* gcc.target/riscv/movsifge-thead.c: New test.
	* gcc.target/riscv/movsifge-ventana.c: New test.
	* gcc.target/riscv/movsifge-zicond.c: New test.
	* gcc.target/riscv/movsifgt-sfb.c: New test.
	* gcc.target/riscv/movsifgt-thead.c: New test.
	* gcc.target/riscv/movsifgt-ventana.c: New test.
	* gcc.target/riscv/movsifgt-zicond.c: New test.
	* gcc.target/riscv/movsifle-sfb.c: New test.
	* gcc.target/riscv/movsifle-thead.c: New test.
	* gcc.target/riscv/movsifle-ventana.c: New test.
	* gcc.target/riscv/movsifle-zicond.c: New test.
	* gcc.target/riscv/movsiflt-sfb.c: New test.
	* gcc.target/riscv/movsiflt-thead.c: New test.
	* gcc.target/riscv/movsiflt-ventana.c: New test.
	* gcc.target/riscv/movsiflt-zicond.c: New test.
	* gcc.target/riscv/movsifne-sfb.c: New test.
	* gcc.target/riscv/movsifne-thead.c: New test.
	* gcc.target/riscv/movsifne-ventana.c: New test.
	* gcc.target/riscv/movsifne-zicond.c: New test.
---
 gcc/testsuite/gcc.target/riscv/movdifge-sfb.c     |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifge-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifge-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifge-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifgt-sfb.c     |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifgt-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifgt-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifgt-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifle-sfb.c     |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifle-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifle-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifle-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdiflt-sfb.c     |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdiflt-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdiflt-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdiflt-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifne-sfb.c     |   27 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifne-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifne-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifne-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifge-sfb.c     |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifge-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifge-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifge-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifgt-sfb.c     |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifgt-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifgt-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifgt-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifle-sfb.c     |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifle-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifle-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifle-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsiflt-sfb.c     |   26 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsiflt-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsiflt-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsiflt-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifne-sfb.c     |   27 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifne-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifne-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifne-zicond.c  |   28 ++++++++++++++++++++++
 40 files changed, 1072 insertions(+)

gcc-riscv-branch-cost-test-movccf.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifge-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifge-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	fge.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifge-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifge-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fge.d	a5,fa0,fa1
+	th.mveqz	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifge-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifge-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fge.d	a5,fa0,fa1
+	vt.maskc	a0,a0,a5
+	vt.maskcn	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifge-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifge-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fge.d	a5,fa0,fa1
+	czero.eqz	a0,a0,a5
+	czero.nez	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifgt-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifgt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	fgt.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifgt-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifgt-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fgt.d	a5,fa0,fa1
+	th.mveqz	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifgt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifgt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fgt.d	a5,fa0,fa1
+	vt.maskc	a0,a0,a5
+	vt.maskcn	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifgt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifgt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fgt.d	a5,fa0,fa1
+	czero.eqz	a0,a0,a5
+	czero.nez	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifle-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifle-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	fle.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifle-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifle-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fle.d	a5,fa0,fa1
+	th.mveqz	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifle-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifle-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fle.d	a5,fa0,fa1
+	vt.maskc	a0,a0,a5
+	vt.maskcn	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifle-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifle-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fle.d	a5,fa0,fa1
+	czero.eqz	a0,a0,a5
+	czero.nez	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiflt-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiflt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	flt.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiflt-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiflt-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	flt.d	a5,fa0,fa1
+	th.mveqz	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiflt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiflt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	flt.d	a5,fa0,fa1
+	vt.maskc	a0,a0,a5
+	vt.maskcn	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiflt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiflt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	flt.d	a5,fa0,fa1
+	czero.eqz	a0,a0,a5
+	czero.nez	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifne-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifne-sfb.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	feq.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a1,a0
+1:
+	mv	a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifne-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifne-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	th.mvnez	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifne-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifne-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	vt.maskc	a1,a1,a5
+	vt.maskcn	a0,a0,a5
+	or	a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifne-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifne-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	czero.eqz	a1,a1,a5
+	czero.nez	a0,a0,a5
+	or	a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifge-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifge-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	fge.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifge-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifge-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fge.d	a5,fa0,fa1
+	th.mveqz	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifge-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifge-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fge.d	a5,fa0,fa1
+	vt.maskc	a0,a0,a5
+	vt.maskcn	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifge-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifge-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fge.d	a5,fa0,fa1
+	czero.eqz	a0,a0,a5
+	czero.nez	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifgt-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifgt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	fgt.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifgt-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifgt-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fgt.d	a5,fa0,fa1
+	th.mveqz	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifgt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifgt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fgt.d	a5,fa0,fa1
+	vt.maskc	a0,a0,a5
+	vt.maskcn	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifgt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifgt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fgt.d	a5,fa0,fa1
+	czero.eqz	a0,a0,a5
+	czero.nez	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifle-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifle-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	fle.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifle-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifle-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fle.d	a5,fa0,fa1
+	th.mveqz	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifle-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifle-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fle.d	a5,fa0,fa1
+	vt.maskc	a0,a0,a5
+	vt.maskcn	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifle-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifle-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fle.d	a5,fa0,fa1
+	czero.eqz	a0,a0,a5
+	czero.nez	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiflt-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiflt-sfb.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	flt.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a0,a1
+1:
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiflt-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiflt-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	flt.d	a5,fa0,fa1
+	th.mveqz	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiflt-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiflt-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	flt.d	a5,fa0,fa1
+	vt.maskc	a0,a0,a5
+	vt.maskcn	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiflt-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiflt-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	flt.d	a5,fa0,fa1
+	czero.eqz	a0,a0,a5
+	czero.nez	a5,a1,a5
+	or	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifne-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifne-sfb.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	feq.d	a5,fa0,fa1
+	bne	a5,zero,1f	# movcc
+	mv	a1,a0
+1:
+	mv	a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifne-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifne-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	th.mvnez	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifne-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifne-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	vt.maskc	a1,a1,a5
+	vt.maskcn	a0,a0,a5
+	or	a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifne-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifne-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	czero.eqz	a1,a1,a5
+	czero.nez	a0,a0,a5
+	or	a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 14/44] RISC-V: Also invert the cond-move condition for GEU and LEU
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (12 preceding siblings ...)
  2023-11-19  5:37 ` [PATCH 12/44] RISC-V/testsuite: Add branched cases for FP " Maciej W. Rozycki
@ 2023-11-19  5:38 ` 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
                   ` (30 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:38 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Update `riscv_expand_conditional_move' and handle the missing GEU and 
LEU operators there, avoiding an extraneous conditional set operation, 
such as with this output:

	sgtu	a0,a0,a1
	seqz	a1,a0
	czero.eqz	a3,a3,a1
	czero.nez	a1,a2,a1
	or	a0,a1,a3

produced when optimizing for Zicond targets from:

int
movsigtu (int w, int x, int y, int z)
{
  return w > x ? y : z;
}

These operators can be inverted producing optimal code such as this:

	sgtu	a1,a0,a1
	czero.nez	a3,a3,a1
	czero.eqz	a1,a2,a1
	or	a0,a1,a3

which this change causes to happen.

	gcc/
	* config/riscv/riscv.cc (riscv_expand_conditional_move): Also 
	invert the condition for GEU and LEU.
---
 gcc/config/riscv/riscv.cc |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

gcc-riscv-expand-conditional-move-geu-leu.diff
Index: gcc/gcc/config/riscv/riscv.cc
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.cc
+++ gcc/gcc/config/riscv/riscv.cc
@@ -4142,7 +4142,7 @@ riscv_expand_conditional_move (rtx dest,
 	  /* If riscv_expand_int_scc inverts the condition, then it will
 	     flip the value of INVERT.  We need to know where so that
 	     we can adjust it for our needs.  */
-	  if (code == LE || code == GE)
+	  if (code == LE || code == LEU || code == GE || code == GEU)
 	    invert_ptr = &invert;
 
 	  /* Emit an scc like instruction into a temporary

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 15/44] RISC-V/testsuite: Add branched cases for GEU and LEU cond-move operations
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (13 preceding siblings ...)
  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  5:38 ` 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
                   ` (29 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:38 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for Ventana and Zicond targets and the GEU and LEU 
conditional-move operations, that if-conversion does *not* trigger at 
`-mbranch-cost=3' setting, which makes original branched code sequences 
cheaper than their branchless equivalents if-conversion would emit.
	
gcc/testsuite/
	* gcc.target/riscv/movdibgtu-ventana.c: New test.
	* gcc.target/riscv/movdibgtu-zicond.c: New test.
	* gcc.target/riscv/movdibltu-ventana.c: New test.
	* gcc.target/riscv/movdibltu-zicond.c: New test.
	* gcc.target/riscv/movsibgtu-ventana.c: New test.
	* gcc.target/riscv/movsibgtu-zicond.c: New test.
	* gcc.target/riscv/movsibltu-ventana.c: New test.
	* gcc.target/riscv/movsibltu-zicond.c: New test.
---
 gcc/testsuite/gcc.target/riscv/movdibgtu-ventana.c |   28 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibgtu-zicond.c  |   28 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibltu-ventana.c |   28 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibltu-zicond.c  |   28 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibgtu-ventana.c |   28 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibgtu-zicond.c  |   28 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibltu-ventana.c |   28 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibltu-zicond.c  |   28 +++++++++++++++++++++
 8 files changed, 224 insertions(+)

gcc-riscv-expand-conditional-move-geu-leu-test-movcc-branch.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibgtu-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibgtu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bleu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibgtu-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibgtu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bleu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibltu-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibltu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgeu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibltu-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibltu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgeu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibgtu-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibgtu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bleu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibgtu-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibgtu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bleu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibltu-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibltu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgeu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibltu-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibltu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgeu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 16/44] RISC-V/testsuite: Add branchless cases for GEU and LEU cond-move operations
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (14 preceding siblings ...)
  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  5:38 ` 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
                   ` (28 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:38 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for Ventana and Zicond targets and the GEU and LEU 
conditional-move operations, that if-conversion triggers via 
`noce_try_cmove' at `-mbranch-cost=4' setting, which makes branchless 
code sequences produced by if-conversion cheaper than their original 
branched equivalents, and that extraneous instructions such as SEQZ, 
etc. are not present in output.

	gcc/testsuite/
	* gcc.target/riscv/movdigtu-ventana.c: New test.
	* gcc.target/riscv/movdigtu-zicond.c: New test.
	* gcc.target/riscv/movdiltu-ventana.c: New test.
	* gcc.target/riscv/movdiltu-zicond.c: New test.
	* gcc.target/riscv/movsigtu-ventana.c: New test.
	* gcc.target/riscv/movsigtu-zicond.c: New test.
	* gcc.target/riscv/movsiltu-ventana.c: New test.
	* gcc.target/riscv/movsiltu-zicond.c: New test.
---
 gcc/testsuite/gcc.target/riscv/movdigtu-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdigtu-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdiltu-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdiltu-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsigtu-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsigtu-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsiltu-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsiltu-zicond.c  |   28 ++++++++++++++++++++++
 8 files changed, 224 insertions(+)

gcc-riscv-expand-conditional-move-geu-leu-test-movcc.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/movdigtu-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdigtu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a1,a0,a1
+	vt.maskcn	a3,a3,a1
+	vt.maskc	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdigtu-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdigtu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a1,a0,a1
+	czero.nez	a3,a3,a1
+	czero.eqz	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiltu-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiltu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a1,a0,a1
+	vt.maskcn	a3,a3,a1
+	vt.maskc	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiltu-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiltu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a1,a0,a1
+	czero.nez	a3,a3,a1
+	czero.eqz	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsigtu-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsigtu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a1,a0,a1
+	vt.maskcn	a3,a3,a1
+	vt.maskc	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsigtu-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsigtu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a1,a0,a1
+	czero.nez	a3,a3,a1
+	czero.eqz	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiltu-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiltu-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a1,a0,a1
+	vt.maskcn	a3,a3,a1
+	vt.maskc	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiltu-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiltu-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a1,a0,a1
+	czero.nez	a3,a3,a1
+	czero.eqz	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 17/44] RISC-V: Avoid extraneous EQ or NE operation in cond-move expansion
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (15 preceding siblings ...)
  2023-11-19  5:38 ` [PATCH 16/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
@ 2023-11-19  5:38 ` 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
                   ` (27 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:38 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

In the non-zero case there is no need for the conditional value used by 
Ventana and Zicond integer conditional operations to be specifically 1. 
Regardless we canonicalize it by producing an extraneous conditional-set 
operation, such as with the sequence below:

(insn 22 6 23 2 (set (reg:DI 141)
        (minus:DI (reg/v:DI 135 [ w ])
            (reg/v:DI 136 [ x ]))) 11 {subdi3}
     (nil))
(insn 23 22 24 2 (set (reg:DI 140)
        (ne:DI (reg:DI 141)
            (const_int 0 [0]))) 307 {*sne_zero_didi}
     (nil))
(insn 24 23 25 2 (set (reg:DI 143)
        (if_then_else:DI (eq:DI (reg:DI 140)
                (const_int 0 [0]))
            (const_int 0 [0])
            (reg:DI 13 a3 [ z ]))) 27913 {*czero.eqz.didi}
     (nil))
(insn 25 24 26 2 (set (reg:DI 142)
        (if_then_else:DI (ne:DI (reg:DI 140)
                (const_int 0 [0]))
            (const_int 0 [0])
            (reg/v:DI 137 [ y ]))) 27914 {*czero.nez.didi}
     (nil))
(insn 26 25 18 2 (set (reg/v:DI 138 [ z ])
        (ior:DI (reg:DI 142)
            (reg:DI 143))) 105 {iordi3}
     (nil))

where insn 23 can well be removed without changing the semantics of the 
sequence.  This is actually fixed up later on by combine and the insn 
does not make it to output meaning no SNEZ (or SEQZ in the reverse case) 
appears in the assembly produced, however it counts towards the cost of 
the sequence calculated by if-conversion, raising the trigger level for 
the branchless sequence to be chosen.  Arguably to emit this extraneous 
operation it can be also considered rather sloppy of our backend's.

Remove the check for operand 1 being constant 0 in the Ventana/Zicond 
case for equality comparisons then, observing that `riscv_zero_if_equal' 
called via `riscv_emit_int_compare' will canonicalize the comparison if 
required, removing the extraneous insn from output:

(insn 22 6 23 2 (set (reg:DI 142)
        (minus:DI (reg/v:DI 135 [ w ])
            (reg/v:DI 136 [ x ]))) 11 {subdi3}
     (nil))
(insn 23 22 24 2 (set (reg:DI 141)
        (if_then_else:DI (eq:DI (reg:DI 142)
                (const_int 0 [0]))
            (const_int 0 [0])
            (reg:DI 13 a3 [ z ]))) 27913 {*czero.eqz.didi}
     (nil))
(insn 24 23 25 2 (set (reg:DI 140)
        (if_then_else:DI (ne:DI (reg:DI 142)
                (const_int 0 [0]))
            (const_int 0 [0])
            (reg/v:DI 137 [ y ]))) 27914 {*czero.nez.didi}
     (nil))
(insn 25 24 18 2 (set (reg/v:DI 138 [ z ])
        (ior:DI (reg:DI 140)
            (reg:DI 141))) 105 {iordi3}
     (nil))

while keeping actual assembly produced the same.

Adjust branch costs across the test cases affected accordingly.

	gcc/
	* config/riscv/riscv.cc (riscv_expand_conditional_move): Remove 
	the check for operand 1 being constant 0 in the Ventana/Zicond
	case for equality comparisons.

	gcc/testsuite/
	* gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c: 
	Lower `-mbranch-cost=' setting.
	* gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c: 
	Likewise.
	* gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c: 
	Likewise.
	* gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c: 
	Likewise.
	* gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c: 
	Likewise.
	* gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c: 
	Likewise.
---
 gcc/config/riscv/riscv.cc                                                             |    6 +++---
 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c |    4 ++--
 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c |    4 ++--
 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c |    4 ++--
 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c |    4 ++--
 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c |    4 ++--
 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c |    4 ++--
 7 files changed, 15 insertions(+), 15 deletions(-)

gcc-riscv-expand-conditional-move-zicond-equality.diff
Index: gcc/gcc/config/riscv/riscv.cc
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.cc
+++ gcc/gcc/config/riscv/riscv.cc
@@ -4132,9 +4132,9 @@ riscv_expand_conditional_move (rtx dest,
 	return false;
 
       /* Canonicalize the comparison.  It must be an equality comparison
-	 against 0.  If it isn't, then emit an SCC instruction so that
-	 we can then use an equality comparison against zero.  */
-      if (!equality_operator (op, VOIDmode) || op1 != CONST0_RTX (mode))
+	 of integer operands.  If it isn't, then emit an SCC instruction
+	 so that we can then use an equality comparison against zero.  */
+      if (!equality_operator (op, VOIDmode) || !INTEGRAL_MODE_P (mode0))
 	{
 	  bool *invert_ptr = nullptr;
 	  bool invert = false;
Index: gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c
+++ gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" { target { rv64 } } } */
-/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=4" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=3" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=3" { target { rv32 } } } */
 /* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
 
 long primitiveSemantics_compare_imm_return_imm_imm_00(long a, long b) {
Index: gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c
+++ gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" { target { rv64 } } } */
-/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=4" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=3" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=3" { target { rv32 } } } */
 /* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
 
 long primitiveSemantics_compare_imm_return_imm_reg_00(long a, long b) {
Index: gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c
+++ gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=5" { target { rv64 } } } */
-/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=5" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=4" { target { rv32 } } } */
 /* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
 
 long primitiveSemantics_compare_imm_return_reg_reg_00(long a, long b, long c) {
Index: gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c
+++ gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" { target { rv64 } } } */
-/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=4" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=3" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=3" { target { rv32 } } } */
 /* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
 
 long primitiveSemantics_compare_reg_return_imm_imm_00(long a, long b, long c) {
Index: gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c
+++ gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" { target { rv64 } } } */
-/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=4" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=3" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=3" { target { rv32 } } } */
 /* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
 
 long primitiveSemantics_compare_reg_return_imm_reg_00(long a, long b, long c) {
Index: gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c
+++ gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=5" { target { rv64 } } } */
-/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=5" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=4" { target { rv32 } } } */
 /* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
 
 long primitiveSemantics_compare_reg_return_reg_reg_00(long a, long b, long c,

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 18/44] RISC-V/testsuite: Add branched cases for equality cond-move operations
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (16 preceding siblings ...)
  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  5:38 ` 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
                   ` (26 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:38 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for Ventana and Zicond targets and the equality conditional-move 
operations, that if-conversion does *not* trigger at the respective 
sufficiently low `-mbranch-cost=' settings that make original branched 
code sequences cheaper than their branchless equivalents if-conversion 
would emit.

	gcc/testsuite/
	* gcc.target/riscv/movdibeq-ventana.c: New test.
	* gcc.target/riscv/movdibeq-zicond.c: New test.
	* gcc.target/riscv/movdibne-ventana.c: New test.
	* gcc.target/riscv/movdibne-zicond.c: New test.
	* gcc.target/riscv/movsibeq-ventana.c: New test.
	* gcc.target/riscv/movsibeq-zicond.c: New test.
	* gcc.target/riscv/movsibne-ventana.c: New test.
	* gcc.target/riscv/movsibne-zicond.c: New test.
---
 gcc/testsuite/gcc.target/riscv/movdibeq-ventana.c |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibeq-zicond.c  |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibne-ventana.c |   30 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibne-zicond.c  |   30 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibeq-ventana.c |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibeq-zicond.c  |   28 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibne-ventana.c |   30 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibne-zicond.c  |   30 ++++++++++++++++++++++
 8 files changed, 232 insertions(+)

gcc-riscv-expand-conditional-move-zicond-equality-test-movcc-branch.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibeq-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibeq-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bne	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibeq-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibeq-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bne	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibne-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibne-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	beq	a0,a1,.L3
+	mv	a0,a2
+	ret
+.L3:
+	mv	a0,a3
+	ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibne-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibne-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	beq	a0,a1,.L3
+	mv	a0,a2
+	ret
+.L3:
+	mv	a0,a3
+	ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibeq-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibeq-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bne	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibeq-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibeq-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bne	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibne-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibne-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	beq	a0,a1,.L3
+	mv	a0,a2
+	ret
+.L3:
+	mv	a0,a3
+	ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibne-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibne-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	beq	a0,a1,.L3
+	mv	a0,a2
+	ret
+.L3:
+	mv	a0,a3
+	ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 19/44] RISC-V/testsuite: Add branchless cases for equality cond-move operations
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (17 preceding siblings ...)
  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  5:39 ` 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
                   ` (25 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:39 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for Ventana and Zicond targets and the equality conditional-move 
operations, that if-conversion triggers via `noce_try_cmove' at the 
respective sufficiently high `-mbranch-cost=' settings that make 
branchless code sequences produced by if-conversion cheaper than their 
original branched equivalents, and that extraneous instructions such as 
SNEZ, etc. are not present in output.

	gcc/testsuite/
	* gcc.target/riscv/movdieq-ventana.c: New test.
	* gcc.target/riscv/movdieq-zicond.c: New test.
	* gcc.target/riscv/movdine-ventana.c: New test.
	* gcc.target/riscv/movdine-zicond.c: New test.
	* gcc.target/riscv/movsieq-ventana.c: New test.
	* gcc.target/riscv/movsieq-zicond.c: New test.
	* gcc.target/riscv/movsine-ventana.c: New test.
	* gcc.target/riscv/movsine-zicond.c: New test.
---
 gcc/testsuite/gcc.target/riscv/movdieq-ventana.c |   28 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdieq-zicond.c  |   28 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdine-ventana.c |   28 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdine-zicond.c  |   28 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsieq-ventana.c |   28 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsieq-zicond.c  |   28 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsine-ventana.c |   28 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsine-zicond.c  |   28 +++++++++++++++++++++++
 8 files changed, 224 insertions(+)

gcc-riscv-expand-conditional-move-zicond-equality-test-movcc.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/movdieq-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdieq-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sub	a1,a0,a1
+	vt.maskc	a3,a3,a1
+	vt.maskcn	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdieq-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdieq-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sub	a1,a0,a1
+	czero.eqz	a3,a3,a1
+	czero.nez	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdine-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdine-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sub	a1,a0,a1
+	vt.maskcn	a3,a3,a1
+	vt.maskc	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdine-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdine-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sub	a1,a0,a1
+	czero.nez	a3,a3,a1
+	czero.eqz	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsieq-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsieq-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sub	a1,a0,a1
+	vt.maskc	a3,a3,a1
+	vt.maskcn	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsieq-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsieq-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sub	a1,a0,a1
+	czero.eqz	a3,a3,a1
+	czero.nez	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsine-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsine-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sub	a1,a0,a1
+	vt.maskcn	a3,a3,a1
+	vt.maskc	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsine-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsine-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sub	a1,a0,a1
+	czero.nez	a3,a3,a1
+	czero.eqz	a1,a2,a1
+	or	a0,a1,a3
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 20/44] RISC-V: Also accept constants for T-Head cond-move comparison operands
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (18 preceding siblings ...)
  2023-11-19  5:39 ` [PATCH 19/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
@ 2023-11-19  5:39 ` 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
                   ` (24 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:39 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

There is no need for the requirement for conditional-move comparison 
operands to be stricter for T-Head targets than for other targets and 
limit them to registers only.  Constants will be reloaded if required 
just as with branches or other-target conditional-move operations and 
there is no extra overhead specific to the T-Head case.  This enables 
more opportunities for a branchless sequence to be produced.

	gcc/
	* config/riscv/riscv.cc (riscv_expand_conditional_move): Also 
	accept constants for T-Head comparison operands.
---
 gcc/config/riscv/riscv.cc |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

gcc-riscv-expand-conditional-move-thead-op.diff
Index: gcc/gcc/config/riscv/riscv.cc
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.cc
+++ gcc/gcc/config/riscv/riscv.cc
@@ -4097,8 +4097,8 @@ riscv_expand_conditional_move (rtx dest,
       && reg_or_0_operand (cons, mode)
       && reg_or_0_operand (alt, mode)
       && (GET_MODE (op) == mode || GET_MODE (op) == E_VOIDmode)
-      && GET_MODE (op0) == mode
-      && GET_MODE (op1) == mode
+      && (GET_MODE (op0) == mode || CONST_INT_P (op0))
+      && (GET_MODE (op1) == mode || CONST_INT_P (op1))
       && (code == EQ || code == NE))
     need_eq_ne_p = true;
 

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 21/44] RISC-V: Also accept constants for T-Head cond-move data input operands
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (19 preceding siblings ...)
  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  5:39 ` 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
                   ` (23 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:39 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

There is no need for the requirement for conditional-move data input 
operands to be stricter for T-Head targets than for short forward branch 
targets and limit them to registers only.  They are keyed according to 
the `sfb_alu_operand' predicate, which lets certain constants through.  
Such constants are already forced into a register for the `cons' operand 
in the analogous short forward branch case and we can force them for the 
`alt' operand and T-Head as well.  This enables more opportunities for a 
branchless sequence to be produced.

	gcc/
	* config/riscv/riscv.cc (riscv_expand_conditional_move): Also
        accept constants for T-Head data input operands.
---
 gcc/config/riscv/riscv.cc |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

gcc-riscv-expand-conditional-move-thead-alt.diff
Index: gcc/gcc/config/riscv/riscv.cc
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.cc
+++ gcc/gcc/config/riscv/riscv.cc
@@ -4094,8 +4094,6 @@ riscv_expand_conditional_move (rtx dest,
 
   if (TARGET_XTHEADCONDMOV
       && GET_MODE_CLASS (mode) == MODE_INT
-      && reg_or_0_operand (cons, mode)
-      && reg_or_0_operand (alt, mode)
       && (GET_MODE (op) == mode || GET_MODE (op) == E_VOIDmode)
       && (GET_MODE (op0) == mode || CONST_INT_P (op0))
       && (GET_MODE (op1) == mode || CONST_INT_P (op1))
@@ -4113,6 +4111,8 @@ riscv_expand_conditional_move (rtx dest,
 	 cases for extensions which are more general than SFB.  But
 	 does mean we need to force CONS into a register at this point.  */
       cons = force_reg (mode, cons);
+      /* With XTheadCondMov we need to force ALT into a register too.  */
+      alt = force_reg (mode, alt);
       emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (mode,
 							  cond, cons, alt)));
       return true;

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 22/44] RISC-V: Fold all the cond-move variants together
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (20 preceding siblings ...)
  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  5:40 ` 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
                   ` (22 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:40 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Code in `riscv_expand_conditional_move' for Ventana and Zicond targets 
seems like bolted on as an afterthought rather than properly merged so 
as to handle all the cases together.

Fold the existing code pieces together then (observing that for short 
forward branch targets no integer comparisons need to be canonicalized), 
letting T-Head targets produce branchless sequences for all the integer 
comparisons rather than for equality ones only, and preparing for the 
handling of floating-point comparisons here across all conditional-move 
targets.

	gcc/
	* config/riscv/riscv.cc (riscv_expand_conditional_move): Unify
	conditional-move handling across all the relevant targets.
---
 gcc/config/riscv/riscv.cc |   58 +++++++++++++++++++---------------------------
 1 file changed, 25 insertions(+), 33 deletions(-)

gcc-riscv-expand-conditional-move-sfb-alu-thead.diff
Index: gcc/gcc/config/riscv/riscv.cc
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.cc
+++ gcc/gcc/config/riscv/riscv.cc
@@ -4090,35 +4090,9 @@ riscv_expand_conditional_move (rtx dest,
   rtx_code code = GET_CODE (op);
   rtx op0 = XEXP (op, 0);
   rtx op1 = XEXP (op, 1);
-  bool need_eq_ne_p = false;
-
-  if (TARGET_XTHEADCONDMOV
-      && GET_MODE_CLASS (mode) == MODE_INT
-      && (GET_MODE (op) == mode || GET_MODE (op) == E_VOIDmode)
-      && (GET_MODE (op0) == mode || CONST_INT_P (op0))
-      && (GET_MODE (op1) == mode || CONST_INT_P (op1))
-      && (code == EQ || code == NE))
-    need_eq_ne_p = true;
-
-  if (need_eq_ne_p
-      || (TARGET_SFB_ALU && GET_MODE (op0) == word_mode))
-    {
-      riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p);
-      rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
 
-      /* The expander is a bit loose in its specification of the true
-	 arm of the conditional move.  That allows us to support more
-	 cases for extensions which are more general than SFB.  But
-	 does mean we need to force CONS into a register at this point.  */
-      cons = force_reg (mode, cons);
-      /* With XTheadCondMov we need to force ALT into a register too.  */
-      alt = force_reg (mode, alt);
-      emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (mode,
-							  cond, cons, alt)));
-      return true;
-    }
-  else if (TARGET_ZICOND_LIKE
-	   && GET_MODE_CLASS (mode) == MODE_INT)
+  if ((TARGET_ZICOND_LIKE && GET_MODE_CLASS (mode) == MODE_INT)
+      || TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
     {
       machine_mode mode0 = GET_MODE (op0);
       machine_mode mode1 = GET_MODE (op1);
@@ -4132,9 +4106,11 @@ riscv_expand_conditional_move (rtx dest,
 	return false;
 
       /* Canonicalize the comparison.  It must be an equality comparison
-	 of integer operands.  If it isn't, then emit an SCC instruction
+	 of integer operands, or with SFB it can be any comparison of
+	 integer operands.  If it isn't, then emit an SCC instruction
 	 so that we can then use an equality comparison against zero.  */
-      if (!equality_operator (op, VOIDmode) || !INTEGRAL_MODE_P (mode0))
+      if ((!TARGET_SFB_ALU && !equality_operator (op, VOIDmode))
+	  || !INTEGRAL_MODE_P (mode0))
 	{
 	  bool *invert_ptr = nullptr;
 	  bool invert = false;
@@ -4166,10 +4142,26 @@ riscv_expand_conditional_move (rtx dest,
 	  op1 = XEXP (op, 1);
 	}
 
+      if (TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
+	{
+	  riscv_emit_int_compare (&code, &op0, &op1, !TARGET_SFB_ALU);
+	  rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+
+	  /* The expander is a bit loose in its specification of the true
+	     arm of the conditional move.  That allows us to support more
+	     cases for extensions which are more general than SFB.  But
+	     does mean we need to force CONS into a register at this point.  */
+	  cons = force_reg (mode, cons);
+	  /* With XTheadCondMov we need to force ALT into a register too.  */
+	  alt = force_reg (mode, alt);
+	  emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (mode, cond,
+							      cons, alt)));
+	  return true;
+	}
       /* 0, reg or 0, imm */
-      if (cons == CONST0_RTX (mode)
-	  && (REG_P (alt)
-	      || (CONST_INT_P (alt) && alt != CONST0_RTX (mode))))
+      else if (cons == CONST0_RTX (mode)
+	       && (REG_P (alt)
+		   || (CONST_INT_P (alt) && alt != CONST0_RTX (mode))))
 	{
 	  riscv_emit_int_compare (&code, &op0, &op1, true);
 	  rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 23/44] RISC-V/testsuite: Add branched cases for T-Head non-equality cond moves
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (21 preceding siblings ...)
  2023-11-19  5:40 ` [PATCH 22/44] RISC-V: Fold all the cond-move variants together Maciej W. Rozycki
@ 2023-11-19  5:40 ` 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
                   ` (21 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:40 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for T-Head targets and the non-equality integer conditional-move 
operations, that if-conversion does *not* trigger at `-mbranch-cost=1' 
setting, which makes original branched code sequences cheaper than their 
branchless equivalents if-conversion would emit.

	gcc/testsuite/
	* gcc.target/riscv/movdibge-thead.c: New test.
	* gcc.target/riscv/movdibgeu-thead.c: New test.
	* gcc.target/riscv/movdibgt-thead.c: New test.
	* gcc.target/riscv/movdibgtu-thead.c: New test.
	* gcc.target/riscv/movdible-thead.c: New test.
	* gcc.target/riscv/movdibleu-thead.c: New test.
	* gcc.target/riscv/movdiblt-thead.c: New test.
	* gcc.target/riscv/movdibltu-thead.c: New test.
	* gcc.target/riscv/movsibge-thead.c: New test.
	* gcc.target/riscv/movsibgeu-thead.c: New test.
	* gcc.target/riscv/movsibgt-thead.c: New test.
	* gcc.target/riscv/movsibgtu-thead.c: New test.
	* gcc.target/riscv/movsible-thead.c: New test.
	* gcc.target/riscv/movsibleu-thead.c: New test.
	* gcc.target/riscv/movsiblt-thead.c: New test.
	* gcc.target/riscv/movsibltu-thead.c: New test.
---
 gcc/testsuite/gcc.target/riscv/movdibge-thead.c  |   27 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibgeu-thead.c |   27 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibgt-thead.c  |   27 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibgtu-thead.c |   27 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdible-thead.c  |   27 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibleu-thead.c |   27 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdiblt-thead.c  |   27 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibltu-thead.c |   27 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibge-thead.c  |   27 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibgeu-thead.c |   27 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibgt-thead.c  |   27 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibgtu-thead.c |   27 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsible-thead.c  |   27 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibleu-thead.c |   27 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsiblt-thead.c  |   27 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibltu-thead.c |   27 +++++++++++++++++++++++
 16 files changed, 432 insertions(+)

gcc-riscv-expand-conditional-move-sfb-alu-thead-test-movcc-branch.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibge-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibge-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	blt	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibgeu-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibgeu-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bltu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibgt-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibgt-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	ble	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibgtu-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibgtu-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bleu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdible-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdible-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgt	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibleu-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibleu-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgtu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiblt-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiblt-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bge	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibltu-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibltu-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgeu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibge-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibge-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	blt	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibgeu-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibgeu-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bltu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibgt-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibgt-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	ble	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibgtu-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibgtu-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bleu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsible-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsible-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgt	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibleu-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibleu-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgtu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiblt-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiblt-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bge	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibltu-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibltu-thead.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgeu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 24/44] RISC-V/testsuite: Add branchless cases for T-Head non-equality cond moves
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (22 preceding siblings ...)
  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  5:40 ` 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
                   ` (20 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:40 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for T-Head targets and the non-equality integer conditional-move 
operations, that if-conversion triggers via `noce_try_cmove' at 
`-mbranch-cost=2' setting, which makes branchless code sequences 
produced by if-conversion cheaper than their original branched 
equivalents, and that extraneous instructions such as SNEZ, etc. are not 
present in output.

	gcc/testsuite/
	* gcc.target/riscv/movdige-thead.c: New test.
	* gcc.target/riscv/movdigeu-thead.c: New test.
	* gcc.target/riscv/movdigt-thead.c: New test.
	* gcc.target/riscv/movdigtu-thead.c: New test.
	* gcc.target/riscv/movdile-thead.c: New test.
	* gcc.target/riscv/movdileu-thead.c: New test.
	* gcc.target/riscv/movdilt-thead.c: New test.
	* gcc.target/riscv/movdiltu-thead.c: New test.
	* gcc.target/riscv/movsige-thead.c: New test.
	* gcc.target/riscv/movsigeu-thead.c: New test.
	* gcc.target/riscv/movsigt-thead.c: New test.
	* gcc.target/riscv/movsigtu-thead.c: New test.
	* gcc.target/riscv/movsile-thead.c: New test.
	* gcc.target/riscv/movsileu-thead.c: New test.
	* gcc.target/riscv/movsilt-thead.c: New test.
	* gcc.target/riscv/movsiltu-thead.c: New test.
---
 gcc/testsuite/gcc.target/riscv/movdige-thead.c  |   26 ++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdigeu-thead.c |   26 ++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdigt-thead.c  |   26 ++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdigtu-thead.c |   26 ++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdile-thead.c  |   26 ++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdileu-thead.c |   26 ++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdilt-thead.c  |   26 ++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdiltu-thead.c |   26 ++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsige-thead.c  |   26 ++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsigeu-thead.c |   26 ++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsigt-thead.c  |   26 ++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsigtu-thead.c |   26 ++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsile-thead.c  |   26 ++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsileu-thead.c |   26 ++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsilt-thead.c  |   26 ++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsiltu-thead.c |   26 ++++++++++++++++++++++++
 16 files changed, 416 insertions(+)

gcc-riscv-expand-conditional-move-sfb-alu-thead-test-movcc.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/movdige-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdige-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a0,a0,a1
+	th.mvnez	a2,a3,a0
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdigeu-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdigeu-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a0,a0,a1
+	th.mvnez	a2,a3,a0
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdigt-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdigt-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a0,a0,a1
+	th.mveqz	a2,a3,a0
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdigtu-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdigtu-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a0,a0,a1
+	th.mveqz	a2,a3,a0
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdile-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdile-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a0,a0,a1
+	th.mvnez	a2,a3,a0
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdileu-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdileu-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a0,a0,a1
+	th.mvnez	a2,a3,a0
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdilt-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdilt-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a0,a0,a1
+	th.mveqz	a2,a3,a0
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiltu-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiltu-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a0,a0,a1
+	th.mveqz	a2,a3,a0
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsige-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsige-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a0,a0,a1
+	th.mvnez	a2,a3,a0
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsigeu-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsigeu-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a0,a0,a1
+	th.mvnez	a2,a3,a0
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsigt-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsigt-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a0,a0,a1
+	th.mveqz	a2,a3,a0
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsigtu-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsigtu-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a0,a0,a1
+	th.mveqz	a2,a3,a0
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsile-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsile-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a0,a0,a1
+	th.mvnez	a2,a3,a0
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsileu-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsileu-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a0,a0,a1
+	th.mvnez	a2,a3,a0
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsilt-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsilt-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a0,a0,a1
+	th.mveqz	a2,a3,a0
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiltu-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiltu-thead.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a0,a0,a1
+	th.mveqz	a2,a3,a0
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 25/44] RISC-V: Implement `riscv_emit_unary' helper
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (23 preceding siblings ...)
  2023-11-19  5:40 ` [PATCH 24/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
@ 2023-11-19  5:40 ` Maciej W. Rozycki
  2023-11-19 17:54   ` Jeff Law
  2023-11-19  5:40 ` [PATCH 26/44] RISC-V: Add `movMODEcc' implementation for generic targets Maciej W. Rozycki
                   ` (19 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:40 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Add a `riscv_emit_unary' helper for unary operations, complementing 
`riscv_emit_binary'.

	gcc/
	* config/riscv/riscv-protos.h (riscv_emit_unary): New prototype.
	* config/riscv/riscv.cc (riscv_emit_unary): New function.
---
 gcc/config/riscv/riscv-protos.h |    1 +
 gcc/config/riscv/riscv.cc       |    8 ++++++++
 2 files changed, 9 insertions(+)

gcc-riscv-emit-unary.diff
Index: gcc/gcc/config/riscv/riscv-protos.h
===================================================================
--- gcc.orig/gcc/config/riscv/riscv-protos.h
+++ gcc/gcc/config/riscv/riscv-protos.h
@@ -134,6 +134,7 @@ riscv_zcmp_valid_stack_adj_bytes_p (HOST
 extern void riscv_expand_int_scc (rtx, enum rtx_code, rtx, rtx, bool *invert_ptr = 0);
 extern void riscv_expand_float_scc (rtx, enum rtx_code, rtx, rtx);
 extern void riscv_expand_conditional_branch (rtx, enum rtx_code, rtx, rtx);
+extern rtx riscv_emit_unary (enum rtx_code code, rtx dest, rtx x);
 extern rtx riscv_emit_binary (enum rtx_code code, rtx dest, rtx x, rtx y);
 #endif
 extern bool riscv_expand_conditional_move (rtx, rtx, rtx, rtx);
Index: gcc/gcc/config/riscv/riscv.cc
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.cc
+++ gcc/gcc/config/riscv/riscv.cc
@@ -1703,6 +1703,14 @@ riscv_emit_set (rtx target, rtx src)
   return target;
 }
 
+/* Emit an instruction of the form (set DEST (CODE X)).  */
+
+rtx
+riscv_emit_unary (enum rtx_code code, rtx dest, rtx x)
+{
+  return riscv_emit_set (dest, gen_rtx_fmt_e (code, GET_MODE (dest), x));
+}
+
 /* Emit an instruction of the form (set DEST (CODE X Y)).  */
 
 rtx

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 26/44] RISC-V: Add `movMODEcc' implementation for generic targets
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (24 preceding siblings ...)
  2023-11-19  5:40 ` [PATCH 25/44] RISC-V: Implement `riscv_emit_unary' helper Maciej W. Rozycki
@ 2023-11-19  5:40 ` Maciej W. Rozycki
  2023-11-19 18:18   ` Jeff Law
  2023-11-19  5:40 ` [PATCH 27/44] RISC-V/testsuite: Add branched cases for generic integer cond moves Maciej W. Rozycki
                   ` (18 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:40 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

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} } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 27/44] RISC-V/testsuite: Add branched cases for generic integer cond moves
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (25 preceding siblings ...)
  2023-11-19  5:40 ` [PATCH 26/44] RISC-V: Add `movMODEcc' implementation for generic targets Maciej W. Rozycki
@ 2023-11-19  5:40 ` 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
                   ` (17 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:40 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for generic integer conditional-move operations, if-conversion 
*not* to trigger at the respective sufficiently low `-mbranch-cost=' 
settings that make original branched code sequences cheaper than their 
branchless equivalents if-conversion would emit.  Cover all integer 
relational operations to make sure no corner case escapes.

	gcc/testsuite/
	* gcc.target/riscv/movdibeq.c: New test.
	* gcc.target/riscv/movdibge.c: New test.
	* gcc.target/riscv/movdibgeu.c: New test.
	* gcc.target/riscv/movdibgt.c: New test.
	* gcc.target/riscv/movdibgtu.c: New test.
	* gcc.target/riscv/movdible.c: New test.
	* gcc.target/riscv/movdibleu.c: New test.
	* gcc.target/riscv/movdiblt.c: New test.
	* gcc.target/riscv/movdibltu.c: New test.
	* gcc.target/riscv/movdibne.c: New test.
	* gcc.target/riscv/movsibeq.c: New test.
	* gcc.target/riscv/movsibge.c: New test.
	* gcc.target/riscv/movsibgeu.c: New test.
	* gcc.target/riscv/movsibgt.c: New test.
	* gcc.target/riscv/movsibgtu.c: New test.
	* gcc.target/riscv/movsible.c: New test.
	* gcc.target/riscv/movsibleu.c: New test.
	* gcc.target/riscv/movsiblt.c: New test.
	* gcc.target/riscv/movsibltu.c: New test.
	* gcc.target/riscv/movsibne.c: New test.
---
 gcc/testsuite/gcc.target/riscv/movdibeq.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibge.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibgeu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibgt.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibgtu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdible.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibleu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdiblt.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibltu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibne.c  |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibeq.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibge.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibgeu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibgt.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibgtu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsible.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibleu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsiblt.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibltu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibne.c  |   28 ++++++++++++++++++++++++++++
 20 files changed, 524 insertions(+)

gcc-riscv-test-movcc-branch-generic.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibeq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibeq.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bne	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibge.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibge.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	blt	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibgeu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibgeu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bltu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibgt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibgt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	ble	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibgtu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibgtu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bleu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdible.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdible.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgt	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibleu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibleu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgtu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiblt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiblt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bge	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibltu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibltu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgeu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibne.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibne.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	beq	a0,a1,.L3
+	mv	a0,a2
+	ret
+.L3:
+	mv	a0,a3
+	ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibeq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibeq.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bne	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibge.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibge.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	blt	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibgeu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibgeu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bltu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibgt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibgt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	ble	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibgtu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibgtu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bleu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsible.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsible.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgt	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibleu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibleu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgtu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiblt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiblt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bge	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibltu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibltu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	bgeu	a0,a1,.L2
+	mv	a3,a2
+.L2:
+	mv	a0,a3
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibne.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibne.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	beq	a0,a1,.L3
+	mv	a0,a2
+	ret
+.L3:
+	mv	a0,a3
+	ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 28/44] RISC-V/testsuite: Add branchless cases for generic integer cond moves
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (26 preceding siblings ...)
  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  5:41 ` 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
                   ` (16 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:41 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for generic integer conditional-move operations, if-conversion 
to trigger via `noce_try_cmove' at the respective sufficiently high 
`-mbranch-cost=' settings that make branchless code sequences produced 
by if-conversion cheaper than their original branched equivalents, and, 
where applicable, that extraneous instructions such as SNEZ, etc. are 
not present in output.  Cover all integer relational operations to make 
sure no corner case escapes.

	gcc/testsuite/
	* gcc.target/riscv/movdieq.c: New test.
	* gcc.target/riscv/movdige.c: New test.
	* gcc.target/riscv/movdigeu.c: New test.
	* gcc.target/riscv/movdigt.c: New test.
	* gcc.target/riscv/movdigtu.c: New test.
	* gcc.target/riscv/movdile.c: New test.
	* gcc.target/riscv/movdileu.c: New test.
	* gcc.target/riscv/movdilt.c: New test.
	* gcc.target/riscv/movdiltu.c: New test.
	* gcc.target/riscv/movdine.c: New test.
	* gcc.target/riscv/movsieq.c: New test.
	* gcc.target/riscv/movsige.c: New test.
	* gcc.target/riscv/movsigeu.c: New test.
	* gcc.target/riscv/movsigt.c: New test.
	* gcc.target/riscv/movsigtu.c: New test.
	* gcc.target/riscv/movsile.c: New test.
	* gcc.target/riscv/movsileu.c: New test.
	* gcc.target/riscv/movsilt.c: New test.
	* gcc.target/riscv/movsiltu.c: New test.
	* gcc.target/riscv/movsine.c: New test.
---
 gcc/testsuite/gcc.target/riscv/movdieq.c  |   29 +++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdige.c  |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdigeu.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdigt.c  |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdigtu.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdile.c  |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdileu.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdilt.c  |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdiltu.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdine.c  |   29 +++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsieq.c  |   29 +++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsige.c  |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsigeu.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsigt.c  |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsigtu.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsile.c  |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsileu.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsilt.c  |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsiltu.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsine.c  |   29 +++++++++++++++++++++++++++++
 20 files changed, 564 insertions(+)

gcc-riscv-test-movcc-generic.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/movdieq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdieq.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=7 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sub	a5,a0,a1
+	snez	a5,a5
+	neg	a5,a5
+	and	a3,a5,a3
+	not	a5,a5
+	and	a5,a5,a2
+	or	a0,a3,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:seqz|snez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdige.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdige.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a1,a0,a1
+	neg	a1,a1
+	and	a3,a1,a3
+	not	a1,a1
+	and	a1,a1,a2
+	or	a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdigeu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdigeu.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a1,a0,a1
+	neg	a1,a1
+	and	a3,a1,a3
+	not	a1,a1
+	and	a1,a1,a2
+	or	a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdigt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdigt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a1,a0,a1
+	neg	a1,a1
+	and	a3,a1,a3
+	not	a1,a1
+	and	a1,a1,a2
+	or	a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdigtu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdigtu.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a1,a0,a1
+	neg	a1,a1
+	and	a3,a1,a3
+	not	a1,a1
+	and	a1,a1,a2
+	or	a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdile.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdile.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a1,a0,a1
+	neg	a1,a1
+	and	a3,a1,a3
+	not	a1,a1
+	and	a1,a1,a2
+	or	a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdileu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdileu.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a1,a0,a1
+	neg	a1,a1
+	and	a3,a1,a3
+	not	a1,a1
+	and	a1,a1,a2
+	or	a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdilt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdilt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a1,a0,a1
+	neg	a1,a1
+	and	a3,a1,a3
+	not	a1,a1
+	and	a1,a1,a2
+	or	a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiltu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiltu.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a1,a0,a1
+	neg	a1,a1
+	and	a3,a1,a3
+	not	a1,a1
+	and	a1,a1,a2
+	or	a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdine.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdine.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sub	a5,a0,a1
+	seqz	a5,a5
+	neg	a5,a5
+	and	a3,a5,a3
+	not	a5,a5
+	and	a5,a5,a2
+	or	a0,a3,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:seqz|snez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsieq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsieq.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=7 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=7 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sub	a5,a0,a1
+	snez	a5,a5
+	neg	a5,a5
+	and	a3,a5,a3
+	not	a5,a5
+	and	a5,a5,a2
+	or	a0,a3,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:seqz|snez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsige.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsige.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a1,a0,a1
+	neg	a1,a1
+	and	a3,a1,a3
+	not	a1,a1
+	and	a1,a1,a2
+	or	a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsigeu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsigeu.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a1,a0,a1
+	neg	a1,a1
+	and	a3,a1,a3
+	not	a1,a1
+	and	a1,a1,a2
+	or	a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsigt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsigt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a1,a0,a1
+	neg	a1,a1
+	and	a3,a1,a3
+	not	a1,a1
+	and	a1,a1,a2
+	or	a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsigtu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsigtu.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a1,a0,a1
+	neg	a1,a1
+	and	a3,a1,a3
+	not	a1,a1
+	and	a1,a1,a2
+	or	a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsile.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsile.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a1,a0,a1
+	neg	a1,a1
+	and	a3,a1,a3
+	not	a1,a1
+	and	a1,a1,a2
+	or	a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsileu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsileu.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a1,a0,a1
+	neg	a1,a1
+	and	a3,a1,a3
+	not	a1,a1
+	and	a1,a1,a2
+	or	a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsilt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsilt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a1,a0,a1
+	neg	a1,a1
+	and	a3,a1,a3
+	not	a1,a1
+	and	a1,a1,a2
+	or	a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiltu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiltu.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a1,a0,a1
+	neg	a1,a1
+	and	a3,a1,a3
+	not	a1,a1
+	and	a1,a1,a2
+	or	a0,a3,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsine.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsine.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	sub	a5,a0,a1
+	seqz	a5,a5
+	neg	a5,a5
+	and	a3,a5,a3
+	not	a5,a5
+	and	a5,a5,a2
+	or	a0,a3,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:seqz|snez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 29/44] RISC-V: Add `addMODEcc' implementation for generic targets
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (27 preceding siblings ...)
  2023-11-19  5:41 ` [PATCH 28/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
@ 2023-11-19  5:41 ` Maciej W. Rozycki
  2023-11-19 18:23   ` Jeff Law
  2023-11-19  5:41 ` [PATCH 30/44] RISC-V/testsuite: Add branched cases for generic integer cond adds Maciej W. Rozycki
                   ` (15 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:41 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

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(+)

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"

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 30/44] RISC-V/testsuite: Add branched cases for generic integer cond adds
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (28 preceding siblings ...)
  2023-11-19  5:41 ` [PATCH 29/44] RISC-V: Add `addMODEcc' implementation for generic targets Maciej W. Rozycki
@ 2023-11-19  5:41 ` 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
                   ` (14 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:41 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for generic integer conditional-add operations, if-conversion 
*not* to trigger at the respective sufficiently low `-mbranch-cost=' 
settings that make original branched code sequences cheaper than their 
branchless equivalents if-conversion would emit.  Cover all integer 
relational operations to make sure no corner case escapes.
	
gcc/testsuite/
	* gcc.target/riscv/adddibeq.c: New test.
	* gcc.target/riscv/adddibge.c: New test.
	* gcc.target/riscv/adddibgeu.c: New test.
	* gcc.target/riscv/adddibgt.c: New test.
	* gcc.target/riscv/adddibgtu.c: New test.
	* gcc.target/riscv/adddible.c: New test.
	* gcc.target/riscv/adddibleu.c: New test.
	* gcc.target/riscv/adddiblt.c: New test.
	* gcc.target/riscv/adddibltu.c: New test.
	* gcc.target/riscv/adddibne.c: New test.
	* gcc.target/riscv/addsibeq.c: New test.
	* gcc.target/riscv/addsibge.c: New test.
	* gcc.target/riscv/addsibgeu.c: New test.
	* gcc.target/riscv/addsibgt.c: New test.
	* gcc.target/riscv/addsibgtu.c: New test.
	* gcc.target/riscv/addsible.c: New test.
	* gcc.target/riscv/addsibleu.c: New test.
	* gcc.target/riscv/addsiblt.c: New test.
	* gcc.target/riscv/addsibltu.c: New test.
	* gcc.target/riscv/addsibne.c: New test.
---
 gcc/testsuite/gcc.target/riscv/adddibeq.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddibge.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddibgeu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddibgt.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddibgtu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddible.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddibleu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddiblt.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddibltu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddibne.c  |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsibeq.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsibge.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsibgeu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsibgt.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsibgtu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsible.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsibleu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsiblt.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsibltu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsibne.c  |   28 ++++++++++++++++++++++++++++
 20 files changed, 524 insertions(+)

gcc-riscv-test-addcc-branch-generic.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/adddibeq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddibeq.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	bne	a0,a1,.L2
+	add	a2,a2,a3
+.L2:
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddibge.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddibge.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	blt	a0,a1,.L2
+	add	a2,a2,a3
+.L2:
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddibgeu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddibgeu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	bltu	a0,a1,.L2
+	add	a2,a2,a3
+.L2:
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddibgt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddibgt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	ble	a0,a1,.L2
+	add	a2,a2,a3
+.L2:
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddibgtu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddibgtu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	bleu	a0,a1,.L2
+	add	a2,a2,a3
+.L2:
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddible.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddible.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	bgt	a0,a1,.L2
+	add	a2,a2,a3
+.L2:
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddibleu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddibleu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	bgtu	a0,a1,.L2
+	add	a2,a2,a3
+.L2:
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddiblt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddiblt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	bge	a0,a1,.L2
+	add	a2,a2,a3
+.L2:
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddibltu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddibltu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	bgeu	a0,a1,.L2
+	add	a2,a2,a3
+.L2:
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddibne.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddibne.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	beq	a0,a1,.L3
+	add	a0,a2,a3
+	ret
+.L3:
+	mv	a0,a2
+	ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsibeq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsibeq.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	bne	a0,a1,.L2
+	addw	a2,a2,a3
+.L2:
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sub|subw)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsibge.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsibge.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	blt	a0,a1,.L2
+	add[w]	a2,a2,a3
+.L2:
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsibgeu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsibgeu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	bltu	a0,a1,.L2
+	add[w]	a2,a2,a3
+.L2:
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsibgt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsibgt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	ble	a0,a1,.L2
+	add[w]	a2,a2,a3
+.L2:
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsibgtu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsibgtu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	bleu	a0,a1,.L2
+	add[w]	a2,a2,a3
+.L2:
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsible.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsible.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	bgt	a0,a1,.L2
+	add[w]	a2,a2,a3
+.L2:
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsibleu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsibleu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	bgtu	a0,a1,.L2
+	add[w]	a2,a2,a3
+.L2:
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsiblt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsiblt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	bge	a0,a1,.L2
+	add[w]	a2,a2,a3
+.L2:
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsibltu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsibltu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	bgeu	a0,a1,.L2
+	add[w]	a2,a2,a3
+.L2:
+	mv	a0,a2
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsibne.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsibne.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	beq	a0,a1,.L3
+	add[w]	a0,a2,a3
+	ret
+.L3:
+	mv	a0,a2
+	ret
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:sub|subw)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 31/44] RISC-V/testsuite: Add branchless cases for generic integer cond adds
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (29 preceding siblings ...)
  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  5:41 ` Maciej W. Rozycki
  2023-11-19 18:25   ` Jeff Law
  2023-11-19  5:42 ` [PATCH 32/44] RISC-V: Only use SUBREG if applicable in `riscv_expand_float_scc' Maciej W. Rozycki
                   ` (13 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:41 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for generic integer conditional-add operations, if-conversion
to trigger via `noce_try_addcc' at the respective sufficiently high
`-mbranch-cost=' settings that make branchless code sequences produced
by if-conversion cheaper than their original branched equivalents, and,
where applicable, that extraneous instructions such as SNEZ, etc. are
not present in output.  Cover all integer relational operations to make
sure no corner case escapes.

The reason to XFAIL SImode tests for RV64 targets is the compiler thinks 
it has to sign-extend addends, which causes if-conversion to give up.

	gcc/testsuite/
	* gcc.target/riscv/adddieq.c: New test.
	* gcc.target/riscv/adddige.c: New test.
	* gcc.target/riscv/adddigeu.c: New test.
	* gcc.target/riscv/adddigt.c: New test.
	* gcc.target/riscv/adddigtu.c: New test.
	* gcc.target/riscv/adddile.c: New test.
	* gcc.target/riscv/adddileu.c: New test.
	* gcc.target/riscv/adddilt.c: New test.
	* gcc.target/riscv/adddiltu.c: New test.
	* gcc.target/riscv/adddine.c: New test.
	* gcc.target/riscv/addsieq.c: New test.
	* gcc.target/riscv/addsige.c: New test.
	* gcc.target/riscv/addsigeu.c: New test.
	* gcc.target/riscv/addsigt.c: New test.
	* gcc.target/riscv/addsigtu.c: New test.
	* gcc.target/riscv/addsile.c: New test.
	* gcc.target/riscv/addsileu.c: New test.
	* gcc.target/riscv/addsilt.c: New test.
	* gcc.target/riscv/addsiltu.c: New test.
	* gcc.target/riscv/addsine.c: New test.
---
 gcc/testsuite/gcc.target/riscv/adddieq.c  |   27 +++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddige.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddigeu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddigt.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddigtu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddile.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddileu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddilt.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddiltu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddine.c  |   27 +++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsieq.c  |   27 +++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsige.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsigeu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsigt.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsigtu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsile.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsileu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsilt.c  |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsiltu.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsine.c  |   27 +++++++++++++++++++++++++++
 20 files changed, 524 insertions(+)

gcc-riscv-test-addcc-generic.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/adddieq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddieq.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	sub	a1,a0,a1
+	seqz	a1,a1
+	neg	a1,a1
+	and	a1,a1,a3
+	add	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:seqz|snez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddige.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddige.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a1,a0,a1
+	addi	a1,a1,-1
+	and	a1,a1,a3
+	add	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddigeu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddigeu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a1,a0,a1
+	addi	a1,a1,-1
+	and	a1,a1,a3
+	add	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddigt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddigt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a1,a0,a1
+	neg	a1,a1
+	and	a1,a1,a3
+	add	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddigtu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddigtu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a1,a0,a1
+	neg	a1,a1
+	and	a1,a1,a3
+	add	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddile.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddile.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a1,a0,a1
+	addi	a1,a1,-1
+	and	a1,a1,a3
+	add	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddileu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddileu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a1,a0,a1
+	addi	a1,a1,-1
+	and	a1,a1,a3
+	add	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddilt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddilt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a1,a0,a1
+	neg	a1,a1
+	and	a1,a1,a3
+	add	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddiltu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddiltu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef unsigned int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a1,a0,a1
+	neg	a1,a1
+	and	a1,a1,a3
+	add	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddine.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddine.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	sub	a1,a0,a1
+	snez	a1,a1
+	neg	a1,a1
+	and	a1,a1,a3
+	add	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:seqz|snez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsieq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsieq.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsieq (int_t w, int_t x, int_t y, int_t z)
+{
+  return w == x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	sub[w]	a1,a0,a1
+	seqz	a1,a1
+	neg[w]	a1,a1
+	and	a1,a1,a3
+	add[w]	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sub|subw)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:seqz|snez)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail rv64 } } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsige.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsige.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsige (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a1,a0,a1
+	addi[w]	a1,a1,-1
+	and	a1,a1,a3
+	add[w]	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" { xfail rv64 } } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsigeu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsigeu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsigeu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w >= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a1,a0,a1
+	addi[w]	a1,a1,-1
+	and	a1,a1,a3
+	add[w]	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" { xfail rv64 } } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsigt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsigt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsigt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a1,a0,a1
+	neg[w]	a1,a1
+	and	a1,a1,a3
+	add[w]	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" { xfail rv64 } } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsigtu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsigtu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsigtu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w > x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a1,a0,a1
+	neg[w]	a1,a1
+	and	a1,a1,a3
+	add[w]	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" { xfail rv64 } } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsile.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsile.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsile (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	sgt	a1,a0,a1
+	addi[w]	a1,a1,-1
+	and	a1,a1,a3
+	add[w]	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" { xfail rv64 } } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsileu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsileu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsileu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w <= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	sgtu	a1,a0,a1
+	addi[w]	a1,a1,-1
+	and	a1,a1,a3
+	add[w]	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" { xfail rv64 } } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsilt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsilt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsilt (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	slt	a1,a0,a1
+	neg[w]	a1,a1
+	and	a1,a1,a3
+	add[w]	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" { xfail rv64 } } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsiltu.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsiltu.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsiltu (int_t w, int_t x, int_t y, int_t z)
+{
+  return w < x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	sltu	a1,a0,a1
+	neg[w]	a1,a1
+	and	a1,a1,a3
+	add[w]	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" { xfail rv64 } } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsine.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsine.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsine (int_t w, int_t x, int_t y, int_t z)
+{
+  return w != x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	sub[w]	a1,a0,a1
+	snez	a1,a1
+	neg[w]	a1,a1
+	and	a1,a1,a3
+	add[w]	a0,a1,a2
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:sub|subw)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:seqz|snez)\\s" 1 { xfail rv64 } } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail rv64 } } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 32/44] RISC-V: Only use SUBREG if applicable in `riscv_expand_float_scc'
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (30 preceding siblings ...)
  2023-11-19  5:41 ` [PATCH 31/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
@ 2023-11-19  5:42 ` 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
                   ` (12 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:42 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

A subsequent change to enable the processing of conditional moves on a 
floating-point condition by `riscv_expand_conditional_move' will cause 
`riscv_expand_float_scc' to be called for word-mode target RTX with RV64 
targets.  In that case an invalid insn such as:

(insn 25 24 0 (set (reg:DI 141)
        (subreg:SI (reg:DI 143) 0)) -1
     (nil))

would be produced, which would crash the compiler later on.  Since the 
output operand of the SET operation to be produced already has the same 
mode as the input operand does, just omit the use of SUBREG and assign 
directly.

	gcc/
	* config/riscv/riscv.cc (riscv_expand_float_scc): Suppress the 
	use of SUBREG if the conditional-set target is word-mode.
---
 gcc/config/riscv/riscv.cc |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

gcc-riscv-expand-float-scc-subreg.diff
Index: gcc/gcc/config/riscv/riscv.cc
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.cc
+++ gcc/gcc/config/riscv/riscv.cc
@@ -4071,7 +4071,9 @@ riscv_expand_float_scc (rtx target, enum
   riscv_emit_float_compare (&code, &op0, &op1);
 
   rtx cmp = riscv_force_binary (word_mode, code, op0, op1);
-  riscv_emit_set (target, lowpart_subreg (SImode, cmp, word_mode));
+  if (GET_MODE (target) != word_mode)
+    cmp = lowpart_subreg (GET_MODE (target), cmp, word_mode);
+  riscv_emit_set (target, cmp);
 }
 
 /* Jump to LABEL if (CODE OP0 OP1) holds.  */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 33/44] RISC-V: Also allow FP conditions in `riscv_expand_conditional_move'
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (31 preceding siblings ...)
  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  5:42 ` Maciej W. Rozycki
  2023-11-19 18:30   ` Jeff Law
  2023-11-19  5:42 ` [PATCH 34/44] RISC-V: Provide FP conditional-branch instructions for if-conversion Maciej W. Rozycki
                   ` (11 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:42 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

In `riscv_expand_conditional_move' we only let integer conditions 
through at the moment, even though code has already been prepared to 
handle floating-point conditions as well.

Lift this restriction and only bail out if a non-word-mode integer 
condition has been requested, as we cannot handle this specific case 
owing to machine instruction set restriction.  We already take care of 
the non-integer, non-floating-point case later on.

	gcc/
	* config/riscv/riscv.cc (riscv_expand_conditional_move): Don't 
	bail out in floating-point conditions.
---
 gcc/config/riscv/riscv.cc |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

gcc-riscv-expand-conditional-move-fp.diff
Index: gcc/gcc/config/riscv/riscv.cc
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.cc
+++ gcc/gcc/config/riscv/riscv.cc
@@ -4109,12 +4109,12 @@ riscv_expand_conditional_move (rtx dest,
       machine_mode mode0 = GET_MODE (op0);
       machine_mode mode1 = GET_MODE (op1);
 
-      /* The comparison must be comparing WORD_MODE objects.   We must
-	 enforce that so that we don't strip away a sign_extension
+      /* An integer comparison must be comparing WORD_MODE objects.  We
+	 must enforce that so that we don't strip away a sign_extension
 	 thinking it is unnecessary.  We might consider using
 	 riscv_extend_operands if they are not already properly extended.  */
-      if ((mode0 != word_mode && mode0 != VOIDmode)
-	  || (mode1 != word_mode && mode1 != VOIDmode))
+      if ((INTEGRAL_MODE_P (mode0) && mode0 != word_mode)
+	  || (INTEGRAL_MODE_P (mode1) && mode1 != word_mode))
 	return false;
 
       /* In the fallback generic case use MODE rather than WORD_MODE for

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 34/44] RISC-V: Provide FP conditional-branch instructions for if-conversion
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (32 preceding siblings ...)
  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  5:42 ` Maciej W. Rozycki
  2023-11-19 19:42   ` Jeff Law
  2023-11-19  5:42 ` [PATCH 35/44] RISC-V: Avoid extraneous integer comparison for FP comparisons Maciej W. Rozycki
                   ` (10 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:42 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Do not expand floating-point conditional-branch RTL instructions right 
away that use a comparison operation that is either directly available 
as a machine conditional-set instruction or is NE, which can be emulated 
by EQ.  This is so that if-conversion sees them in their original form 
and can produce fewer operations tried in a branchless code sequence 
compared to when such an instruction has been already converted to a 
sequence of a floating-point conditional-set RTL instruction followed by 
an integer conditional-branch RTL instruction.  Split any floating-point 
conditional-branch RTL instructions still remaining after reload then.

Adjust the testsuite accordingly: since the middle end uses the inverse 
condition internally, an inverse conditional-set instruction may make it 
to assembly output and also `cond_move_process_if_block' will be used by 
if-conversion rather than `noce_process_if_block', because the latter 
function not yet been updated to handle inverted conditions.

	gcc/
	* config/riscv/predicates.md (ne_operator): New predicate.
	* config/riscv/riscv.cc (riscv_insn_cost): Handle branches on a 
	floating-point condition.
	* config/riscv/riscv.md (@cbranch<mode>4): Rename expander to...
	(@cbranch<ANYF:mode>4): ... this.  Only expand the RTX via 
	`riscv_expand_conditional_branch' for `!signed_order_operator' 
	operators, otherwise let it through.
	(*cbranch<ANYF:mode>4, *cbranch<ANYF:mode>4): New insns and 
	splitters.

	gcc/testsuite/
	* gcc.target/riscv/movdifge-sfb.c: Reject "if-conversion 
	succeeded through" rather than accepting it.
	* gcc.target/riscv/movdifge-thead.c: Likewise.
	* gcc.target/riscv/movdifge-ventana.c: Likewise.
	* gcc.target/riscv/movdifge-zicond.c: Likewise.
	* gcc.target/riscv/movdifgt-sfb.c: Likewise.
	* gcc.target/riscv/movdifgt-thead.c: Likewise.
	* gcc.target/riscv/movdifgt-ventana.c: Likewise.
	* gcc.target/riscv/movdifgt-zicond.c: Likewise.
	* gcc.target/riscv/movdifle-sfb.c: Likewise.
	* gcc.target/riscv/movdifle-thead.c: Likewise.
	* gcc.target/riscv/movdifle-ventana.c: Likewise.
	* gcc.target/riscv/movdifle-zicond.c: Likewise.
	* gcc.target/riscv/movdiflt-sfb.c: Likewise.
	* gcc.target/riscv/movdiflt-thead.c: Likewise.
	* gcc.target/riscv/movdiflt-ventana.c: Likewise.
	* gcc.target/riscv/movdiflt-zicond.c: Likewise.
	* gcc.target/riscv/movsifge-sfb.c: Likewise.
	* gcc.target/riscv/movsifge-thead.c: Likewise.
	* gcc.target/riscv/movsifge-ventana.c: Likewise.
	* gcc.target/riscv/movsifge-zicond.c: Likewise.
	* gcc.target/riscv/movsifgt-sfb.c: Likewise.
	* gcc.target/riscv/movsifgt-thead.c: Likewise.
	* gcc.target/riscv/movsifgt-ventana.c: Likewise.
	* gcc.target/riscv/movsifgt-zicond.c: Likewise.
	* gcc.target/riscv/movsifle-sfb.c: Likewise.
	* gcc.target/riscv/movsifle-thead.c: Likewise.
	* gcc.target/riscv/movsifle-ventana.c: Likewise.
	* gcc.target/riscv/movsifle-zicond.c: Likewise.
	* gcc.target/riscv/movsiflt-sfb.c: Likewise.
	* gcc.target/riscv/movsiflt-thead.c: Likewise.
	* gcc.target/riscv/movsiflt-ventana.c: Likewise.
	* gcc.target/riscv/movsiflt-zicond.c: Likewise.
	* gcc.target/riscv/smax-ieee.c: Also accept FLT.D.
	* gcc.target/riscv/smaxf-ieee.c: Also accept FLT.S.
	* gcc.target/riscv/smin-ieee.c: Also accept FGT.D.
	* gcc.target/riscv/sminf-ieee.c: Also accept FGT.S.
---
 gcc/config/riscv/predicates.md                    |    3 
 gcc/config/riscv/riscv.cc                         |   22 +++--
 gcc/config/riscv/riscv.md                         |   89 +++++++++++++++++++---
 gcc/testsuite/gcc.target/riscv/movdifge-sfb.c     |    2 
 gcc/testsuite/gcc.target/riscv/movdifge-thead.c   |    2 
 gcc/testsuite/gcc.target/riscv/movdifge-ventana.c |    2 
 gcc/testsuite/gcc.target/riscv/movdifge-zicond.c  |    2 
 gcc/testsuite/gcc.target/riscv/movdifgt-sfb.c     |    2 
 gcc/testsuite/gcc.target/riscv/movdifgt-thead.c   |    2 
 gcc/testsuite/gcc.target/riscv/movdifgt-ventana.c |    2 
 gcc/testsuite/gcc.target/riscv/movdifgt-zicond.c  |    2 
 gcc/testsuite/gcc.target/riscv/movdifle-sfb.c     |    2 
 gcc/testsuite/gcc.target/riscv/movdifle-thead.c   |    2 
 gcc/testsuite/gcc.target/riscv/movdifle-ventana.c |    2 
 gcc/testsuite/gcc.target/riscv/movdifle-zicond.c  |    2 
 gcc/testsuite/gcc.target/riscv/movdiflt-sfb.c     |    2 
 gcc/testsuite/gcc.target/riscv/movdiflt-thead.c   |    2 
 gcc/testsuite/gcc.target/riscv/movdiflt-ventana.c |    2 
 gcc/testsuite/gcc.target/riscv/movdiflt-zicond.c  |    2 
 gcc/testsuite/gcc.target/riscv/movsifge-sfb.c     |    2 
 gcc/testsuite/gcc.target/riscv/movsifge-thead.c   |    2 
 gcc/testsuite/gcc.target/riscv/movsifge-ventana.c |    2 
 gcc/testsuite/gcc.target/riscv/movsifge-zicond.c  |    2 
 gcc/testsuite/gcc.target/riscv/movsifgt-sfb.c     |    2 
 gcc/testsuite/gcc.target/riscv/movsifgt-thead.c   |    2 
 gcc/testsuite/gcc.target/riscv/movsifgt-ventana.c |    2 
 gcc/testsuite/gcc.target/riscv/movsifgt-zicond.c  |    2 
 gcc/testsuite/gcc.target/riscv/movsifle-sfb.c     |    2 
 gcc/testsuite/gcc.target/riscv/movsifle-thead.c   |    2 
 gcc/testsuite/gcc.target/riscv/movsifle-ventana.c |    2 
 gcc/testsuite/gcc.target/riscv/movsifle-zicond.c  |    2 
 gcc/testsuite/gcc.target/riscv/movsiflt-sfb.c     |    2 
 gcc/testsuite/gcc.target/riscv/movsiflt-thead.c   |    2 
 gcc/testsuite/gcc.target/riscv/movsiflt-ventana.c |    2 
 gcc/testsuite/gcc.target/riscv/movsiflt-zicond.c  |    2 
 gcc/testsuite/gcc.target/riscv/smax-ieee.c        |    2 
 gcc/testsuite/gcc.target/riscv/smaxf-ieee.c       |    2 
 gcc/testsuite/gcc.target/riscv/smin-ieee.c        |    2 
 gcc/testsuite/gcc.target/riscv/sminf-ieee.c       |    2 
 39 files changed, 134 insertions(+), 52 deletions(-)

gcc-riscv-cbranch-split.diff
Index: gcc/gcc/config/riscv/predicates.md
===================================================================
--- gcc.orig/gcc/config/riscv/predicates.md
+++ gcc/gcc/config/riscv/predicates.md
@@ -333,6 +333,9 @@
 (define_predicate "modular_operator"
   (match_code "plus,minus,mult,ashift"))
 
+(define_predicate "ne_operator"
+  (match_code "ne"))
+
 (define_predicate "equality_operator"
   (match_code "eq,ne"))
 
Index: gcc/gcc/config/riscv/riscv.cc
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.cc
+++ gcc/gcc/config/riscv/riscv.cc
@@ -3308,7 +3308,9 @@ riscv_address_cost (rtx addr, machine_mo
    calculation for conditional branches: one unit is considered the cost
    of microarchitecture-dependent actual branch execution and therefore
    multiplied by BRANCH_COST and any remaining units are considered fixed
-   branch overhead.  */
+   branch overhead.  Branches on a floating-point condition incur an extra
+   instruction cost as they will be split into an FCMP operation followed
+   by a branch on an integer condition.  */
 
 static int
 riscv_insn_cost (rtx_insn *insn, bool speed)
@@ -3316,11 +3318,19 @@ riscv_insn_cost (rtx_insn *insn, bool sp
   rtx x = PATTERN (insn);
   int cost = pattern_cost (x, speed);
 
-  if (JUMP_P (insn)
-      && GET_CODE (x) == SET
-      && GET_CODE (SET_DEST (x)) == PC
-      && GET_CODE (SET_SRC (x)) == IF_THEN_ELSE)
-    cost += COSTS_N_INSNS (BRANCH_COST (speed, false) - 1);
+  if (JUMP_P (insn))
+    {
+      if (GET_CODE (x) == PARALLEL)
+	x = XVECEXP (x, 0, 0);
+      if (GET_CODE (x) == SET
+	  && GET_CODE (SET_DEST (x)) == PC
+	  && GET_CODE (SET_SRC (x)) == IF_THEN_ELSE)
+	{
+	  cost += COSTS_N_INSNS (BRANCH_COST (speed, false) - 1);
+	  if (FLOAT_MODE_P (GET_MODE (XEXP (XEXP (SET_SRC (x), 0), 0))))
+	    cost += COSTS_N_INSNS (1);
+	}
+    }
   return cost;
 }
 
Index: gcc/gcc/config/riscv/riscv.md
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.md
+++ gcc/gcc/config/riscv/riscv.md
@@ -2750,20 +2750,89 @@
   DONE;
 })
 
-(define_expand "@cbranch<mode>4"
-  [(set (pc)
-	(if_then_else (match_operator 0 "fp_branch_comparison"
-		       [(match_operand:ANYF 1 "register_operand")
-			(match_operand:ANYF 2 "register_operand")])
-		      (label_ref (match_operand 3 ""))
-		      (pc)))]
+(define_expand "@cbranch<ANYF:mode>4"
+  [(parallel [(set (pc)
+		   (if_then_else (match_operator 0 "fp_branch_comparison"
+				  [(match_operand:ANYF 1 "register_operand")
+				   (match_operand:ANYF 2 "register_operand")])
+				 (label_ref (match_operand 3 ""))
+				 (pc)))
+	      (clobber (match_operand 4 ""))])]
   "TARGET_HARD_FLOAT || TARGET_ZFINX"
 {
-  riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
-				   operands[1], operands[2]);
-  DONE;
+  if (!signed_order_operator (operands[0], GET_MODE (operands[0])))
+    {
+      riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
+				       operands[1], operands[2]);
+      DONE;
+    }
+  operands[4] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
 })
 
+(define_insn_and_split "*cbranch<ANYF:mode>4"
+  [(set (pc)
+	(if_then_else (match_operator 1 "fp_native_comparison"
+		       [(match_operand:ANYF 2 "register_operand" "f")
+			(match_operand:ANYF 3 "register_operand" "f")])
+		      (label_ref (match_operand 0 ""))
+		      (pc)))
+   (clobber (match_operand:X 4 "register_operand" "=r"))]
+  "TARGET_HARD_FLOAT || TARGET_ZFINX"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 4)
+	(match_op_dup:X 1 [(match_dup 2) (match_dup 3)]))
+   (set (pc)
+        (if_then_else (ne:X (match_dup 4) (const_int 0))
+		      (label_ref (match_operand 0))
+		      (pc)))]
+  ""
+  [(set_attr "type" "branch")
+   (set (attr "length")
+	(if_then_else (and (le (minus (match_dup 0) (pc))
+			       (const_int 4084))
+			   (le (minus (pc) (match_dup 0))
+			       (const_int 4096)))
+		      (const_int 8)
+		      (if_then_else (and (le (minus (match_dup 0) (pc))
+					     (const_int 1048564))
+					 (le (minus (pc) (match_dup 0))
+					     (const_int 1048576)))
+				    (const_int 12)
+				    (const_int 16))))])
+
+(define_insn_and_split "*cbranch<ANYF:mode>4"
+  [(set (pc)
+	(if_then_else (match_operator 1 "ne_operator"
+		       [(match_operand:ANYF 2 "register_operand" "f")
+			(match_operand:ANYF 3 "register_operand" "f")])
+		      (label_ref (match_operand 0 ""))
+		      (pc)))
+   (clobber (match_operand:X 4 "register_operand" "=r"))]
+  "TARGET_HARD_FLOAT || TARGET_ZFINX"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 4)
+	(eq:X (match_dup 2) (match_dup 3)))
+   (set (pc)
+        (if_then_else (eq:X (match_dup 4) (const_int 0))
+		      (label_ref (match_operand 0))
+		      (pc)))]
+  ""
+  [(set_attr "type" "branch")
+   (set (attr "length")
+	(if_then_else (and (le (minus (match_dup 0) (pc))
+			       (const_int 4084))
+			   (le (minus (pc) (match_dup 0))
+			       (const_int 4096)))
+		      (const_int 8)
+		      (if_then_else (and (le (minus (match_dup 0) (pc))
+					     (const_int 1048564))
+					 (le (minus (pc) (match_dup 0))
+					     (const_int 1048576)))
+				    (const_int 12)
+				    (const_int 16))))])
+
 (define_insn_and_split "*branch_on_bit<X:mode>"
   [(set (pc)
 	(if_then_else
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifge-sfb.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movdifge-sfb.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifge-sfb.c
@@ -20,7 +20,7 @@ movdifge (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
 /* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifge-thead.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movdifge-thead.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifge-thead.c
@@ -18,7 +18,7 @@ movdifge (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
 /* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifge-ventana.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movdifge-ventana.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifge-ventana.c
@@ -20,7 +20,7 @@ movdifge (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifge-zicond.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movdifge-zicond.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifge-zicond.c
@@ -20,7 +20,7 @@ movdifge (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifgt-sfb.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movdifgt-sfb.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifgt-sfb.c
@@ -20,7 +20,7 @@ movdifgt (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
 /* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifgt-thead.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movdifgt-thead.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifgt-thead.c
@@ -18,7 +18,7 @@ movdifgt (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
 /* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifgt-ventana.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movdifgt-ventana.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifgt-ventana.c
@@ -20,7 +20,7 @@ movdifgt (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifgt-zicond.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movdifgt-zicond.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifgt-zicond.c
@@ -20,7 +20,7 @@ movdifgt (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifle-sfb.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movdifle-sfb.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifle-sfb.c
@@ -20,7 +20,7 @@ movdifle (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
 /* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifle-thead.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movdifle-thead.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifle-thead.c
@@ -18,7 +18,7 @@ movdifle (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
 /* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifle-ventana.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movdifle-ventana.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifle-ventana.c
@@ -20,7 +20,7 @@ movdifle (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifle-zicond.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movdifle-zicond.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifle-zicond.c
@@ -20,7 +20,7 @@ movdifle (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiflt-sfb.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movdiflt-sfb.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiflt-sfb.c
@@ -20,7 +20,7 @@ movdiflt (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
 /* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiflt-thead.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movdiflt-thead.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiflt-thead.c
@@ -18,7 +18,7 @@ movdiflt (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
 /* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiflt-ventana.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movdiflt-ventana.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiflt-ventana.c
@@ -20,7 +20,7 @@ movdiflt (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiflt-zicond.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movdiflt-zicond.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiflt-zicond.c
@@ -20,7 +20,7 @@ movdiflt (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifge-sfb.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movsifge-sfb.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifge-sfb.c
@@ -20,7 +20,7 @@ movsifge (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
 /* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifge-thead.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movsifge-thead.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifge-thead.c
@@ -18,7 +18,7 @@ movsifge (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
 /* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifge-ventana.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movsifge-ventana.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifge-ventana.c
@@ -20,7 +20,7 @@ movsifge (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifge-zicond.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movsifge-zicond.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifge-zicond.c
@@ -20,7 +20,7 @@ movsifge (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifgt-sfb.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movsifgt-sfb.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifgt-sfb.c
@@ -20,7 +20,7 @@ movsifgt (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
 /* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifgt-thead.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movsifgt-thead.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifgt-thead.c
@@ -18,7 +18,7 @@ movsifgt (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
 /* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifgt-ventana.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movsifgt-ventana.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifgt-ventana.c
@@ -20,7 +20,7 @@ movsifgt (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifgt-zicond.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movsifgt-zicond.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifgt-zicond.c
@@ -20,7 +20,7 @@ movsifgt (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifle-sfb.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movsifle-sfb.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifle-sfb.c
@@ -20,7 +20,7 @@ movsifle (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
 /* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifle-thead.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movsifle-thead.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifle-thead.c
@@ -18,7 +18,7 @@ movsifle (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
 /* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifle-ventana.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movsifle-ventana.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifle-ventana.c
@@ -20,7 +20,7 @@ movsifle (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifle-zicond.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movsifle-zicond.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifle-zicond.c
@@ -20,7 +20,7 @@ movsifle (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiflt-sfb.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movsiflt-sfb.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiflt-sfb.c
@@ -20,7 +20,7 @@ movsiflt (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
 /* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiflt-thead.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movsiflt-thead.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiflt-thead.c
@@ -18,7 +18,7 @@ movsiflt (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
 /* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiflt-ventana.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movsiflt-ventana.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiflt-ventana.c
@@ -20,7 +20,7 @@ movsiflt (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiflt-zicond.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/movsiflt-zicond.c
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiflt-zicond.c
@@ -20,7 +20,7 @@ movsiflt (double w, double x, int_t y, i
  */
 
 /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
 /* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/smax-ieee.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/smax-ieee.c
+++ gcc/gcc/testsuite/gcc.target/riscv/smax-ieee.c
@@ -10,4 +10,4 @@ smax (double x, double y)
 
 /* { dg-final { scan-assembler-not "\t(call|tail)\tfmax\t" } } */
 /* { dg-final { scan-assembler-not "\tfmax\\.d\t" } } */
-/* { dg-final { scan-assembler "\tfge\\.d\t" } } */
+/* { dg-final { scan-assembler "\t(fge\\.d|flt\\.d)\t" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/smaxf-ieee.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/smaxf-ieee.c
+++ gcc/gcc/testsuite/gcc.target/riscv/smaxf-ieee.c
@@ -10,4 +10,4 @@ smaxf (float x, float y)
 
 /* { dg-final { scan-assembler-not "\t(call|tail)\tfmaxf\t" } } */
 /* { dg-final { scan-assembler-not "\tfmax\\.s\t" } } */
-/* { dg-final { scan-assembler "\tfge\\.s\t" } } */
+/* { dg-final { scan-assembler "\t(fge\\.s|flt\\.s)\t" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/smin-ieee.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/smin-ieee.c
+++ gcc/gcc/testsuite/gcc.target/riscv/smin-ieee.c
@@ -10,4 +10,4 @@ smin (double x, double y)
 
 /* { dg-final { scan-assembler-not "\t(call|tail)\tfmin\t" } } */
 /* { dg-final { scan-assembler-not "\tfmin\\.d\t" } } */
-/* { dg-final { scan-assembler "\tfle\\.d\t" } } */
+/* { dg-final { scan-assembler "\t(fgt\\.d|fle\\.d)\t" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/sminf-ieee.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/riscv/sminf-ieee.c
+++ gcc/gcc/testsuite/gcc.target/riscv/sminf-ieee.c
@@ -10,4 +10,4 @@ sminf (float x, float y)
 
 /* { dg-final { scan-assembler-not "\t(call|tail)\tfminf\t" } } */
 /* { dg-final { scan-assembler-not "\tfmin\\.s\t" } } */
-/* { dg-final { scan-assembler "\tfle\\.s\t" } } */
+/* { dg-final { scan-assembler "\t(fgt\\.s|fle\\.s)\t" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 35/44] RISC-V: Avoid extraneous integer comparison for FP comparisons
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (33 preceding siblings ...)
  2023-11-19  5:42 ` [PATCH 34/44] RISC-V: Provide FP conditional-branch instructions for if-conversion Maciej W. Rozycki
@ 2023-11-19  5:42 ` 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
                   ` (9 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:42 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

We have floating-point coditional-set machine instructions for a subset 
of FP comparisons, so avoid going through a comparison against constant 
zero in `riscv_expand_float_scc' where not necessary, preventing an 
extraneous RTL instruction from being produced that counts against the 
cost of the replacement branchless code sequence in if-conversion, e.g.:

(insn 29 6 30 2 (set (reg:DI 142)
        (ge:DI (reg/v:DF 135 [ w ])
            (reg/v:DF 136 [ x ]))) 297 {*cstoredfdi4}
     (nil))
(insn 30 29 31 2 (set (reg:DI 143)
        (ne:DI (reg:DI 142)
            (const_int 0 [0]))) 319 {*sne_zero_didi}
     (nil))
(insn 31 30 32 2 (set (reg:DI 141)
        (reg:DI 143)) 206 {*movdi_64bit}
     (nil))
(insn 32 31 33 2 (set (reg:DI 144)
        (neg:DI (reg:DI 141))) 15 {negdi2}
     (nil))
(insn 33 32 34 2 (set (reg:DI 145)
        (and:DI (reg:DI 144)
            (reg/v:DI 137 [ y ]))) 102 {*anddi3}
     (nil))
(insn 34 33 35 2 (set (reg:DI 146)
        (not:DI (reg:DI 144))) 111 {one_cmpldi2}
     (nil))
(insn 35 34 36 2 (set (reg:DI 147)
        (and:DI (reg:DI 146)
            (reg/v:DI 138 [ z ]))) 102 {*anddi3}
     (nil))
(insn 36 35 21 2 (set (reg/v:DI 138 [ z ])
        (ior:DI (reg:DI 145)
            (reg:DI 147))) 105 {iordi3}
     (nil))

where the second insn effectively just copies its input.  This now gets 
simplified to:

(insn 29 6 30 2 (set (reg:DI 141)
        (ge:DI (reg/v:DF 135 [ w ])
            (reg/v:DF 136 [ x ]))) 297 {*cstoredfdi4}
     (nil))
(insn 30 29 31 2 (set (reg:DI 142)
        (neg:DI (reg:DI 141))) 15 {negdi2}
     (nil))
(insn 31 30 32 2 (set (reg:DI 143)
        (and:DI (reg:DI 142)
            (reg/v:DI 137 [ y ]))) 102 {*anddi3}
     (nil))
(insn 32 31 33 2 (set (reg:DI 144)
        (not:DI (reg:DI 142))) 111 {one_cmpldi2}
     (nil))
(insn 33 32 34 2 (set (reg:DI 145)
        (and:DI (reg:DI 144)
            (reg/v:DI 138 [ z ]))) 102 {*anddi3}
     (nil))
(insn 34 33 21 2 (set (reg/v:DI 138 [ z ])
        (ior:DI (reg:DI 143)
            (reg:DI 145))) 105 {iordi3}
     (nil))

lowering the cost of the code sequence produced (even though combine 
would swallow the second insn anyway).

We still need to produce a comparison against constant zero where the 
instruction following a floating-point coditional-set operation is a 
branch, so add canonicalization to `riscv_expand_conditional_branch' 
instead.

	gcc/
	* config/riscv/riscv.cc (riscv_emit_float_compare) <NE>: Handle 
	separately.
	<EQ, LE, LT, GE, GT>: Return operands supplied as is.
	(riscv_emit_binary): Call `riscv_emit_binary' directly rather 
	than going through a temporary register for word-mode targets.
	(riscv_expand_conditional_branch): Canonicalize the comparison 
	if not against constant zero.
---
 gcc/config/riscv/riscv.cc |   29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

gcc-riscv-emit-float-compare-fcmp.diff
Index: gcc/gcc/config/riscv/riscv.cc
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.cc
+++ gcc/gcc/config/riscv/riscv.cc
@@ -4029,9 +4029,10 @@ riscv_emit_float_compare (enum rtx_code
 #undef UNORDERED_COMPARISON
 
     case NE:
-      fp_code = EQ;
       *code = EQ;
-      /* Fall through.  */
+      *op0 = riscv_force_binary (word_mode, EQ, cmp_op0, cmp_op1);
+      *op1 = const0_rtx;
+      break;
 
     case EQ:
     case LE:
@@ -4039,8 +4040,9 @@ riscv_emit_float_compare (enum rtx_code
     case GE:
     case GT:
       /* We have instructions for these cases.  */
-      *op0 = riscv_force_binary (word_mode, fp_code, cmp_op0, cmp_op1);
-      *op1 = const0_rtx;
+      *code = fp_code;
+      *op0 = cmp_op0;
+      *op1 = cmp_op1;
       break;
 
     case LTGT:
@@ -4080,10 +4082,14 @@ riscv_expand_float_scc (rtx target, enum
 {
   riscv_emit_float_compare (&code, &op0, &op1);
 
-  rtx cmp = riscv_force_binary (word_mode, code, op0, op1);
-  if (GET_MODE (target) != word_mode)
-    cmp = lowpart_subreg (GET_MODE (target), cmp, word_mode);
-  riscv_emit_set (target, cmp);
+  machine_mode mode = GET_MODE (target);
+  if (mode != word_mode)
+    {
+      rtx cmp = riscv_force_binary (word_mode, code, op0, op1);
+      riscv_emit_set (target, lowpart_subreg (mode, cmp, word_mode));
+    }
+  else
+    riscv_emit_binary (code, target, op0, op1);
 }
 
 /* Jump to LABEL if (CODE OP0 OP1) holds.  */
@@ -4096,6 +4102,13 @@ riscv_expand_conditional_branch (rtx lab
   else
     riscv_emit_int_compare (&code, &op0, &op1);
 
+  if (FLOAT_MODE_P (GET_MODE (op0)))
+    {
+      op0 = riscv_force_binary (word_mode, code, op0, op1);
+      op1 = const0_rtx;
+      code = NE;
+    }
+
   rtx condition = gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
   emit_jump_insn (gen_condjump (condition, label));
 }

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 36/44] RISC-V/testsuite: Add branched cases for generic FP cond moves
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (34 preceding siblings ...)
  2023-11-19  5:42 ` [PATCH 35/44] RISC-V: Avoid extraneous integer comparison for FP comparisons Maciej W. Rozycki
@ 2023-11-19  5:42 ` 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
                   ` (8 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:42 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for generic floating-point conditional-move operations that have 
a corresponding conditional-set machine instruction, that if-conversion 
does *not* trigger at `-mbranch-cost=4' setting, which makes original 
branched code sequences cheaper than their branchless equivalents 
if-conversion would emit.  Cover all the relevant floating-point 
relational operations to make sure no corner case escapes.

	gcc/testsuite/
	* gcc.target/riscv/movdibfge.c: New test.
	* gcc.target/riscv/movdibfgt.c: New test.
	* gcc.target/riscv/movdibfle.c: New test.
	* gcc.target/riscv/movdibflt.c: New test.
	* gcc.target/riscv/movdibfne.c: New test.
	* gcc.target/riscv/movsibfge.c: New test.
	* gcc.target/riscv/movsibfgt.c: New test.
	* gcc.target/riscv/movsibfle.c: New test.
	* gcc.target/riscv/movsibflt.c: New test.
	* gcc.target/riscv/movsibfne.c: New test.
---
 gcc/testsuite/gcc.target/riscv/movdibfge.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibfgt.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibfle.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibflt.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibfne.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibfge.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibfgt.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibfle.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibflt.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibfne.c |   28 ++++++++++++++++++++++++++++
 10 files changed, 280 insertions(+)

gcc-riscv-test-movccf-branch-generic.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfge.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibfge.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	fge.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfgt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibfgt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	fgt.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfle.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibfle.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	fle.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibflt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibflt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	flt.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfne.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibfne.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	feq.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	bne	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfge.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibfge.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	fge.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfgt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibfgt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	fgt.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfle.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibfle.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	fle.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibflt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibflt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	flt.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfne.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibfne.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	feq.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	bne	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 37/44] RISC-V/testsuite: Add branchless cases for generic FP cond moves
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (35 preceding siblings ...)
  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  5:43 ` 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
                   ` (7 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for generic floating-point conditional-move operations that have 
a corresponding conditional-set machine instruction, that if-conversion 
triggers (via `cond_move_convert_if_block', which doesn't report) at 
`-mbranch-cost=5' setting, which makes branchless code sequences emitted 
by if-conversion cheaper than their original branched equivalents, and 
that extraneous instructions such as SNEZ, etc. are not present in 
output.

	gcc/testsuite/
	* gcc.target/riscv/movdifge.c: New test.
	* gcc.target/riscv/movdifgt.c: New test.
	* gcc.target/riscv/movdifle.c: New test.
	* gcc.target/riscv/movdiflt.c: New test.
	* gcc.target/riscv/movdifne.c: New test.
	* gcc.target/riscv/movsifge.c: New test.
	* gcc.target/riscv/movsifgt.c: New test.
	* gcc.target/riscv/movsifle.c: New test.
	* gcc.target/riscv/movsiflt.c: New test.
	* gcc.target/riscv/movsifne.c: New test.
---
 gcc/testsuite/gcc.target/riscv/movdifge.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifgt.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifle.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdiflt.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifne.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifge.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifgt.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifle.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsiflt.c |   28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifne.c |   28 ++++++++++++++++++++++++++++
 10 files changed, 280 insertions(+)

gcc-riscv-test-movccf-generic.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifge.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifge.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fge.d	a5,fa0,fa1
+	neg	a5,a5
+	and	a0,a5,a0
+	not	a5,a5
+	and	a5,a5,a1
+	or	a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifgt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifgt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fgt.d	a5,fa0,fa1
+	neg	a5,a5
+	and	a0,a5,a0
+	not	a5,a5
+	and	a5,a5,a1
+	or	a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifle.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifle.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fle.d	a5,fa0,fa1
+	neg	a5,a5
+	and	a0,a5,a0
+	not	a5,a5
+	and	a5,a5,a1
+	or	a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdiflt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdiflt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	flt.d	a5,fa0,fa1
+	neg	a5,a5
+	and	a0,a5,a0
+	not	a5,a5
+	and	a5,a5,a1
+	or	a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifne.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifne.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	neg	a5,a5
+	and	a1,a5,a1
+	not	a5,a5
+	and	a0,a5,a0
+	or	a0,a1,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifge.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifge.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fge.d	a5,fa0,fa1
+	neg	a5,a5
+	and	a0,a5,a0
+	not	a5,a5
+	and	a5,a5,a1
+	or	a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifgt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifgt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fgt.d	a5,fa0,fa1
+	neg	a5,a5
+	and	a0,a5,a0
+	not	a5,a5
+	and	a5,a5,a1
+	or	a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifle.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifle.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	fle.d	a5,fa0,fa1
+	neg	a5,a5
+	and	a0,a5,a0
+	not	a5,a5
+	and	a5,a5,a1
+	or	a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsiflt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsiflt.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	flt.d	a5,fa0,fa1
+	neg	a5,a5
+	and	a0,a5,a0
+	not	a5,a5
+	and	a5,a5,a1
+	or	a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifne.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifne.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	neg	a5,a5
+	and	a1,a5,a1
+	not	a5,a5
+	and	a0,a5,a0
+	or	a0,a1,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 38/44] RISC-V/testsuite: Add branched cases for generic FP cond adds
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (36 preceding siblings ...)
  2023-11-19  5:43 ` [PATCH 37/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
@ 2023-11-19  5:43 ` 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
                   ` (6 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for generic floating-point conditional-add operations that have 
a corresponding conditional-set machine instruction, that if-conversion 
does *not* trigger at `-mbranch-cost=2' setting, which makes original 
branched code sequences cheaper than their branchless equivalents 
if-conversion would emit.  Cover all the relevant floating-point 
relational operations to make sure no corner case escapes.

	gcc/testsuite/
	* gcc.target/riscv/adddibfeq.c: New test.
	* gcc.target/riscv/adddibfge.c: New test.
	* gcc.target/riscv/adddibfgt.c: New test.
	* gcc.target/riscv/adddibfle.c: New test.
	* gcc.target/riscv/adddibflt.c: New test.
	* gcc.target/riscv/addsibfeq.c: New test.
	* gcc.target/riscv/addsibfge.c: New test.
	* gcc.target/riscv/addsibfgt.c: New test.
	* gcc.target/riscv/addsibfle.c: New test.
	* gcc.target/riscv/addsibflt.c: New test.
---
 gcc/testsuite/gcc.target/riscv/adddibfeq.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddibfge.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddibfgt.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddibfle.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddibflt.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsibfeq.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsibfge.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsibfgt.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsibfle.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsibflt.c |   26 ++++++++++++++++++++++++++
 10 files changed, 260 insertions(+)

gcc-riscv-test-addccf-branch-generic.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/adddibfeq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddibfeq.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	feq.d	a5,fa0,fa1
+	beq	a5,zero,.L2
+	add	a0,a0,a1
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddibfge.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddibfge.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	fge.d	a5,fa0,fa1
+	beq	a5,zero,.L2
+	add	a0,a0,a1
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddibfgt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddibfgt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	fgt.d	a5,fa0,fa1
+	beq	a5,zero,.L2
+	add	a0,a0,a1
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddibfle.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddibfle.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	fle.d	a5,fa0,fa1
+	beq	a5,zero,.L2
+	add	a0,a0,a1
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddibflt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddibflt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	flt.d	a5,fa0,fa1
+	beq	a5,zero,.L2
+	add	a0,a0,a1
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsibfeq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsibfeq.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	feq.d	a5,fa0,fa1
+	beq	a5,zero,.L2
+	add[w]	a0,a0,a1
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsibfge.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsibfge.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	fge.d	a5,fa0,fa1
+	beq	a5,zero,.L2
+	add[w]	a0,a0,a1
+.L2:
+ */
+
+/* { /* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsibfgt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsibfgt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	fgt.d	a5,fa0,fa1
+	beq	a5,zero,.L2
+	add[w]	a0,a0,a1
+.L2:
+ */
+
+/* { /* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsibfle.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsibfle.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	fle.d	a5,fa0,fa1
+	beq	a5,zero,.L2
+	addw	a0,a0,a1
+.L2:
+ */
+
+/* { /* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsibflt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsibflt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	flt.d	a5,fa0,fa1
+	beq	a5,zero,.L2
+	addw	a0,a0,a1
+.L2:
+ */
+
+/* { /* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 39/44] RISC-V/testsuite: Add branchless cases for generic FP cond adds
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (37 preceding siblings ...)
  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  5:43 ` 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
                   ` (5 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for generic floating-point conditional-add operations that have 
a corresponding conditional-set machine instruction, that if-conversion 
triggers via `noce_try_addcc' at `-mbranch-cost=3' setting, which makes 
branchless code sequences emitted by if-conversion cheaper than their 
original branched equivalents, and that extraneous instructions such as 
SNEZ, etc. are not present in output.

The reason to XFAIL SImode tests for RV64 targets is the compiler thinks
it has to sign-extend addends, which causes if-conversion to give up.

	gcc/testsuite/
	* gcc.target/riscv/adddifeq.c: New test.
	* gcc.target/riscv/adddifge.c: New test.
	* gcc.target/riscv/adddifgt.c: New test.
	* gcc.target/riscv/adddifle.c: New test.
	* gcc.target/riscv/adddiflt.c: New test.
	* gcc.target/riscv/addsifeq.c: New test.
	* gcc.target/riscv/addsifge.c: New test.
	* gcc.target/riscv/addsifgt.c: New test.
	* gcc.target/riscv/addsifle.c: New test.
	* gcc.target/riscv/addsiflt.c: New test.
---
 gcc/testsuite/gcc.target/riscv/adddifeq.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddifge.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddifgt.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddifle.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/adddiflt.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsifeq.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsifge.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsifgt.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsifle.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsiflt.c |   26 ++++++++++++++++++++++++++
 10 files changed, 260 insertions(+)

gcc-riscv-test-addccf-generic.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/adddifeq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddifeq.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	neg	a5,a5
+	and	a5,a5,a1
+	add	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddifge.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddifge.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	fge.d	a5,fa0,fa1
+	neg	a5,a5
+	and	a5,a5,a1
+	add	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddifgt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddifgt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	fgt.d	a5,fa0,fa1
+	neg	a5,a5
+	and	a5,a5,a1
+	add	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddifle.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddifle.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	fle.d	a5,fa0,fa1
+	neg	a5,a5
+	and	a5,a5,a1
+	add	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/adddiflt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddiflt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	flt.d	a5,fa0,fa1
+	neg	a5,a5
+	and	a5,a5,a1
+	add	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsifeq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsifeq.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	neg[w]	a5,a5
+	and	a5,a5,a1
+	add[w]	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail rv64 } } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsifge.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsifge.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifge (double w, double x, int_t y, int_t z)
+{
+  return w >= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	fge.d	a5,fa0,fa1
+	neg[w]	a5,a5
+	and	a5,a5,a1
+	add[w]	a0,a5,a0
+ */
+
+/* { /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail rv64 } } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsifgt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsifgt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifgt (double w, double x, int_t y, int_t z)
+{
+  return w > x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	fgt.d	a5,fa0,fa1
+	neg[w]	a5,a5
+	and	a5,a5,a1
+	add[w]	a0,a5,a0
+ */
+
+/* { /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail rv64 } } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsifle.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsifle.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifle (double w, double x, int_t y, int_t z)
+{
+  return w <= x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	fle.d	a5,fa0,fa1
+	neg[w]	a5,a5
+	and	a5,a5,a1
+	add[w]	a0,a5,a0
+ */
+
+/* { /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail rv64 } } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsiflt.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsiflt.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -ffinite-math-only -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsiflt (double w, double x, int_t y, int_t z)
+{
+  return w < x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	flt.d	a5,fa0,fa1
+	neg[w]	a5,a5
+	and	a5,a5,a1
+	add[w]	a0,a5,a0
+ */
+
+/* { /* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fgt\\.d|fle\\.d|flt\\.d)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail rv64 } } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 40/44] RISC-V: Handle FP NE operator via inversion in cond-operation expansion
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (38 preceding siblings ...)
  2023-11-19  5:43 ` [PATCH 39/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
@ 2023-11-19  5:43 ` Maciej W. Rozycki
  2023-11-19 19:51   ` Jeff Law
  2023-11-19  5:43 ` [PATCH 41/44] RISC-V/testsuite: Add branched cases for FP NE cond-move operations Maciej W. Rozycki
                   ` (4 subsequent siblings)
  44 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

We have no FNE.fmt machine instructions, but we can emulate them for the 
purpose of conditional-move and conditional-add operations by using the 
respective FEQ.fmt instruction and then swapping the data input operands 
or complementing the mask for the conditional addend respectively, so 
update our handlers accordingly.

	gcc/
	* config/riscv/riscv-protos.h (riscv_expand_float_scc): Add 
	`invert_ptr' parameter.
	* config/riscv/riscv.cc (riscv_emit_float_compare): Add NE 
	inversion handling.
	(riscv_expand_float_scc): Pass `invert_ptr' through to 
	`riscv_emit_float_compare'.
	(riscv_expand_conditional_move): Pass `&invert' to 
	`riscv_expand_float_scc'.
	* config/riscv/riscv.md (add<mode>cc): Likewise.
---
 gcc/config/riscv/riscv-protos.h |    3 ++-
 gcc/config/riscv/riscv.cc       |   23 +++++++++++++++--------
 gcc/config/riscv/riscv.md       |    2 +-
 3 files changed, 18 insertions(+), 10 deletions(-)

gcc-riscv-emit-float-compare-ne.diff
Index: gcc/gcc/config/riscv/riscv-protos.h
===================================================================
--- gcc.orig/gcc/config/riscv/riscv-protos.h
+++ gcc/gcc/config/riscv/riscv-protos.h
@@ -132,7 +132,8 @@ riscv_zcmp_valid_stack_adj_bytes_p (HOST
 
 #ifdef RTX_CODE
 extern void riscv_expand_int_scc (rtx, enum rtx_code, rtx, rtx, bool *invert_ptr = 0);
-extern void riscv_expand_float_scc (rtx, enum rtx_code, rtx, rtx);
+extern void riscv_expand_float_scc (rtx, enum rtx_code, rtx, rtx,
+				    bool *invert_ptr = nullptr);
 extern void riscv_expand_conditional_branch (rtx, enum rtx_code, rtx, rtx);
 extern rtx riscv_emit_unary (enum rtx_code code, rtx dest, rtx x);
 extern rtx riscv_emit_binary (enum rtx_code code, rtx dest, rtx x, rtx y);
Index: gcc/gcc/config/riscv/riscv.cc
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.cc
+++ gcc/gcc/config/riscv/riscv.cc
@@ -3965,7 +3965,8 @@ riscv_emit_int_compare (enum rtx_code *c
 /* Like riscv_emit_int_compare, but for floating-point comparisons.  */
 
 static void
-riscv_emit_float_compare (enum rtx_code *code, rtx *op0, rtx *op1)
+riscv_emit_float_compare (enum rtx_code *code, rtx *op0, rtx *op1,
+			  bool *invert_ptr = nullptr)
 {
   rtx tmp0, tmp1, cmp_op0 = *op0, cmp_op1 = *op1;
   enum rtx_code fp_code = *code;
@@ -4029,10 +4030,15 @@ riscv_emit_float_compare (enum rtx_code
 #undef UNORDERED_COMPARISON
 
     case NE:
-      *code = EQ;
-      *op0 = riscv_force_binary (word_mode, EQ, cmp_op0, cmp_op1);
-      *op1 = const0_rtx;
-      break;
+      fp_code = EQ;
+      if (invert_ptr != nullptr)
+	*invert_ptr = !*invert_ptr;
+      else
+	{
+	  cmp_op0 = riscv_force_binary (word_mode, fp_code, cmp_op0, cmp_op1);
+	  cmp_op1 = const0_rtx;
+	}
+      gcc_fallthrough ();
 
     case EQ:
     case LE:
@@ -4078,9 +4084,10 @@ riscv_expand_int_scc (rtx target, enum r
 /* Like riscv_expand_int_scc, but for floating-point comparisons.  */
 
 void
-riscv_expand_float_scc (rtx target, enum rtx_code code, rtx op0, rtx op1)
+riscv_expand_float_scc (rtx target, enum rtx_code code, rtx op0, rtx op1,
+			bool *invert_ptr)
 {
-  riscv_emit_float_compare (&code, &op0, &op1);
+  riscv_emit_float_compare (&code, &op0, &op1, invert_ptr);
 
   machine_mode mode = GET_MODE (target);
   if (mode != word_mode)
@@ -4171,7 +4178,7 @@ riscv_expand_conditional_move (rtx dest,
 	    riscv_expand_int_scc (tmp, code, op0, op1, invert_ptr);
 	  else if (FLOAT_MODE_P (mode0)
 		   && fp_scc_comparison (op, GET_MODE (op)))
-	    riscv_expand_float_scc (tmp, code, op0, op1);
+	    riscv_expand_float_scc (tmp, code, op0, op1, &invert);
 	  else
 	    return false;
 
Index: gcc/gcc/config/riscv/riscv.md
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.md
+++ gcc/gcc/config/riscv/riscv.md
@@ -2697,7 +2697,7 @@
   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);
+    riscv_expand_float_scc (reg0, code, cmp0, cmp1, &invert);
   else
     FAIL;
 

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 41/44] RISC-V/testsuite: Add branched cases for FP NE cond-move operations
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (39 preceding siblings ...)
  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  5:43 ` Maciej W. Rozycki
  2023-11-19  5:43 ` [PATCH 42/44] " Maciej W. Rozycki
                   ` (3 subsequent siblings)
  44 siblings, 0 replies; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for generic, Ventana and Zicond targets and the floating-point 
NE conditional-move operation, that if-conversion does *not* trigger at 
the respective sufficiently low `-mbranch-cost=' settings that make 
original branched code sequences cheaper than their branchless 
equivalents if-conversion would emit.

	gcc/testsuite/
	* gcc.target/riscv/movdibfeq-ventana.c: New test.
	* gcc.target/riscv/movdibfeq-zicond.c: New test.
	* gcc.target/riscv/movdibfeq.c: New test.
	* gcc.target/riscv/movsibfeq-ventana.c: New test.
	* gcc.target/riscv/movsibfeq-zicond.c: New test.
	* gcc.target/riscv/movsibfeq.c: New test.
---
 gcc/testsuite/gcc.target/riscv/movdibfeq-ventana.c |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibfeq-zicond.c  |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdibfeq.c         |   28 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibfeq-ventana.c |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibfeq-zicond.c  |   30 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsibfeq.c         |   28 +++++++++++++++++++
 6 files changed, 176 insertions(+)

gcc-riscv-test-movccne-branch-generic.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfeq-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibfeq-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	feq.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfeq-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibfeq-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	feq.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfeq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdibfeq.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	feq.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfeq-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibfeq-ventana.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	feq.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
+/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfeq-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibfeq-zicond.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	feq.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
+/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfeq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsibfeq.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=4 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branched assembly like:
+
+	feq.d	a4,fa0,fa1
+	mv	a5,a0
+	mv	a0,a1
+	beq	a4,zero,.L2
+	mv	a0,a5
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 42/44] RISC-V/testsuite: Add branched cases for FP NE cond-move operations
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (40 preceding siblings ...)
  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 ` 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
                   ` (2 subsequent siblings)
  44 siblings, 0 replies; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for the floating-point NE conditional-move operation, that 
if-conversion triggers via `noce_try_cmove' at the respective 
sufficiently high `-mbranch-cost=' settings that make branchless code 
sequences produced by if-conversion cheaper than their original branched 
equivalents, and that extraneous instructions such as SNEZ, etc. are not 
present in output.

	gcc/testsuite/
	* gcc.target/riscv/movdifeq-sfb.c: New test.
	* gcc.target/riscv/movdifeq-thead.c: New test.
	* gcc.target/riscv/movdifeq-ventana.c: New test.
	* gcc.target/riscv/movdifeq-zicond.c: New test.
	* gcc.target/riscv/movdifeq.c: New test.
	* gcc.target/riscv/movsifeq-sfb.c: New test.
	* gcc.target/riscv/movsifeq-thead.c: New test.
	* gcc.target/riscv/movsifeq-ventana.c: New test.
	* gcc.target/riscv/movsifeq-zicond.c: New test.
	* gcc.target/riscv/movsifeq.c: New test.
---
 gcc/testsuite/gcc.target/riscv/movdifeq-sfb.c     |   27 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifeq-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifeq-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifeq-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movdifeq.c         |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifeq-sfb.c     |   27 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifeq-thead.c   |   25 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifeq-ventana.c |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifeq-zicond.c  |   28 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/movsifeq.c         |   28 ++++++++++++++++++++++
 10 files changed, 272 insertions(+)

gcc-riscv-test-movccne-generic.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifeq-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifeq-sfb.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	feq.d	a5,fa0,fa1
+	beq	a5,zero,1f	# movcc
+	mv	a1,a0
+1:
+	mv	a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifeq-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifeq-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	th.mveqz	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifeq-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifeq-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	vt.maskcn	a1,a1,a5
+	vt.maskc	a0,a0,a5
+	or	a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifeq-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifeq-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	czero.nez	a1,a1,a5
+	czero.eqz	a0,a0,a5
+	or	a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movdifeq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movdifeq.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+movdifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	neg	a5,a5
+	and	a0,a5,a0
+	not	a5,a5
+	and	a5,a5,a1
+	or	a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifeq-sfb.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifeq-sfb.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect short forward branch assembly like:
+
+	feq.d	a5,fa0,fa1
+	beq	a5,zero,1f	# movcc
+	mv	a1,a0
+1:
+	mv	a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifeq-thead.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifeq-thead.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	th.mveqz	a0,a1,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifeq-ventana.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifeq-ventana.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	vt.maskcn	a1,a1,a5
+	vt.maskc	a0,a0,a5
+	or	a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifeq-zicond.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifeq-zicond.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	czero.nez	a1,a1,a5
+	czero.eqz	a0,a0,a5
+	or	a0,a0,a1
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/movsifeq.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/movsifeq.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=5 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+movsifeq (double w, double x, int_t y, int_t z)
+{
+  return w == x ? y : z;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	neg	a5,a5
+	and	a0,a5,a0
+	not	a5,a5
+	and	a5,a5,a1
+	or	a0,a0,a5
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 43/44] RISC-V/testsuite: Add branched cases for FP NE cond-add operation
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (41 preceding siblings ...)
  2023-11-19  5:43 ` [PATCH 42/44] " Maciej W. Rozycki
@ 2023-11-19  5:44 ` 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
  44 siblings, 0 replies; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:44 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for the generic floating-point NE conditional-add operation, 
that if-conversion does *not* trigger at `-mbranch-cost=2' setting, 
which makes original branched code sequences cheaper than their 
branchless equivalents if-conversion would emit.

	gcc/testsuite/
	* gcc.target/riscv/adddibfne.c: New test.
	* gcc.target/riscv/addsibfne.c: New test.
---
 gcc/testsuite/gcc.target/riscv/adddibfne.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsibfne.c |   26 ++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

gcc-riscv-test-addccne-branch-generic.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/adddibfne.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddibfne.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	feq.d	a5,fa0,fa1
+	bne	a5,zero,.L2
+	add	a0,a0,a1
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsibfne.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsibfne.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=2 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y + z : y;
+}
+
+/* Expect branched assembly like:
+
+	feq.d	a5,fa0,fa1
+	bne	a5,zero,.L2
+	add[w]	a0,a0,a1
+.L2:
+ */
+
+/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
+/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 44/44] RISC-V/testsuite: Add branchless cases for FP NE cond-add operation
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (42 preceding siblings ...)
  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 ` Maciej W. Rozycki
  2023-11-19  5:52 ` [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Kito Cheng
  44 siblings, 0 replies; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  5:44 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

Verify, for the generic floating-point NE conditional-add operation, 
that if-conversion triggers via `noce_try_addcc' at `-mbranch-cost=3' 
setting, which makes branchless code sequences emitted by if-conversion 
cheaper than their original branched equivalents, and that extraneous 
instructions such as SNEZ, etc. are not present in output.

The reason to XFAIL the SImode test for RV64 targets is GCC thinks it 
has to sign-extend addends, which causes if-conversion to give up.

	gcc/testsuite/
	* gcc.target/riscv/adddifne.c: New test.
	* gcc.target/riscv/addsifne.c: New test.
---
 gcc/testsuite/gcc.target/riscv/adddifne.c |   26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/addsifne.c |   26 ++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

gcc-riscv-test-addccne-generic.diff
Index: gcc/gcc/testsuite/gcc.target/riscv/adddifne.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/adddifne.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" } */
+
+typedef int __attribute__ ((mode (DI))) int_t;
+
+int_t
+adddifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	addi	a5,a5,-1
+	and	a5,a5,a1
+	add	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
Index: gcc/gcc/testsuite/gcc.target/riscv/addsifne.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.target/riscv/addsifne.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=3 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+addsifne (double w, double x, int_t y, int_t z)
+{
+  return w != x ? y + z : y;
+}
+
+/* Expect branchless assembly like:
+
+	feq.d	a5,fa0,fa1
+	addi[w]	a5,a5,-1
+	and	a5,a5,a1
+	add[w]	a0,a5,a0
+ */
+
+/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_addcc" 1 "ce1" { xfail rv64 } } } */
+/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail rv64 } } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements
  2023-11-19  5:35 [PATCH 00/44] RISC-V: Various if-conversion fixes and improvements Maciej W. Rozycki
                   ` (43 preceding siblings ...)
  2023-11-19  5:44 ` [PATCH 44/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
@ 2023-11-19  5:52 ` Kito Cheng
  44 siblings, 0 replies; 101+ messages in thread
From: Kito Cheng @ 2023-11-19  5:52 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Palmer Dabbelt

quick response for this patch set, it's a really huge number of
patches, so I'll review it individually, and feel free to commit
individual one once got LGTM for each single patch :P


On Sun, Nov 19, 2023 at 1:35 PM Maciej W. Rozycki <macro@embecosm.com> wrote:
>
> Hi,
>
>  This patch series has come out from a simple change to add generic
> conditional-move and conditional-add expansions for a yet-out-of-tree
> target, which has relatively expensive branches and no conditional
> operations beyond the base architecture conditional-set instructions.  At
> one point I have concluded it may make sense to release this code to the
> general public, especially as some of the conditional execution sequences
> will trigger for targets we already have support for.  Naturally as a part
> of a proper upstream submission I chose to add suitable test cases.
>
>  Now these test cases triggered a lot of issues in our existing code and
> as I fixed them what was supposed to be a couple of patches has turned
> into this humongous patch series, including a branch costing model rework.
> Oh well.
>
>  Please see individual change descriptions for the details.  The overall
> patch series structure is as follows:
>
> - 01-02 add test cases covering the existing state that won't change
>   throughout the patch series,
>
> - 03-08 make small preparatory clean-ups that do not change semantics,
>
> - 09-13 implement a branch cost model rework and add the associated test
>   cases,
>
> - 14-24 make various improvements for integer conditional operations and
>   add the associated test cases,
>
> - 25-28 add generic `movMODEcc' support and the associated test cases,
>
> - 29-31 add generic `addMODEcc' support and the associated test cases,
>
> - 32-44 make various improvements for floating-point conditional
>   operations and add the associated test cases.
>
> There is potential here for middle end improvement, in particular branch
> costing is already documented in if-cvt.cc to be intended to consistently
> use BRANCH_COST, and then the generic conditional-move and conditional-add
> sequences could I suppose be emitted there in a target-agnostic way rather
> than being supplied by the backend.  This I suppose could be investigated
> in the future if the RISC-V approach turned out potentially useful for
> other targets.
>
>  This has been so far verified as follows, using SiFive HiFive Unmatched
> hardware and the `riscv64-linux-gnu' target:
>
> - New target test cases have been run with `-mtune=sifive-5-series',
>   `-mtune=sifive-5-series/-march=rv32gc/-mabi=ilp32d' and
>   `-mtune=sifive-5-series/-mmovcc/-mbranch-cost=8' DejaGNU board options.
>
> - The C language test suite has been run at significant points in the
>   patch series with `-mtune=sifive-5-series' and (past 26/44) also with
>   `-mtune=sifive-5-series/-mmovcc/-mbranch-cost=8', and selectively with
>   `-mtune=sifive-7-series' and
>   `-mtune=sifive-7-series/-mmovcc/-mbranch-cost=8' DejaGNU board options.
>
> Since this is huge and every test iteration takes a couple of hours I will
> continue running testing and may investigate running QEMU testing for the
> features the Unmatched does not support such as Zicond.  I don't expect
> real issues however.
>
>  There are a bunch of issues triggered with `-mmovcc/-mbranch-cost=8' or
> with lone `-mbranch-cost=8' even and the vector test cases, which are
> either due to match patterns expecting an assembly label that has been
> reordered or are similar to PR target/112092 and which are not a problem
> with this patch series, but rather one with the vector testsuite or code.
>
>  Any questions, comments, or concerns?  Otherwise OK to apply?
>
>   Maciej

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 01/44] testsuite: Add cases for conditional-move and conditional-add operations
  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
  0 siblings, 1 reply; 101+ messages in thread
From: Kito Cheng @ 2023-11-19  5:52 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Palmer Dabbelt

ok

On Sun, Nov 19, 2023 at 1:35 PM Maciej W. Rozycki <macro@embecosm.com> wrote:
>
> Add generic execution tests for expressions that are expected to expand
> to conditional-move and conditional-add operations where supported.  To
> ensure no corner case escapes all relational operators are extensively
> covered for integer comparisons and all ordered operators are covered
> for floating-point comparisons.  Unordered operators are not covered at
> this point as they'd require a different input data set.
>
>         gcc/testsuite/
>         * gcc.dg/torture/addieq.c: New test.
>         * gcc.dg/torture/addifeq.c: New test.
>         * gcc.dg/torture/addifge.c: New test.
>         * gcc.dg/torture/addifgt.c: New test.
>         * gcc.dg/torture/addifle.c: New test.
>         * gcc.dg/torture/addiflt.c: New test.
>         * gcc.dg/torture/addifne.c: New test.
>         * gcc.dg/torture/addige.c: New test.
>         * gcc.dg/torture/addigeu.c: New test.
>         * gcc.dg/torture/addigt.c: New test.
>         * gcc.dg/torture/addigtu.c: New test.
>         * gcc.dg/torture/addile.c: New test.
>         * gcc.dg/torture/addileu.c: New test.
>         * gcc.dg/torture/addilt.c: New test.
>         * gcc.dg/torture/addiltu.c: New test.
>         * gcc.dg/torture/addine.c: New test.
>         * gcc.dg/torture/addleq.c: New test.
>         * gcc.dg/torture/addlfeq.c: New test.
>         * gcc.dg/torture/addlfge.c: New test.
>         * gcc.dg/torture/addlfgt.c: New test.
>         * gcc.dg/torture/addlfle.c: New test.
>         * gcc.dg/torture/addlflt.c: New test.
>         * gcc.dg/torture/addlfne.c: New test.
>         * gcc.dg/torture/addlge.c: New test.
>         * gcc.dg/torture/addlgeu.c: New test.
>         * gcc.dg/torture/addlgt.c: New test.
>         * gcc.dg/torture/addlgtu.c: New test.
>         * gcc.dg/torture/addlle.c: New test.
>         * gcc.dg/torture/addlleu.c: New test.
>         * gcc.dg/torture/addllt.c: New test.
>         * gcc.dg/torture/addlltu.c: New test.
>         * gcc.dg/torture/addlne.c: New test.
>         * gcc.dg/torture/movieq.c: New test.
>         * gcc.dg/torture/movifeq.c: New test.
>         * gcc.dg/torture/movifge.c: New test.
>         * gcc.dg/torture/movifgt.c: New test.
>         * gcc.dg/torture/movifle.c: New test.
>         * gcc.dg/torture/moviflt.c: New test.
>         * gcc.dg/torture/movifne.c: New test.
>         * gcc.dg/torture/movige.c: New test.
>         * gcc.dg/torture/movigeu.c: New test.
>         * gcc.dg/torture/movigt.c: New test.
>         * gcc.dg/torture/movigtu.c: New test.
>         * gcc.dg/torture/movile.c: New test.
>         * gcc.dg/torture/movileu.c: New test.
>         * gcc.dg/torture/movilt.c: New test.
>         * gcc.dg/torture/moviltu.c: New test.
>         * gcc.dg/torture/movine.c: New test.
>         * gcc.dg/torture/movleq.c: New test.
>         * gcc.dg/torture/movlfeq.c: New test.
>         * gcc.dg/torture/movlfge.c: New test.
>         * gcc.dg/torture/movlfgt.c: New test.
>         * gcc.dg/torture/movlfle.c: New test.
>         * gcc.dg/torture/movlflt.c: New test.
>         * gcc.dg/torture/movlfne.c: New test.
>         * gcc.dg/torture/movlge.c: New test.
>         * gcc.dg/torture/movlgeu.c: New test.
>         * gcc.dg/torture/movlgt.c: New test.
>         * gcc.dg/torture/movlgtu.c: New test.
>         * gcc.dg/torture/movlle.c: New test.
>         * gcc.dg/torture/movlleu.c: New test.
>         * gcc.dg/torture/movllt.c: New test.
>         * gcc.dg/torture/movlltu.c: New test.
>         * gcc.dg/torture/movlne.c: New test.
> ---
>  gcc/testsuite/gcc.dg/torture/addieq.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addifeq.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addifge.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addifgt.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addifle.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addiflt.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addifne.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addige.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addigeu.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addigt.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addigtu.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addile.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addileu.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addilt.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addiltu.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addine.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addleq.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addlfeq.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addlfge.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addlfgt.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addlfle.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addlflt.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addlfne.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addlge.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addlgeu.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addlgt.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addlgtu.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addlle.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addlleu.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addllt.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addlltu.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/addlne.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movieq.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movifeq.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movifge.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movifgt.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movifle.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/moviflt.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movifne.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movige.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movigeu.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movigt.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movigtu.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movile.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movileu.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movilt.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/moviltu.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movine.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movleq.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movlfeq.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movlfge.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movlfgt.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movlfle.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movlflt.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movlfne.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movlge.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movlgeu.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movlgt.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movlgtu.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movlle.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movlleu.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movllt.c  |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movlltu.c |   31 +++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/torture/movlne.c  |   31 +++++++++++++++++++++++++++++++
>  64 files changed, 1984 insertions(+)
>
> gcc-test-movcc.diff
> Index: gcc/gcc/testsuite/gcc.dg/torture/addieq.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addieq.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addieq (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w == x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addieq (-1, -1, 12, 23) != 35)
> +    return 1;
> +  if (addieq (-1, 3, 12, 23) != 12)
> +    return 1;
> +  if (addieq (1, 3, 12, 23) != 12)
> +    return 1;
> +  if (addieq (3, 3, 12, 23) != 35)
> +    return 1;
> +  if (addieq (5, 3, 12, 23) != 12)
> +    return 1;
> +  if (addieq (3, -1, 12, 23) != 12)
> +    return 1;
> +  if (addieq (3, 1, 12, 23) != 12)
> +    return 1;
> +  if (addieq (3, 5, 12, 23) != 12)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addifeq.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addifeq.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addifeq (double w, double x, int_t y, int_t z)
> +{
> +  return w == x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addifeq (-1.0, -1.0, 12, 23) != 35)
> +    return 1;
> +  if (addifeq (-1.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (addifeq (1.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (addifeq (3.0, 3.0, 12, 23) != 35)
> +    return 1;
> +  if (addifeq (5.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (addifeq (3.0, -1.0, 12, 23) != 12)
> +    return 1;
> +  if (addifeq (3.0, 1.0, 12, 23) != 12)
> +    return 1;
> +  if (addifeq (3.0, 5.0, 12, 23) != 12)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addifge.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addifge.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addifge (double w, double x, int_t y, int_t z)
> +{
> +  return w >= x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addifge (-1.0, -1.0, 12, 23) != 35)
> +    return 1;
> +  if (addifge (-1.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (addifge (1.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (addifge (3.0, 3.0, 12, 23) != 35)
> +    return 1;
> +  if (addifge (5.0, 3.0, 12, 23) != 35)
> +    return 1;
> +  if (addifge (3.0, -1.0, 12, 23) != 35)
> +    return 1;
> +  if (addifge (3.0, 1.0, 12, 23) != 35)
> +    return 1;
> +  if (addifge (3.0, 5.0, 12, 23) != 12)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addifgt.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addifgt.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addifgt (double w, double x, int_t y, int_t z)
> +{
> +  return w > x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addifgt (-1.0, -1.0, 12, 23) != 12)
> +    return 1;
> +  if (addifgt (-1.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (addifgt (1.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (addifgt (3.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (addifgt (5.0, 3.0, 12, 23) != 35)
> +    return 1;
> +  if (addifgt (3.0, -1.0, 12, 23) != 35)
> +    return 1;
> +  if (addifgt (3.0, 1.0, 12, 23) != 35)
> +    return 1;
> +  if (addifgt (3.0, 5.0, 12, 23) != 12)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addifle.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addifle.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addifle (double w, double x, int_t y, int_t z)
> +{
> +  return w <= x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addifle (-1.0, -1.0, 12, 23) != 35)
> +    return 1;
> +  if (addifle (-1.0, 3.0, 12, 23) != 35)
> +    return 1;
> +  if (addifle (1.0, 3.0, 12, 23) != 35)
> +    return 1;
> +  if (addifle (3.0, 3.0, 12, 23) != 35)
> +    return 1;
> +  if (addifle (5.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (addifle (3.0, -1.0, 12, 23) != 12)
> +    return 1;
> +  if (addifle (3.0, 1.0, 12, 23) != 12)
> +    return 1;
> +  if (addifle (3.0, 5.0, 12, 23) != 35)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addiflt.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addiflt.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addiflt (double w, double x, int_t y, int_t z)
> +{
> +  return w < x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addiflt (-1.0, -1.0, 12, 23) != 12)
> +    return 1;
> +  if (addiflt (-1.0, 3.0, 12, 23) != 35)
> +    return 1;
> +  if (addiflt (1.0, 3.0, 12, 23) != 35)
> +    return 1;
> +  if (addiflt (3.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (addiflt (5.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (addiflt (3.0, -1.0, 12, 23) != 12)
> +    return 1;
> +  if (addiflt (3.0, 1.0, 12, 23) != 12)
> +    return 1;
> +  if (addiflt (3.0, 5.0, 12, 23) != 35)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addifne.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addifne.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addifne (double w, double x, int_t y, int_t z)
> +{
> +  return w != x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addifne (-1.0, -1.0, 12, 23) != 12)
> +    return 1;
> +  if (addifne (-1.0, 3.0, 12, 23) != 35)
> +    return 1;
> +  if (addifne (1.0, 3.0, 12, 23) != 35)
> +    return 1;
> +  if (addifne (3.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (addifne (5.0, 3.0, 12, 23) != 35)
> +    return 1;
> +  if (addifne (3.0, -1.0, 12, 23) != 35)
> +    return 1;
> +  if (addifne (3.0, 1.0, 12, 23) != 35)
> +    return 1;
> +  if (addifne (3.0, 5.0, 12, 23) != 35)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addige.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addige.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addige (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addige (-1, -1, 12, 23) != 35)
> +    return 1;
> +  if (addige (-1, 3, 12, 23) != 12)
> +    return 1;
> +  if (addige (1, 3, 12, 23) != 12)
> +    return 1;
> +  if (addige (3, 3, 12, 23) != 35)
> +    return 1;
> +  if (addige (5, 3, 12, 23) != 35)
> +    return 1;
> +  if (addige (3, -1, 12, 23) != 35)
> +    return 1;
> +  if (addige (3, 1, 12, 23) != 35)
> +    return 1;
> +  if (addige (3, 5, 12, 23) != 12)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addigeu.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addigeu.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef unsigned int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addigeu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addigeu (-1, -1, 12, 23) != 35)
> +    return 1;
> +  if (addigeu (-1, 3, 12, 23) != 35)
> +    return 1;
> +  if (addigeu (1, 3, 12, 23) != 12)
> +    return 1;
> +  if (addigeu (3, 3, 12, 23) != 35)
> +    return 1;
> +  if (addigeu (5, 3, 12, 23) != 35)
> +    return 1;
> +  if (addigeu (3, -1, 12, 23) != 12)
> +    return 1;
> +  if (addigeu (3, 1, 12, 23) != 35)
> +    return 1;
> +  if (addigeu (3, 5, 12, 23) != 12)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addigt.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addigt.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addigt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addigt (-1, -1, 12, 23) != 12)
> +    return 1;
> +  if (addigt (-1, 3, 12, 23) != 12)
> +    return 1;
> +  if (addigt (1, 3, 12, 23) != 12)
> +    return 1;
> +  if (addigt (3, 3, 12, 23) != 12)
> +    return 1;
> +  if (addigt (5, 3, 12, 23) != 35)
> +    return 1;
> +  if (addigt (3, -1, 12, 23) != 35)
> +    return 1;
> +  if (addigt (3, 1, 12, 23) != 35)
> +    return 1;
> +  if (addigt (3, 5, 12, 23) != 12)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addigtu.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addigtu.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef unsigned int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addigtu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addigtu (-1, -1, 12, 23) != 12)
> +    return 1;
> +  if (addigtu (-1, 3, 12, 23) != 35)
> +    return 1;
> +  if (addigtu (1, 3, 12, 23) != 12)
> +    return 1;
> +  if (addigtu (3, 3, 12, 23) != 12)
> +    return 1;
> +  if (addigtu (5, 3, 12, 23) != 35)
> +    return 1;
> +  if (addigtu (3, -1, 12, 23) != 12)
> +    return 1;
> +  if (addigtu (3, 1, 12, 23) != 35)
> +    return 1;
> +  if (addigtu (3, 5, 12, 23) != 12)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addile.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addile.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addile (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addile (-1, -1, 12, 23) != 35)
> +    return 1;
> +  if (addile (-1, 3, 12, 23) != 35)
> +    return 1;
> +  if (addile (1, 3, 12, 23) != 35)
> +    return 1;
> +  if (addile (3, 3, 12, 23) != 35)
> +    return 1;
> +  if (addile (5, 3, 12, 23) != 12)
> +    return 1;
> +  if (addile (3, -1, 12, 23) != 12)
> +    return 1;
> +  if (addile (3, 1, 12, 23) != 12)
> +    return 1;
> +  if (addile (3, 5, 12, 23) != 35)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addileu.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addileu.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef unsigned int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addileu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addileu (-1, -1, 12, 23) != 35)
> +    return 1;
> +  if (addileu (-1, 3, 12, 23) != 12)
> +    return 1;
> +  if (addileu (1, 3, 12, 23) != 35)
> +    return 1;
> +  if (addileu (3, 3, 12, 23) != 35)
> +    return 1;
> +  if (addileu (5, 3, 12, 23) != 12)
> +    return 1;
> +  if (addileu (3, -1, 12, 23) != 35)
> +    return 1;
> +  if (addileu (3, 1, 12, 23) != 12)
> +    return 1;
> +  if (addileu (3, 5, 12, 23) != 35)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addilt.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addilt.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addilt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addilt (-1, -1, 12, 23) != 12)
> +    return 1;
> +  if (addilt (-1, 3, 12, 23) != 35)
> +    return 1;
> +  if (addilt (1, 3, 12, 23) != 35)
> +    return 1;
> +  if (addilt (3, 3, 12, 23) != 12)
> +    return 1;
> +  if (addilt (5, 3, 12, 23) != 12)
> +    return 1;
> +  if (addilt (3, -1, 12, 23) != 12)
> +    return 1;
> +  if (addilt (3, 1, 12, 23) != 12)
> +    return 1;
> +  if (addilt (3, 5, 12, 23) != 35)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addiltu.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addiltu.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef unsigned int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addiltu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addiltu (-1, -1, 12, 23) != 12)
> +    return 1;
> +  if (addiltu (-1, 3, 12, 23) != 12)
> +    return 1;
> +  if (addiltu (1, 3, 12, 23) != 35)
> +    return 1;
> +  if (addiltu (3, 3, 12, 23) != 12)
> +    return 1;
> +  if (addiltu (5, 3, 12, 23) != 12)
> +    return 1;
> +  if (addiltu (3, -1, 12, 23) != 35)
> +    return 1;
> +  if (addiltu (3, 1, 12, 23) != 12)
> +    return 1;
> +  if (addiltu (3, 5, 12, 23) != 35)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addine.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addine.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addine (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w != x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addine (-1, -1, 12, 23) != 12)
> +    return 1;
> +  if (addine (-1, 3, 12, 23) != 35)
> +    return 1;
> +  if (addine (1, 3, 12, 23) != 35)
> +    return 1;
> +  if (addine (3, 3, 12, 23) != 12)
> +    return 1;
> +  if (addine (5, 3, 12, 23) != 35)
> +    return 1;
> +  if (addine (3, -1, 12, 23) != 35)
> +    return 1;
> +  if (addine (3, 1, 12, 23) != 35)
> +    return 1;
> +  if (addine (3, 5, 12, 23) != 35)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addleq.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addleq.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addleq (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w == x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addleq (-1L, -1L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addleq (-1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addleq (1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addleq (3L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addleq (5L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addleq (3L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addleq (3L, 1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addleq (3L, 5L, 12L, 23L) != 12L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addlfeq.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addlfeq.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addlfeq (double w, double x, int_t y, int_t z)
> +{
> +  return w == x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addlfeq (-1.0, -1.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfeq (-1.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlfeq (1.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlfeq (3.0, 3.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfeq (5.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlfeq (3.0, -1.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlfeq (3.0, 1.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlfeq (3.0, 5.0, 12L, 23L) != 12L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addlfge.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addlfge.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addlfge (double w, double x, int_t y, int_t z)
> +{
> +  return w >= x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addlfge (-1.0, -1.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfge (-1.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlfge (1.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlfge (3.0, 3.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfge (5.0, 3.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfge (3.0, -1.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfge (3.0, 1.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfge (3.0, 5.0, 12L, 23L) != 12L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addlfgt.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addlfgt.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addlfgt (double w, double x, int_t y, int_t z)
> +{
> +  return w > x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addlfgt (-1.0, -1.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlfgt (-1.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlfgt (1.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlfgt (3.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlfgt (5.0, 3.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfgt (3.0, -1.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfgt (3.0, 1.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfgt (3.0, 5.0, 12L, 23L) != 12L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addlfle.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addlfle.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addlfle (double w, double x, int_t y, int_t z)
> +{
> +  return w <= x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addlfle (-1.0, -1.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfle (-1.0, 3.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfle (1.0, 3.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfle (3.0, 3.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfle (5.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlfle (3.0, -1.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlfle (3.0, 1.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlfle (3.0, 5.0, 12L, 23L) != 35L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addlflt.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addlflt.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addlflt (double w, double x, int_t y, int_t z)
> +{
> +  return w < x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addlflt (-1.0, -1.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlflt (-1.0, 3.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlflt (1.0, 3.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlflt (3.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlflt (5.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlflt (3.0, -1.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlflt (3.0, 1.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlflt (3.0, 5.0, 12L, 23L) != 35L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addlfne.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addlfne.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addlfne (double w, double x, int_t y, int_t z)
> +{
> +  return w != x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addlfne (-1.0, -1.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlfne (-1.0, 3.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfne (1.0, 3.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfne (3.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlfne (5.0, 3.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfne (3.0, -1.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfne (3.0, 1.0, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlfne (3.0, 5.0, 12L, 23L) != 35L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addlge.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addlge.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addlge (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addlge (-1L, -1L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlge (-1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlge (1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlge (3L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlge (5L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlge (3L, -1L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlge (3L, 1L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlge (3L, 5L, 12L, 23L) != 12L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addlgeu.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addlgeu.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef unsigned long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addlgeu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addlgeu (-1L, -1L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlgeu (-1L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlgeu (1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlgeu (3L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlgeu (5L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlgeu (3L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlgeu (3L, 1L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlgeu (3L, 5L, 12L, 23L) != 12L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addlgt.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addlgt.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addlgt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addlgt (-1L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlgt (-1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlgt (1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlgt (3L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlgt (5L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlgt (3L, -1L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlgt (3L, 1L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlgt (3L, 5L, 12L, 23L) != 12L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addlgtu.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addlgtu.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef unsigned long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addlgtu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addlgtu (-1L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlgtu (-1L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlgtu (1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlgtu (3L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlgtu (5L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlgtu (3L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlgtu (3L, 1L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlgtu (3L, 5L, 12L, 23L) != 12L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addlle.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addlle.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addlle (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addlle (-1L, -1L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlle (-1L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlle (1L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlle (3L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlle (5L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlle (3L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlle (3L, 1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlle (3L, 5L, 12L, 23L) != 35L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addlleu.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addlleu.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef unsigned long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addlleu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addlleu (-1L, -1L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlleu (-1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlleu (1L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlleu (3L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlleu (5L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlleu (3L, -1L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlleu (3L, 1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlleu (3L, 5L, 12L, 23L) != 35L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addllt.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addllt.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addllt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addllt (-1L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addllt (-1L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addllt (1L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addllt (3L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addllt (5L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addllt (3L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addllt (3L, 1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addllt (3L, 5L, 12L, 23L) != 35L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addlltu.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addlltu.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef unsigned long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addlltu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addlltu (-1L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlltu (-1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlltu (1L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlltu (3L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlltu (5L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlltu (3L, -1L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlltu (3L, 1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlltu (3L, 5L, 12L, 23L) != 35L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/addlne.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/addlne.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +addlne (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w != x ? y + z : y;
> +}
> +
> +int
> +main (void)
> +{
> +  if (addlne (-1L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlne (-1L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlne (1L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlne (3L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (addlne (5L, 3L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlne (3L, -1L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlne (3L, 1L, 12L, 23L) != 35L)
> +    return 1;
> +  if (addlne (3L, 5L, 12L, 23L) != 35L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movieq.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movieq.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movieq (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w == x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movieq (-1, -1, 12, 23) != 12)
> +    return 1;
> +  if (movieq (-1, 3, 12, 23) != 23)
> +    return 1;
> +  if (movieq (1, 3, 12, 23) != 23)
> +    return 1;
> +  if (movieq (3, 3, 12, 23) != 12)
> +    return 1;
> +  if (movieq (5, 3, 12, 23) != 23)
> +    return 1;
> +  if (movieq (3, -1, 12, 23) != 23)
> +    return 1;
> +  if (movieq (3, 1, 12, 23) != 23)
> +    return 1;
> +  if (movieq (3, 5, 12, 23) != 23)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movifeq.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movifeq.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movifeq (double w, double x, int_t y, int_t z)
> +{
> +  return w == x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movifeq (-1.0, -1.0, 12, 23) != 12)
> +    return 1;
> +  if (movifeq (-1.0, 3.0, 12, 23) != 23)
> +    return 1;
> +  if (movifeq (1.0, 3.0, 12, 23) != 23)
> +    return 1;
> +  if (movifeq (3.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (movifeq (5.0, 3.0, 12, 23) != 23)
> +    return 1;
> +  if (movifeq (3.0, -1.0, 12, 23) != 23)
> +    return 1;
> +  if (movifeq (3.0, 1.0, 12, 23) != 23)
> +    return 1;
> +  if (movifeq (3.0, 5.0, 12, 23) != 23)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movifge.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movifge.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movifge (double w, double x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movifge (-1.0, -1.0, 12, 23) != 12)
> +    return 1;
> +  if (movifge (-1.0, 3.0, 12, 23) != 23)
> +    return 1;
> +  if (movifge (1.0, 3.0, 12, 23) != 23)
> +    return 1;
> +  if (movifge (3.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (movifge (5.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (movifge (3.0, -1.0, 12, 23) != 12)
> +    return 1;
> +  if (movifge (3.0, 1.0, 12, 23) != 12)
> +    return 1;
> +  if (movifge (3.0, 5.0, 12, 23) != 23)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movifgt.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movifgt.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movifgt (double w, double x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movifgt (-1.0, -1.0, 12, 23) != 23)
> +    return 1;
> +  if (movifgt (-1.0, 3.0, 12, 23) != 23)
> +    return 1;
> +  if (movifgt (1.0, 3.0, 12, 23) != 23)
> +    return 1;
> +  if (movifgt (3.0, 3.0, 12, 23) != 23)
> +    return 1;
> +  if (movifgt (5.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (movifgt (3.0, -1.0, 12, 23) != 12)
> +    return 1;
> +  if (movifgt (3.0, 1.0, 12, 23) != 12)
> +    return 1;
> +  if (movifgt (3.0, 5.0, 12, 23) != 23)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movifle.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movifle.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movifle (double w, double x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movifle (-1.0, -1.0, 12, 23) != 12)
> +    return 1;
> +  if (movifle (-1.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (movifle (1.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (movifle (3.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (movifle (5.0, 3.0, 12, 23) != 23)
> +    return 1;
> +  if (movifle (3.0, -1.0, 12, 23) != 23)
> +    return 1;
> +  if (movifle (3.0, 1.0, 12, 23) != 23)
> +    return 1;
> +  if (movifle (3.0, 5.0, 12, 23) != 12)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/moviflt.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/moviflt.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +moviflt (double w, double x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (moviflt (-1.0, -1.0, 12, 23) != 23)
> +    return 1;
> +  if (moviflt (-1.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (moviflt (1.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (moviflt (3.0, 3.0, 12, 23) != 23)
> +    return 1;
> +  if (moviflt (5.0, 3.0, 12, 23) != 23)
> +    return 1;
> +  if (moviflt (3.0, -1.0, 12, 23) != 23)
> +    return 1;
> +  if (moviflt (3.0, 1.0, 12, 23) != 23)
> +    return 1;
> +  if (moviflt (3.0, 5.0, 12, 23) != 12)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movifne.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movifne.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movifne (double w, double x, int_t y, int_t z)
> +{
> +  return w != x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movifne (-1.0, -1.0, 12, 23) != 23)
> +    return 1;
> +  if (movifne (-1.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (movifne (1.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (movifne (3.0, 3.0, 12, 23) != 23)
> +    return 1;
> +  if (movifne (5.0, 3.0, 12, 23) != 12)
> +    return 1;
> +  if (movifne (3.0, -1.0, 12, 23) != 12)
> +    return 1;
> +  if (movifne (3.0, 1.0, 12, 23) != 12)
> +    return 1;
> +  if (movifne (3.0, 5.0, 12, 23) != 12)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movige.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movige.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movige (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movige (-1, -1, 12, 23) != 12)
> +    return 1;
> +  if (movige (-1, 3, 12, 23) != 23)
> +    return 1;
> +  if (movige (1, 3, 12, 23) != 23)
> +    return 1;
> +  if (movige (3, 3, 12, 23) != 12)
> +    return 1;
> +  if (movige (5, 3, 12, 23) != 12)
> +    return 1;
> +  if (movige (3, -1, 12, 23) != 12)
> +    return 1;
> +  if (movige (3, 1, 12, 23) != 12)
> +    return 1;
> +  if (movige (3, 5, 12, 23) != 23)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movigeu.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movigeu.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef unsigned int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movigeu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movigeu (-1, -1, 12, 23) != 12)
> +    return 1;
> +  if (movigeu (-1, 3, 12, 23) != 12)
> +    return 1;
> +  if (movigeu (1, 3, 12, 23) != 23)
> +    return 1;
> +  if (movigeu (3, 3, 12, 23) != 12)
> +    return 1;
> +  if (movigeu (5, 3, 12, 23) != 12)
> +    return 1;
> +  if (movigeu (3, -1, 12, 23) != 23)
> +    return 1;
> +  if (movigeu (3, 1, 12, 23) != 12)
> +    return 1;
> +  if (movigeu (3, 5, 12, 23) != 23)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movigt.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movigt.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movigt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movigt (-1, -1, 12, 23) != 23)
> +    return 1;
> +  if (movigt (-1, 3, 12, 23) != 23)
> +    return 1;
> +  if (movigt (1, 3, 12, 23) != 23)
> +    return 1;
> +  if (movigt (3, 3, 12, 23) != 23)
> +    return 1;
> +  if (movigt (5, 3, 12, 23) != 12)
> +    return 1;
> +  if (movigt (3, -1, 12, 23) != 12)
> +    return 1;
> +  if (movigt (3, 1, 12, 23) != 12)
> +    return 1;
> +  if (movigt (3, 5, 12, 23) != 23)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movigtu.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movigtu.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef unsigned int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movigtu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movigtu (-1, -1, 12, 23) != 23)
> +    return 1;
> +  if (movigtu (-1, 3, 12, 23) != 12)
> +    return 1;
> +  if (movigtu (1, 3, 12, 23) != 23)
> +    return 1;
> +  if (movigtu (3, 3, 12, 23) != 23)
> +    return 1;
> +  if (movigtu (5, 3, 12, 23) != 12)
> +    return 1;
> +  if (movigtu (3, -1, 12, 23) != 23)
> +    return 1;
> +  if (movigtu (3, 1, 12, 23) != 12)
> +    return 1;
> +  if (movigtu (3, 5, 12, 23) != 23)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movile.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movile.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movile (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movile (-1, -1, 12, 23) != 12)
> +    return 1;
> +  if (movile (-1, 3, 12, 23) != 12)
> +    return 1;
> +  if (movile (1, 3, 12, 23) != 12)
> +    return 1;
> +  if (movile (3, 3, 12, 23) != 12)
> +    return 1;
> +  if (movile (5, 3, 12, 23) != 23)
> +    return 1;
> +  if (movile (3, -1, 12, 23) != 23)
> +    return 1;
> +  if (movile (3, 1, 12, 23) != 23)
> +    return 1;
> +  if (movile (3, 5, 12, 23) != 12)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movileu.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movileu.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef unsigned int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movileu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movileu (-1, -1, 12, 23) != 12)
> +    return 1;
> +  if (movileu (-1, 3, 12, 23) != 23)
> +    return 1;
> +  if (movileu (1, 3, 12, 23) != 12)
> +    return 1;
> +  if (movileu (3, 3, 12, 23) != 12)
> +    return 1;
> +  if (movileu (5, 3, 12, 23) != 23)
> +    return 1;
> +  if (movileu (3, -1, 12, 23) != 12)
> +    return 1;
> +  if (movileu (3, 1, 12, 23) != 23)
> +    return 1;
> +  if (movileu (3, 5, 12, 23) != 12)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movilt.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movilt.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movilt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movilt (-1, -1, 12, 23) != 23)
> +    return 1;
> +  if (movilt (-1, 3, 12, 23) != 12)
> +    return 1;
> +  if (movilt (1, 3, 12, 23) != 12)
> +    return 1;
> +  if (movilt (3, 3, 12, 23) != 23)
> +    return 1;
> +  if (movilt (5, 3, 12, 23) != 23)
> +    return 1;
> +  if (movilt (3, -1, 12, 23) != 23)
> +    return 1;
> +  if (movilt (3, 1, 12, 23) != 23)
> +    return 1;
> +  if (movilt (3, 5, 12, 23) != 12)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/moviltu.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/moviltu.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef unsigned int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +moviltu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (moviltu (-1, -1, 12, 23) != 23)
> +    return 1;
> +  if (moviltu (-1, 3, 12, 23) != 23)
> +    return 1;
> +  if (moviltu (1, 3, 12, 23) != 12)
> +    return 1;
> +  if (moviltu (3, 3, 12, 23) != 23)
> +    return 1;
> +  if (moviltu (5, 3, 12, 23) != 23)
> +    return 1;
> +  if (moviltu (3, -1, 12, 23) != 12)
> +    return 1;
> +  if (moviltu (3, 1, 12, 23) != 23)
> +    return 1;
> +  if (moviltu (3, 5, 12, 23) != 12)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movine.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movine.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef int int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movine (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w != x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movine (-1, -1, 12, 23) != 23)
> +    return 1;
> +  if (movine (-1, 3, 12, 23) != 12)
> +    return 1;
> +  if (movine (1, 3, 12, 23) != 12)
> +    return 1;
> +  if (movine (3, 3, 12, 23) != 23)
> +    return 1;
> +  if (movine (5, 3, 12, 23) != 12)
> +    return 1;
> +  if (movine (3, -1, 12, 23) != 12)
> +    return 1;
> +  if (movine (3, 1, 12, 23) != 12)
> +    return 1;
> +  if (movine (3, 5, 12, 23) != 12)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movleq.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movleq.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movleq (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w == x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movleq (-1L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movleq (-1L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movleq (1L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movleq (3L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movleq (5L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movleq (3L, -1L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movleq (3L, 1L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movleq (3L, 5L, 12L, 23L) != 23L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movlfeq.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movlfeq.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movlfeq (double w, double x, int_t y, int_t z)
> +{
> +  return w == x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movlfeq (-1.0, -1.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfeq (-1.0, 3.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlfeq (1.0, 3.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlfeq (3.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfeq (5.0, 3.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlfeq (3.0, -1.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlfeq (3.0, 1.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlfeq (3.0, 5.0, 12L, 23L) != 23L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movlfge.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movlfge.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movlfge (double w, double x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movlfge (-1.0, -1.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfge (-1.0, 3.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlfge (1.0, 3.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlfge (3.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfge (5.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfge (3.0, -1.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfge (3.0, 1.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfge (3.0, 5.0, 12L, 23L) != 23L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movlfgt.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movlfgt.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movlfgt (double w, double x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movlfgt (-1.0, -1.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlfgt (-1.0, 3.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlfgt (1.0, 3.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlfgt (3.0, 3.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlfgt (5.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfgt (3.0, -1.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfgt (3.0, 1.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfgt (3.0, 5.0, 12L, 23L) != 23L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movlfle.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movlfle.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movlfle (double w, double x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movlfle (-1.0, -1.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfle (-1.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfle (1.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfle (3.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfle (5.0, 3.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlfle (3.0, -1.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlfle (3.0, 1.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlfle (3.0, 5.0, 12L, 23L) != 12L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movlflt.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movlflt.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movlflt (double w, double x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movlflt (-1.0, -1.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlflt (-1.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlflt (1.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlflt (3.0, 3.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlflt (5.0, 3.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlflt (3.0, -1.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlflt (3.0, 1.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlflt (3.0, 5.0, 12L, 23L) != 12L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movlfne.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movlfne.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movlfne (double w, double x, int_t y, int_t z)
> +{
> +  return w != x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movlfne (-1.0, -1.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlfne (-1.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfne (1.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfne (3.0, 3.0, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlfne (5.0, 3.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfne (3.0, -1.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfne (3.0, 1.0, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlfne (3.0, 5.0, 12L, 23L) != 12L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movlge.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movlge.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movlge (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movlge (-1L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlge (-1L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlge (1L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlge (3L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlge (5L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlge (3L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlge (3L, 1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlge (3L, 5L, 12L, 23L) != 23L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movlgeu.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movlgeu.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef unsigned long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movlgeu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movlgeu (-1L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlgeu (-1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlgeu (1L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlgeu (3L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlgeu (5L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlgeu (3L, -1L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlgeu (3L, 1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlgeu (3L, 5L, 12L, 23L) != 23L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movlgt.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movlgt.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movlgt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movlgt (-1L, -1L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlgt (-1L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlgt (1L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlgt (3L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlgt (5L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlgt (3L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlgt (3L, 1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlgt (3L, 5L, 12L, 23L) != 23L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movlgtu.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movlgtu.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef unsigned long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movlgtu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movlgtu (-1L, -1L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlgtu (-1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlgtu (1L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlgtu (3L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlgtu (5L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlgtu (3L, -1L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlgtu (3L, 1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlgtu (3L, 5L, 12L, 23L) != 23L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movlle.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movlle.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movlle (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movlle (-1L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlle (-1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlle (1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlle (3L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlle (5L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlle (3L, -1L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlle (3L, 1L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlle (3L, 5L, 12L, 23L) != 12L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movlleu.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movlleu.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef unsigned long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movlleu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movlleu (-1L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlleu (-1L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlleu (1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlleu (3L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlleu (5L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlleu (3L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlleu (3L, 1L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlleu (3L, 5L, 12L, 23L) != 12L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movllt.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movllt.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movllt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movllt (-1L, -1L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movllt (-1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movllt (1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movllt (3L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movllt (5L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movllt (3L, -1L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movllt (3L, 1L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movllt (3L, 5L, 12L, 23L) != 12L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movlltu.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movlltu.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef unsigned long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movlltu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movlltu (-1L, -1L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlltu (-1L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlltu (1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlltu (3L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlltu (5L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlltu (3L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlltu (3L, 1L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlltu (3L, 5L, 12L, 23L) != 12L)
> +    return 1;
> +  return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/torture/movlne.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/torture/movlne.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +
> +typedef long int_t;
> +
> +__attribute__ ((noinline)) int_t
> +movlne (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w != x ? y : z;
> +}
> +
> +int
> +main (void)
> +{
> +  if (movlne (-1L, -1L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlne (-1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlne (1L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlne (3L, 3L, 12L, 23L) != 23L)
> +    return 1;
> +  if (movlne (5L, 3L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlne (3L, -1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlne (3L, 1L, 12L, 23L) != 12L)
> +    return 1;
> +  if (movlne (3L, 5L, 12L, 23L) != 12L)
> +    return 1;
> +  return 0;
> +}

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 03/44] RISC-V: Reorder comment on SFB patterns
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Kito Cheng @ 2023-11-19  5:53 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Palmer Dabbelt

LGTM

On Sun, Nov 19, 2023 at 1:36 PM Maciej W. Rozycki <macro@embecosm.com> wrote:
>
> Our `mov<mode>cc' expander is no longer specific to short forward branch
> targets, so move its associated comment accordingly.
>
>         gcc/
>         * config/riscv/riscv.md (mov<mode>cc): Move comment on SFB
>         patterns over to...
>         (*mov<GPR:mode><X:mode>cc): ... here.
> ---
>  gcc/config/riscv/riscv.md |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> gcc-riscv-sfb-comment-move.diff
> Index: gcc-master/gcc/config/riscv/riscv.md
> ===================================================================
> --- gcc-master.orig/gcc/config/riscv/riscv.md
> +++ gcc-master/gcc/config/riscv/riscv.md
> @@ -2655,8 +2655,6 @@
>    [(set_attr "type" "branch")
>     (set_attr "mode" "none")])
>
> -;; Patterns for implementations that optimize short forward branches.
> -
>  (define_expand "mov<mode>cc"
>    [(set (match_operand:GPR 0 "register_operand")
>         (if_then_else:GPR (match_operand 1 "comparison_operator")
> @@ -2671,6 +2669,8 @@
>      FAIL;
>  })
>
> +;; Patterns for implementations that optimize short forward branches.
> +
>  (define_insn "*mov<GPR:mode><X:mode>cc"
>    [(set (match_operand:GPR 0 "register_operand" "=r,r")
>         (if_then_else:GPR

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 07/44] RISC-V: Use `nullptr' in `riscv_expand_conditional_move'
  2023-11-19  5:36 ` [PATCH 07/44] RISC-V: Use `nullptr' " Maciej W. Rozycki
@ 2023-11-19  5:53   ` Kito Cheng
  0 siblings, 0 replies; 101+ messages in thread
From: Kito Cheng @ 2023-11-19  5:53 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Palmer Dabbelt

LGTM

On Sun, Nov 19, 2023 at 1:37 PM Maciej W. Rozycki <macro@embecosm.com> wrote:
>
> Use `nullptr' for consistency rather than 0 to initialize `invert_ptr'.
>
>         gcc/
>         * config/riscv/riscv.cc (riscv_expand_conditional_move): Use
>         `nullptr' rather than 0 to initialize a pointer.
> ---
>  gcc/config/riscv/riscv.cc |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> gcc-riscv-expand-conditional-move-nullptr.diff
> Index: gcc/gcc/config/riscv/riscv.cc
> ===================================================================
> --- gcc.orig/gcc/config/riscv/riscv.cc
> +++ gcc/gcc/config/riscv/riscv.cc
> @@ -4024,7 +4024,7 @@ riscv_expand_conditional_move (rtx dest,
>        if (!equality_operator (op, VOIDmode) || op1 != CONST0_RTX (mode))
>         {
>           enum rtx_code new_code = NE;
> -         bool *invert_ptr = 0;
> +         bool *invert_ptr = nullptr;
>           bool invert = false;
>
>           if (code == LE || code == GE)

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 02/44] RISC-V/testsuite: Add cases for integer SFB cond-move operations
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Kito Cheng @ 2023-11-19  5:53 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Palmer Dabbelt

LGTM

On Sun, Nov 19, 2023 at 1:36 PM Maciej W. Rozycki <macro@embecosm.com> wrote:
>
> Verify, for short forward branch targets and the conditional-move
> operations that already work as expected, that if-conversion triggers
> via `noce_try_cmove' already at `-mbranch-cost=1' and that extraneous
> instructions such as SNEZ, etc. are not present in output.  Cover all
> integer relational operations to make sure no corner case escapes.
>
>         gcc/testsuite/
>         * gcc.target/riscv/movdieq-sfb.c: New test.
>         * gcc.target/riscv/movdige-sfb.c: New test.
>         * gcc.target/riscv/movdigeu-sfb.c: New test.
>         * gcc.target/riscv/movdigt-sfb.c: New test.
>         * gcc.target/riscv/movdigtu-sfb.c: New test.
>         * gcc.target/riscv/movdile-sfb.c: New test.
>         * gcc.target/riscv/movdileu-sfb.c: New test.
>         * gcc.target/riscv/movdilt-sfb.c: New test.
>         * gcc.target/riscv/movdiltu-sfb.c: New test.
>         * gcc.target/riscv/movdine-sfb.c: New test.
>         * gcc.target/riscv/movsieq-sfb.c: New test.
>         * gcc.target/riscv/movsige-sfb.c: New test.
>         * gcc.target/riscv/movsigeu-sfb.c: New test.
>         * gcc.target/riscv/movsigt-sfb.c: New test.
>         * gcc.target/riscv/movsigtu-sfb.c: New test.
>         * gcc.target/riscv/movsile-sfb.c: New test.
>         * gcc.target/riscv/movsileu-sfb.c: New test.
>         * gcc.target/riscv/movsilt-sfb.c: New test.
>         * gcc.target/riscv/movsiltu-sfb.c: New test.
>         * gcc.target/riscv/movsine-sfb.c: New test.
> ---
>  gcc/testsuite/gcc.target/riscv/movdieq-sfb.c  |   25 +++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdige-sfb.c  |   26 ++++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdigeu-sfb.c |   26 ++++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdigt-sfb.c  |   26 ++++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdigtu-sfb.c |   26 ++++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdile-sfb.c  |   26 ++++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdileu-sfb.c |   26 ++++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdilt-sfb.c  |   26 ++++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdiltu-sfb.c |   26 ++++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdine-sfb.c  |   25 +++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsieq-sfb.c  |   25 +++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsige-sfb.c  |   26 ++++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsigeu-sfb.c |   26 ++++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsigt-sfb.c  |   26 ++++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsigtu-sfb.c |   26 ++++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsile-sfb.c  |   26 ++++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsileu-sfb.c |   26 ++++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsilt-sfb.c  |   26 ++++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsiltu-sfb.c |   26 ++++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsine-sfb.c  |   25 +++++++++++++++++++++++++
>  20 files changed, 516 insertions(+)
>
> gcc-riscv-test-movcc.diff
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdieq-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdieq-sfb.c
> @@ -0,0 +1,25 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdieq (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w == x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       bne     a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdige-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdige-sfb.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdige (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       blt     a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdigeu-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdigeu-sfb.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdigeu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       bltu    a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdigt-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdigt-sfb.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdigt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       ble     a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdigtu-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdigtu-sfb.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdigtu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       bleu    a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdile-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdile-sfb.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdile (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       bgt     a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|bgt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdileu-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdileu-sfb.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdileu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       bgtu    a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdilt-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdilt-sfb.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdilt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       bge     a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdiltu-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdiltu-sfb.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdiltu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       bgeu    a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdine-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdine-sfb.c
> @@ -0,0 +1,25 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdine (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w != x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       beq     a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsieq-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsieq-sfb.c
> @@ -0,0 +1,25 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsieq (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w == x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       bne     a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsige-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsige-sfb.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsige (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       blt     a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsigeu-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsigeu-sfb.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef unsigned int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsigeu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       bltu    a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsigt-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsigt-sfb.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsigt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       ble     a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bgt|ble)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsigtu-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsigtu-sfb.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef unsigned int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsigtu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       bleu    a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsile-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsile-sfb.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsile (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       bgt     a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsileu-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsileu-sfb.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef unsigned int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsileu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       bgtu    a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsilt-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsilt-sfb.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsilt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       bge     a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsiltu-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsiltu-sfb.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef unsigned int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsiltu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       bgeu    a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsine-sfb.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsine-sfb.c
> @@ -0,0 +1,25 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
> +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsine (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w != x ? y : z;
> +}
> +
> +/* Expect short forward branch assembly like:
> +
> +       beq     a0,a1,1f        # movcc
> +       mv      a3,a2
> +1:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 04/44] RISC-V: Sanitise NEED_EQ_NE_P case with `riscv_emit_int_compare'
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Kito Cheng @ 2023-11-19  5:53 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Palmer Dabbelt

LGTM

On Sun, Nov 19, 2023 at 1:36 PM Maciej W. Rozycki <macro@embecosm.com> wrote:
>
> For the NEED_EQ_NE_P `riscv_emit_int_compare' is documented to only emit
> EQ or NE comparisons against zero, however it does not catch incorrect
> use where a non-equality comparison has been requested and falls through
> to the general case then.  Add a safety guard to catch such a case then.
>
> Arguably the NEED_EQ_NE_P case would best be moved into a function of
> its own, but let's leave it for a separate cleanup.
>
>         gcc/
>         * config/riscv/riscv.cc (riscv_emit_int_compare): Bail out if
>         NEED_EQ_NE_P but the comparison is neither EQ nor NE.
> ---
> FWIW the structure of code here clearly shows the NEED_EQ_NE_P case has
> been bolted on as an afterthought rather than how this piece would look
> if written from scratch right away.  Let's defer any further cleanups at
> this stage of the development cycle though.
> ---
>  gcc/config/riscv/riscv.cc |    1 +
>  1 file changed, 1 insertion(+)
>
> gcc-riscv-emit-int-compare-need-eq-ne.diff
> Index: gcc/gcc/config/riscv/riscv.cc
> ===================================================================
> --- gcc.orig/gcc/config/riscv/riscv.cc
> +++ gcc/gcc/config/riscv/riscv.cc
> @@ -3779,6 +3779,7 @@ riscv_emit_int_compare (enum rtx_code *c
>           *op1 = const0_rtx;
>           return;
>         }
> +      gcc_unreachable ();
>      }
>
>    if (splittable_const_int_operand (*op1, VOIDmode))

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 05/44] RISC-V: Fix `mode' usage in `riscv_expand_conditional_move'
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Kito Cheng @ 2023-11-19  5:54 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Palmer Dabbelt

LGTM

On Sun, Nov 19, 2023 at 1:36 PM Maciej W. Rozycki <macro@embecosm.com> wrote:
>
> In `riscv_expand_conditional_move' `mode' is initialized right away from
> `GET_MODE (dest)', so remove needless references that refrain from using
> the local variable.
>
>         gcc/
>         * config/riscv/riscv.cc (riscv_expand_conditional_move): Use
>         `mode' for `GET_MODE (dest)' throughout.
> ---
>  gcc/config/riscv/riscv.cc |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> gcc-riscv-expand-conditional-move-mode-dest.diff
> Index: gcc/gcc/config/riscv/riscv.cc
> ===================================================================
> --- gcc.orig/gcc/config/riscv/riscv.cc
> +++ gcc/gcc/config/riscv/riscv.cc
> @@ -3999,8 +3999,8 @@ riscv_expand_conditional_move (rtx dest,
>          arm of the conditional move.  That allows us to support more
>          cases for extensions which are more general than SFB.  But
>          does mean we need to force CONS into a register at this point.  */
> -      cons = force_reg (GET_MODE (dest), cons);
> -      emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (GET_MODE (dest),
> +      cons = force_reg (mode, cons);
> +      emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (mode,
>                                                           cond, cons, alt)));
>        return true;
>      }

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 06/44] RISC-V: Avoid repeated GET_MODE calls in `riscv_expand_conditional_move'
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Kito Cheng @ 2023-11-19  5:55 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Palmer Dabbelt

LGTM

On Sun, Nov 19, 2023 at 1:36 PM Maciej W. Rozycki <macro@embecosm.com> wrote:
>
> Use `mode0' and `mode1' shorthands respectively for `GET_MODE (op0)' and
> `GET_MODE (op1)' to improve code readability.
>
>         gcc/
>         * config/riscv/riscv.cc (riscv_expand_conditional_move): Use
>         `mode0' and `mode1' for `GET_MODE (op0)' and `GET_MODE (op1)'.
> ---
>  gcc/config/riscv/riscv.cc |   11 +++++++----
>  1 file changed, 7 insertions(+), 4 deletions(-)
>
> gcc-riscv-expand-conditional-move-mode-cmp.diff
> Index: gcc/gcc/config/riscv/riscv.cc
> ===================================================================
> --- gcc.orig/gcc/config/riscv/riscv.cc
> +++ gcc/gcc/config/riscv/riscv.cc
> @@ -4007,12 +4007,15 @@ riscv_expand_conditional_move (rtx dest,
>    else if (TARGET_ZICOND_LIKE
>            && GET_MODE_CLASS (mode) == MODE_INT)
>      {
> +      machine_mode mode0 = GET_MODE (op0);
> +      machine_mode mode1 = GET_MODE (op1);
> +
>        /* The comparison must be comparing WORD_MODE objects.   We must
>          enforce that so that we don't strip away a sign_extension
>          thinking it is unnecessary.  We might consider using
>          riscv_extend_operands if they are not already properly extended.  */
> -      if ((GET_MODE (op0) != word_mode && GET_MODE (op0) != VOIDmode)
> -         || (GET_MODE (op1) != word_mode && GET_MODE (op1) != VOIDmode))
> +      if ((mode0 != word_mode && mode0 != VOIDmode)
> +         || (mode1 != word_mode && mode1 != VOIDmode))
>         return false;
>
>        /* Canonicalize the comparison.  It must be an equality comparison
> @@ -4032,9 +4035,9 @@ riscv_expand_conditional_move (rtx dest,
>           rtx tmp = gen_reg_rtx (word_mode);
>
>           /* We can support both FP and integer conditional moves.  */
> -         if (INTEGRAL_MODE_P (GET_MODE (XEXP (op, 0))))
> +         if (INTEGRAL_MODE_P (mode0))
>             riscv_expand_int_scc (tmp, code, op0, op1, invert_ptr);
> -         else if (FLOAT_MODE_P (GET_MODE (XEXP (op, 0)))
> +         else if (FLOAT_MODE_P (mode0)
>                    && fp_scc_comparison (op, GET_MODE (op)))
>             riscv_expand_float_scc (tmp, code, op0, op1);
>           else

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 08/44] RISC-V: Simplify EQ vs NE selection in `riscv_expand_conditional_move'
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Kito Cheng @ 2023-11-19  5:56 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Palmer Dabbelt

LGTM

On Sun, Nov 19, 2023 at 1:37 PM Maciej W. Rozycki <macro@embecosm.com> wrote:
>
> Just choose between EQ and NE at `gen_rtx_fmt_ee' invocation, removing
> an extraneous variable only referred once and improving code clarity.
>
>         gcc/
>         * config/riscv/riscv.cc (riscv_expand_conditional_move): Remove
>         extraneous variable for EQ vs NE operation selection.
> ---
> FWIW I have no idea what "We need to know where so that we can adjust it
> for our needs." refers to, but that would have to be for another change.
> ---
>  gcc/config/riscv/riscv.cc |   12 ++++--------
>  1 file changed, 4 insertions(+), 8 deletions(-)
>
> gcc-riscv-expand-conditional-move-new-code.diff
> Index: gcc/gcc/config/riscv/riscv.cc
> ===================================================================
> --- gcc.orig/gcc/config/riscv/riscv.cc
> +++ gcc/gcc/config/riscv/riscv.cc
> @@ -4023,10 +4023,12 @@ riscv_expand_conditional_move (rtx dest,
>          we can then use an equality comparison against zero.  */
>        if (!equality_operator (op, VOIDmode) || op1 != CONST0_RTX (mode))
>         {
> -         enum rtx_code new_code = NE;
>           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
> +            we can adjust it for our needs.  */
>           if (code == LE || code == GE)
>             invert_ptr = &invert;
>
> @@ -4043,13 +4045,7 @@ riscv_expand_conditional_move (rtx dest,
>           else
>             return false;
>
> -         /* If riscv_expand_int_scc inverts the condition, then it will
> -            flip the value of INVERT.  We need to know where so that
> -            we can adjust it for our needs.  */
> -         if (invert)
> -           new_code = EQ;
> -
> -         op = gen_rtx_fmt_ee (new_code, mode, tmp, const0_rtx);
> +         op = gen_rtx_fmt_ee (invert ? EQ : NE, mode, tmp, const0_rtx);
>
>           /* We've generated a new comparison.  Update the local variables.  */
>           code = GET_CODE (op);

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 13/44] RISC-V/testsuite: Add branchless cases for FP cond-move operations
  2023-11-18 18:03   ` Jeff Law
@ 2023-11-19  6:27     ` Maciej W. Rozycki
  0 siblings, 0 replies; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-19  6:27 UTC (permalink / raw)
  To: Jeff Law
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

On Sat, 18 Nov 2023, Jeff Law wrote:

> Is this dependent on any of the other patches in this series?  Or is it
> independent and ready to go as-is?  I ask becuase it's marked as 13/44 and I
> haven't seen the other 43 patches in the series :-)
> 
> If it's independent and been tested, then it's OK for the trunk.  I'll trust
> your regexps :-)

 It depends rather irrevocably on 09/44 and it was sent prematurely due to 
a slipped finger, so let's sort out 09/44 first, which is the branch cost 
model rework I talked about last Tue.

  Maciej

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 10/44] RISC-V/testsuite: Add branched cases for integer cond-move operations
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Kito Cheng @ 2023-11-19  6:44 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Palmer Dabbelt

LGTM, thanks for those test cases!

On Sun, Nov 19, 2023 at 1:37 PM Maciej W. Rozycki <macro@embecosm.com> wrote:
>
> Verify, for T-Head, Ventana and Zicond targets and the integer
> conditional-move operations that already work as expected, that
> if-conversion does *not* trigger at the respective sufficiently low
> `-mbranch-cost=' settings that make original branched code sequences
> cheaper than their branchless equivalents if-conversion would emit.
> Cover all integer relational operations to make sure no corner case
> escapes.
>
> The reason to XFAIL movdibne-thead.c and movsibne-thead.c is the
> branchless T-Head sequence:
>
>         sub     a1,a0,a1
>         th.mveqz        a2,a3,a1
>         mv      a0,a2
>         ret
>
> produced rather than its original branched counterpart:
>
>         beq     a0,a1,.L3
>         mv      a0,a2
>         ret
> .L3:
>         mv      a0,a3
>         ret
>
> at `-mbranch-cost=1', even though under this setting the latter sequence
> is obviously cheaper performance-wise.  This is because the final move
> instruction in the branchless sequence is not counted towards its cost
> and consequently the cost of both sequences works out at 8 each, making
> if-conversion prefer the branchless variant.  Use the XFAIL mark to keep
> track of these cases for future consideration.
>
>         gcc/testsuite/
>         * gcc.target/riscv/movdibeq-thead.c: New test.
>         * gcc.target/riscv/movdibge-ventana.c: New test.
>         * gcc.target/riscv/movdibge-zicond.c: New test.
>         * gcc.target/riscv/movdibgeu-ventana.c: New test.
>         * gcc.target/riscv/movdibgeu-zicond.c: New test.
>         * gcc.target/riscv/movdibgt-ventana.c: New test.
>         * gcc.target/riscv/movdibgt-zicond.c: New test.
>         * gcc.target/riscv/movdible-ventana.c: New test.
>         * gcc.target/riscv/movdible-zicond.c: New test.
>         * gcc.target/riscv/movdibleu-ventana.c: New test.
>         * gcc.target/riscv/movdibleu-zicond.c: New test.
>         * gcc.target/riscv/movdiblt-ventana.c: New test.
>         * gcc.target/riscv/movdiblt-zicond.c: New test.
>         * gcc.target/riscv/movdibne-thead.c: New test.
>         * gcc.target/riscv/movsibeq-thead.c: New test.
>         * gcc.target/riscv/movsibge-ventana.c: New test.
>         * gcc.target/riscv/movsibge-zicond.c: New test.
>         * gcc.target/riscv/movsibgeu-ventana.c: New test.
>         * gcc.target/riscv/movsibgeu-zicond.c: New test.
>         * gcc.target/riscv/movsibgt-ventana.c: New test.
>         * gcc.target/riscv/movsibgt-zicond.c: New test.
>         * gcc.target/riscv/movsible-ventana.c: New test.
>         * gcc.target/riscv/movsible-zicond.c: New test.
>         * gcc.target/riscv/movsibleu-ventana.c: New test.
>         * gcc.target/riscv/movsibleu-zicond.c: New test.
>         * gcc.target/riscv/movsiblt-ventana.c: New test.
>         * gcc.target/riscv/movsiblt-zicond.c: New test.
>         * gcc.target/riscv/movsibne-thead.c: New test.
> ---
>  gcc/testsuite/gcc.target/riscv/movdibeq-thead.c    |   27 +++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdibge-ventana.c  |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdibge-zicond.c   |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdibgeu-ventana.c |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdibgeu-zicond.c  |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdibgt-ventana.c  |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdibgt-zicond.c   |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdible-ventana.c  |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdible-zicond.c   |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdibleu-ventana.c |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdibleu-zicond.c  |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdiblt-ventana.c  |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdiblt-zicond.c   |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdibne-thead.c    |   29 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibeq-thead.c    |   27 +++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibge-ventana.c  |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibge-zicond.c   |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibgeu-ventana.c |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibgeu-zicond.c  |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibgt-ventana.c  |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibgt-zicond.c   |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsible-ventana.c  |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsible-zicond.c   |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibleu-ventana.c |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibleu-zicond.c  |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsiblt-ventana.c  |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsiblt-zicond.c   |   28 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibne-thead.c    |   29 +++++++++++++++++++++
>  28 files changed, 784 insertions(+)
>
> gcc-riscv-branch-cost-test-movcc-branch.diff
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibeq-thead.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibeq-thead.c
> @@ -0,0 +1,27 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdieq (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w == x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       bne     a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibge-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibge-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdige (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       blt     a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibge-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibge-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdige (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       blt     a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibgeu-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibgeu-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdigeu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       bltu    a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibgeu-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibgeu-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdigeu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       bltu    a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibgt-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibgt-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdigt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       ble     a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibgt-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibgt-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdigt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       ble     a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdible-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdible-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdile (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       bgt     a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdible-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdible-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdile (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       bgt     a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibleu-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibleu-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdileu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       bgtu    a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibleu-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibleu-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdileu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       bgtu    a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdiblt-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdiblt-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdilt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       bge     a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdiblt-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdiblt-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdilt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       bge     a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibne-thead.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibne-thead.c
> @@ -0,0 +1,29 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdine (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w != x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       beq     a0,a1,.L3
> +       mv      a0,a2
> +       ret
> +.L3:
> +       mv      a0,a3
> +       ret
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" { xfail "*-*-*" } } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" { xfail "*-*-*" } } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 { xfail "*-*-*" } } } */
> +/* { dg-final { scan-assembler-not "\\ssub\\s" { xfail "*-*-*" } } } */
> +/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" { xfail "*-*-*" } } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibeq-thead.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibeq-thead.c
> @@ -0,0 +1,27 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsieq (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w == x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       bne     a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\ssub\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibge-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibge-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsige (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       blt     a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibge-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibge-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsige (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       blt     a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibgeu-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibgeu-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsigeu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       bltu    a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibgeu-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibgeu-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef unsigned int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsigeu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       bltu    a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibgt-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibgt-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsigt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       ble     a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibgt-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibgt-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsigt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       ble     a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsible-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsible-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsile (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       bgt     a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsible-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsible-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsile (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       bgt     a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibleu-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibleu-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsileu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       bgtu    a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibleu-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibleu-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef unsigned int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsileu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       bgtu    a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bgeu|bgtu|bleu|bltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgtu|sltu)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsiblt-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsiblt-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsilt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       bge     a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsiblt-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsiblt-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsilt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       bge     a0,a1,.L2
> +       mv      a3,a2
> +.L2:
> +       mv      a0,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:bge|bgt|ble|blt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:sgt|slt)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibne-thead.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibne-thead.c
> @@ -0,0 +1,29 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsine (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w != x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       beq     a0,a1,.L3
> +       mv      a0,a2
> +       ret
> +.L3:
> +       mv      a0,a3
> +       ret
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" { xfail "*-*-*" } } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" { xfail "*-*-*" } } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 { xfail "*-*-*" } } } */
> +/* { dg-final { scan-assembler-not "\\ssub\\s" { xfail "*-*-*" } } } */
> +/* { dg-final { scan-assembler-not "\\s(?:th\\.mveqz|th\\.mvnez)\\s" { xfail "*-*-*" } } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 11/44] RISC-V/testsuite: Add branchless cases for integer cond-move operations
  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
  0 siblings, 1 reply; 101+ messages in thread
From: Kito Cheng @ 2023-11-19  6:47 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Palmer Dabbelt

LGTM.
Just one minor comment, I think we don't really need to check rv64 or
rv32 for those compiled without any header file test, but I am fine
with that.

On Sun, Nov 19, 2023 at 1:37 PM Maciej W. Rozycki <macro@embecosm.com> wrote:
>
> Verify, for T-Head, Ventana and Zicond targets and the integer
> conditional-move operations that already work as expected, if-conversion
> to trigger via `noce_try_cmove' at the respective sufficiently high
> `-mbranch-cost=' settings that make branchless code sequences produced
> by if-conversion cheaper than their original branched equivalents, and
> that extraneous instructions such as SNEZ, etc. are not present in
> output.  Cover all integer relational operations to make sure no corner
> case escapes.
>
>         gcc/testsuite/
>         * gcc.target/riscv/movdieq-thead.c: New test.
>         * gcc.target/riscv/movdige-ventana.c: New test.
>         * gcc.target/riscv/movdige-zicond.c: New test.
>         * gcc.target/riscv/movdigeu-ventana.c: New test.
>         * gcc.target/riscv/movdigeu-zicond.c: New test.
>         * gcc.target/riscv/movdigt-ventana.c: New test.
>         * gcc.target/riscv/movdigt-zicond.c: New test.
>         * gcc.target/riscv/movdile-ventana.c: New test.
>         * gcc.target/riscv/movdile-zicond.c: New test.
>         * gcc.target/riscv/movdileu-ventana.c: New test.
>         * gcc.target/riscv/movdileu-zicond.c: New test.
>         * gcc.target/riscv/movdilt-ventana.c: New test.
>         * gcc.target/riscv/movdilt-zicond.c: New test.
>         * gcc.target/riscv/movdine-thead.c: New test.
>         * gcc.target/riscv/movsieq-thead.c: New test.
>         * gcc.target/riscv/movsige-ventana.c: New test.
>         * gcc.target/riscv/movsige-zicond.c: New test.
>         * gcc.target/riscv/movsigeu-ventana.c: New test.
>         * gcc.target/riscv/movsigeu-zicond.c: New test.
>         * gcc.target/riscv/movsigt-ventana.c: New test.
>         * gcc.target/riscv/movsigt-zicond.c: New test.
>         * gcc.target/riscv/movsile-ventana.c: New test.
>         * gcc.target/riscv/movsile-zicond.c: New test.
>         * gcc.target/riscv/movsileu-ventana.c: New test.
>         * gcc.target/riscv/movsileu-zicond.c: New test.
>         * gcc.target/riscv/movsilt-ventana.c: New test.
>         * gcc.target/riscv/movsilt-zicond.c: New test.
>         * gcc.target/riscv/movsine-thead.c: New test.
> ---
>  gcc/testsuite/gcc.target/riscv/movdieq-thead.c    |   26 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdige-ventana.c  |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdige-zicond.c   |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdigeu-ventana.c |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdigeu-zicond.c  |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdigt-ventana.c  |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdigt-zicond.c   |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdile-ventana.c  |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdile-zicond.c   |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdileu-ventana.c |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdileu-zicond.c  |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdilt-ventana.c  |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdilt-zicond.c   |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdine-thead.c    |   26 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsieq-thead.c    |   26 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsige-ventana.c  |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsige-zicond.c   |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsigeu-ventana.c |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsigeu-zicond.c  |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsigt-ventana.c  |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsigt-zicond.c   |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsile-ventana.c  |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsile-zicond.c   |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsileu-ventana.c |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsileu-zicond.c  |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsilt-ventana.c  |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsilt-zicond.c   |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsine-thead.c    |   26 ++++++++++++++++++++
>  28 files changed, 776 insertions(+)
>
> gcc-riscv-branch-cost-test-movcc.diff
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdieq-thead.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdieq-thead.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdieq (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w == x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sub     a0,a0,a1
> +       th.mvnez        a2,a3,a0
> +       mv      a0,a2
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdige-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdige-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdige (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       slt     a1,a0,a1
> +       vt.maskc        a3,a3,a1
> +       vt.maskcn       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdige-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdige-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdige (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       slt     a1,a0,a1
> +       czero.eqz       a3,a3,a1
> +       czero.nez       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdigeu-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdigeu-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdigeu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sltu    a1,a0,a1
> +       vt.maskc        a3,a3,a1
> +       vt.maskcn       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdigeu-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdigeu-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdigeu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sltu    a1,a0,a1
> +       czero.eqz       a3,a3,a1
> +       czero.nez       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdigt-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdigt-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdigt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sgt     a1,a0,a1
> +       vt.maskcn       a3,a3,a1
> +       vt.maskc        a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdigt-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdigt-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdigt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sgt     a1,a0,a1
> +       czero.nez       a3,a3,a1
> +       czero.eqz       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdile-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdile-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdile (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sgt     a1,a0,a1
> +       vt.maskc        a3,a3,a1
> +       vt.maskcn       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdile-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdile-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdile (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sgt     a1,a0,a1
> +       czero.eqz       a3,a3,a1
> +       czero.nez       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdileu-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdileu-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdileu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sgtu    a1,a0,a1
> +       vt.maskc        a3,a3,a1
> +       vt.maskcn       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdileu-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdileu-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdileu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sgtu    a1,a0,a1
> +       czero.eqz       a3,a3,a1
> +       czero.nez       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdilt-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdilt-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdilt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       slt     a1,a0,a1
> +       vt.maskcn       a3,a3,a1
> +       vt.maskc        a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdilt-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdilt-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdilt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       slt     a1,a0,a1
> +       czero.nez       a3,a3,a1
> +       czero.eqz       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdine-thead.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdine-thead.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdine (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w != x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sub     a1,a0,a1
> +       th.mveqz        a2,a3,a1
> +       mv      a0,a2
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsieq-thead.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsieq-thead.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsieq (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w == x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sub     a0,a0,a1
> +       th.mvnez        a2,a3,a0
> +       mv      a0,a2
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsige-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsige-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsige (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       slt     a1,a0,a1
> +       vt.maskc        a3,a3,a1
> +       vt.maskcn       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsige-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsige-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsige (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       slt     a1,a0,a1
> +       czero.eqz       a3,a3,a1
> +       czero.nez       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsigeu-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsigeu-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsigeu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sltu    a1,a0,a1
> +       vt.maskc        a3,a3,a1
> +       vt.maskcn       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsigeu-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsigeu-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef unsigned int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsigeu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sltu    a1,a0,a1
> +       czero.eqz       a3,a3,a1
> +       czero.nez       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsigt-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsigt-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsigt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sgt     a1,a0,a1
> +       vt.maskcn       a3,a3,a1
> +       vt.maskc        a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsigt-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsigt-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsigt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sgt     a1,a0,a1
> +       czero.nez       a3,a3,a1
> +       czero.eqz       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsile-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsile-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsile (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sgt     a1,a0,a1
> +       vt.maskc        a3,a3,a1
> +       vt.maskcn       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsile-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsile-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsile (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sgt     a1,a0,a1
> +       czero.eqz       a3,a3,a1
> +       czero.nez       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsileu-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsileu-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsileu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sgtu    a1,a0,a1
> +       vt.maskc        a3,a3,a1
> +       vt.maskcn       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsileu-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsileu-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef unsigned int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsileu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sgtu    a1,a0,a1
> +       czero.eqz       a3,a3,a1
> +       czero.nez       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsilt-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsilt-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsilt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       slt     a1,a0,a1
> +       vt.maskcn       a3,a3,a1
> +       vt.maskc        a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsilt-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsilt-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsilt (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       slt     a1,a0,a1
> +       czero.nez       a3,a3,a1
> +       czero.eqz       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgt|slt)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bge|bgt|ble|blt)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsine-thead.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsine-thead.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsine (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w != x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sub     a1,a0,a1
> +       th.mveqz        a2,a3,a1
> +       mv      a0,a2
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\ssub\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 12/44] RISC-V/testsuite: Add branched cases for FP cond-move operations
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Kito Cheng @ 2023-11-19  6:48 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Palmer Dabbelt

LGTM

On Sun, Nov 19, 2023 at 1:38 PM Maciej W. Rozycki <macro@embecosm.com> wrote:
>
> Verify, for Ventana and Zicond targets and the ordered floating-point
> conditional-move operations that already work as expected, that
> if-conversion does *not* trigger at `-mbranch-cost=2' setting, which
> makes original branched code sequences cheaper than their branchless
> equivalents if-conversion would emit.  Cover all ordered floating-point
> relational operations to make sure no corner case escapes.
>
>         gcc/testsuite/
>         * gcc.target/riscv/movdibfge-ventana.c: New test.
>         * gcc.target/riscv/movdibfge-zicond.c: New test.
>         * gcc.target/riscv/movdibfgt-ventana.c: New test.
>         * gcc.target/riscv/movdibfgt-zicond.c: New test.
>         * gcc.target/riscv/movdibfle-ventana.c: New test.
>         * gcc.target/riscv/movdibfle-zicond.c: New test.
>         * gcc.target/riscv/movdibflt-ventana.c: New test.
>         * gcc.target/riscv/movdibflt-zicond.c: New test.
>         * gcc.target/riscv/movdibfne-ventana.c: New test.
>         * gcc.target/riscv/movdibfne-zicond.c: New test.
>         * gcc.target/riscv/movsibfge-ventana.c: New test.
>         * gcc.target/riscv/movsibfge-zicond.c: New test.
>         * gcc.target/riscv/movsibfgt-ventana.c: New test.
>         * gcc.target/riscv/movsibfgt-zicond.c: New test.
>         * gcc.target/riscv/movsibfle-ventana.c: New test.
>         * gcc.target/riscv/movsibfle-zicond.c: New test.
>         * gcc.target/riscv/movsibflt-ventana.c: New test.
>         * gcc.target/riscv/movsibflt-zicond.c: New test.
>         * gcc.target/riscv/movsibfne-ventana.c: New test.
>         * gcc.target/riscv/movsibfne-zicond.c: New test.
> ---
>  gcc/testsuite/gcc.target/riscv/movdibfge-ventana.c |   29 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdibfge-zicond.c  |   29 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdibfgt-ventana.c |   30 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdibfgt-zicond.c  |   30 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdibfle-ventana.c |   30 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdibfle-zicond.c  |   30 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdibflt-ventana.c |   30 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdibflt-zicond.c  |   30 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdibfne-ventana.c |   30 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdibfne-zicond.c  |   30 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibfge-ventana.c |   30 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibfge-zicond.c  |   30 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibfgt-ventana.c |   30 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibfgt-zicond.c  |   30 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibfle-ventana.c |   30 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibfle-zicond.c  |   30 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibflt-ventana.c |   30 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibflt-zicond.c  |   30 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibfne-ventana.c |   30 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsibfne-zicond.c  |   30 +++++++++++++++++++++
>  20 files changed, 598 insertions(+)
>
> gcc-riscv-branch-cost-test-movccf-branch.diff
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfge-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibfge-ventana.c
> @@ -0,0 +1,29 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdifge (double w, double x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       fge.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       beq     a4,zero,.L2
> +       mv      a0,a5
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfge-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibfge-zicond.c
> @@ -0,0 +1,29 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdifge (double w, double x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       fge.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       beq     a4,zero,.L2
> +       mv      a0,a5
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfgt-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibfgt-ventana.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdifgt (double w, double x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       fgt.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       beq     a4,zero,.L2
> +       mv      a0,a5
> +.L2:
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfgt-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibfgt-zicond.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdifgt (double w, double x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       fgt.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       beq     a4,zero,.L2
> +       mv      a0,a5
> +.L2:
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfle-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibfle-ventana.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdifle (double w, double x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       fle.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       beq     a4,zero,.L2
> +       mv      a0,a5
> +.L2:
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfle-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibfle-zicond.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdifle (double w, double x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       fle.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       beq     a4,zero,.L2
> +       mv      a0,a5
> +.L2:
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibflt-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibflt-ventana.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdiflt (double w, double x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       flt.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       beq     a4,zero,.L2
> +       mv      a0,a5
> +.L2:
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibflt-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibflt-zicond.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdiflt (double w, double x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       flt.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       beq     a4,zero,.L2
> +       mv      a0,a5
> +.L2:
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfne-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibfne-ventana.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdifne (double w, double x, int_t y, int_t z)
> +{
> +  return w != x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       feq.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       bne     a4,zero,.L2
> +       mv      a0,a5
> +.L2:
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdibfne-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdibfne-zicond.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdifne (double w, double x, int_t y, int_t z)
> +{
> +  return w != x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       feq.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       bne     a4,zero,.L2
> +       mv      a0,a5
> +.L2:
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfge-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibfge-ventana.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsifge (double w, double x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       fge.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       beq     a4,zero,.L2
> +       mv      a0,a5
> +.L2:
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfge-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibfge-zicond.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsifge (double w, double x, int_t y, int_t z)
> +{
> +  return w >= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       fge.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       beq     a4,zero,.L2
> +       mv      a0,a5
> +.L2:
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfgt-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibfgt-ventana.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsifgt (double w, double x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       fgt.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       beq     a4,zero,.L2
> +       mv      a0,a5
> +.L2:
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfgt-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibfgt-zicond.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsifgt (double w, double x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       fgt.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       beq     a4,zero,.L2
> +       mv      a0,a5
> +.L2:
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfle-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibfle-ventana.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsifle (double w, double x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       fle.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       beq     a4,zero,.L2
> +       mv      a0,a5
> +.L2:
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfle-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibfle-zicond.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsifle (double w, double x, int_t y, int_t z)
> +{
> +  return w <= x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       fle.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       beq     a4,zero,.L2
> +       mv      a0,a5
> +.L2:
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:fge\\.d|fle\\.d)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibflt-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibflt-ventana.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsiflt (double w, double x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       flt.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       beq     a4,zero,.L2
> +       mv      a0,a5
> +.L2:
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibflt-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibflt-zicond.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsiflt (double w, double x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       flt.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       beq     a4,zero,.L2
> +       mv      a0,a5
> +.L2:
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:fgt\\.d|flt\\.d)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfne-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibfne-ventana.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsifne (double w, double x, int_t y, int_t z)
> +{
> +  return w != x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       feq.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       bne     a4,zero,.L2
> +       mv      a0,a5
> +.L2:
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskc\\s" } } */
> +/* { dg-final { scan-assembler-not "\\svt\\.maskcn\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsibfne-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsibfne-zicond.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=2 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsifne (double w, double x, int_t y, int_t z)
> +{
> +  return w != x ? y : z;
> +}
> +
> +/* Expect branched assembly like:
> +
> +       feq.d   a4,fa0,fa1
> +       mv      a5,a0
> +       mv      a0,a1
> +       bne     a4,zero,.L2
> +       mv      a0,a5
> +.L2:
> + */
> +
> +/* { dg-final { scan-rtl-dump-not "Conversion succeeded on pass \[0-9\]+\\." "ce1" } } */
> +/* { dg-final { scan-rtl-dump-not "if-conversion succeeded through" "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\sfeq\\.d\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\s(?:beq|bne)\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.eqz\\s" } } */
> +/* { dg-final { scan-assembler-not "\\sczero\\.nez\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 14/44] RISC-V: Also invert the cond-move condition for GEU and LEU
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Kito Cheng @ 2023-11-19  6:50 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Palmer Dabbelt

LGTM

On Sun, Nov 19, 2023 at 1:39 PM Maciej W. Rozycki <macro@embecosm.com> wrote:
>
> Update `riscv_expand_conditional_move' and handle the missing GEU and
> LEU operators there, avoiding an extraneous conditional set operation,
> such as with this output:
>
>         sgtu    a0,a0,a1
>         seqz    a1,a0
>         czero.eqz       a3,a3,a1
>         czero.nez       a1,a2,a1
>         or      a0,a1,a3
>
> produced when optimizing for Zicond targets from:
>
> int
> movsigtu (int w, int x, int y, int z)
> {
>   return w > x ? y : z;
> }
>
> These operators can be inverted producing optimal code such as this:
>
>         sgtu    a1,a0,a1
>         czero.nez       a3,a3,a1
>         czero.eqz       a1,a2,a1
>         or      a0,a1,a3
>
> which this change causes to happen.
>
>         gcc/
>         * config/riscv/riscv.cc (riscv_expand_conditional_move): Also
>         invert the condition for GEU and LEU.
> ---
>  gcc/config/riscv/riscv.cc |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> gcc-riscv-expand-conditional-move-geu-leu.diff
> Index: gcc/gcc/config/riscv/riscv.cc
> ===================================================================
> --- gcc.orig/gcc/config/riscv/riscv.cc
> +++ gcc/gcc/config/riscv/riscv.cc
> @@ -4142,7 +4142,7 @@ riscv_expand_conditional_move (rtx dest,
>           /* If riscv_expand_int_scc inverts the condition, then it will
>              flip the value of INVERT.  We need to know where so that
>              we can adjust it for our needs.  */
> -         if (code == LE || code == GE)
> +         if (code == LE || code == LEU || code == GE || code == GEU)
>             invert_ptr = &invert;
>
>           /* Emit an scc like instruction into a temporary

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 16/44] RISC-V/testsuite: Add branchless cases for GEU and LEU cond-move operations
  2023-11-19  5:38 ` [PATCH 16/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
@ 2023-11-19  7:22   ` Kito Cheng
  0 siblings, 0 replies; 101+ messages in thread
From: Kito Cheng @ 2023-11-19  7:22 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Palmer Dabbelt

LGTM

On Sun, Nov 19, 2023 at 1:38 PM Maciej W. Rozycki <macro@embecosm.com> wrote:
>
> Verify, for Ventana and Zicond targets and the GEU and LEU
> conditional-move operations, that if-conversion triggers via
> `noce_try_cmove' at `-mbranch-cost=4' setting, which makes branchless
> code sequences produced by if-conversion cheaper than their original
> branched equivalents, and that extraneous instructions such as SEQZ,
> etc. are not present in output.
>
>         gcc/testsuite/
>         * gcc.target/riscv/movdigtu-ventana.c: New test.
>         * gcc.target/riscv/movdigtu-zicond.c: New test.
>         * gcc.target/riscv/movdiltu-ventana.c: New test.
>         * gcc.target/riscv/movdiltu-zicond.c: New test.
>         * gcc.target/riscv/movsigtu-ventana.c: New test.
>         * gcc.target/riscv/movsigtu-zicond.c: New test.
>         * gcc.target/riscv/movsiltu-ventana.c: New test.
>         * gcc.target/riscv/movsiltu-zicond.c: New test.
> ---
>  gcc/testsuite/gcc.target/riscv/movdigtu-ventana.c |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdigtu-zicond.c  |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdiltu-ventana.c |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movdiltu-zicond.c  |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsigtu-ventana.c |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsigtu-zicond.c  |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsiltu-ventana.c |   28 ++++++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/movsiltu-zicond.c  |   28 ++++++++++++++++++++++
>  8 files changed, 224 insertions(+)
>
> gcc-riscv-expand-conditional-move-geu-leu-test-movcc.diff
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdigtu-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdigtu-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdigtu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sgtu    a1,a0,a1
> +       vt.maskcn       a3,a3,a1
> +       vt.maskc        a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdigtu-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdigtu-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdigtu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sgtu    a1,a0,a1
> +       czero.nez       a3,a3,a1
> +       czero.eqz       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdiltu-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdiltu-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdiltu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sltu    a1,a0,a1
> +       vt.maskcn       a3,a3,a1
> +       vt.maskc        a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movdiltu-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movdiltu-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (DI))) int_t;
> +
> +int_t
> +movdiltu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sltu    a1,a0,a1
> +       czero.nez       a3,a3,a1
> +       czero.eqz       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsigtu-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsigtu-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsigtu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sgtu    a1,a0,a1
> +       vt.maskcn       a3,a3,a1
> +       vt.maskc        a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsigtu-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsigtu-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef unsigned int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsigtu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w > x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sgtu    a1,a0,a1
> +       czero.nez       a3,a3,a1
> +       czero.eqz       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsiltu-ventana.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsiltu-ventana.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" } */
> +
> +typedef unsigned int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsiltu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sltu    a1,a0,a1
> +       vt.maskcn       a3,a3,a1
> +       vt.maskc        a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\svt\\.maskcn\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/movsiltu-zicond.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/movsiltu-zicond.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
> +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv64 } } } */
> +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=4 -fdump-rtl-ce1" { target { rv32 } } } */
> +
> +typedef unsigned int __attribute__ ((mode (SI))) int_t;
> +
> +int_t
> +movsiltu (int_t w, int_t x, int_t y, int_t z)
> +{
> +  return w < x ? y : z;
> +}
> +
> +/* Expect branchless assembly like:
> +
> +       sltu    a1,a0,a1
> +       czero.nez       a3,a3,a1
> +       czero.eqz       a1,a2,a1
> +       or      a0,a1,a3
> + */
> +
> +/* { dg-final { scan-rtl-dump-times "Conversion succeeded on pass 1\\." 1 "ce1" } } */
> +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove" 1 "ce1" } } */
> +/* { dg-final { scan-assembler-times "\\s(?:sgtu|sltu)\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
> +/* { dg-final { scan-assembler-times "\\sczero\\.nez\\s" 1 } } */
> +/* { dg-final { scan-assembler-not "\\s(?:seqz|snez)\\s" } } */
> +/* { dg-final { scan-assembler-not "\\s(?:bgeu|bgtu|bleu|bltu)\\s" } } */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 15/44] RISC-V/testsuite: Add branched cases for GEU and LEU cond-move operations
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 17:42 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:38, Maciej W. Rozycki wrote:
> Verify, for Ventana and Zicond targets and the GEU and LEU
> conditional-move operations, that if-conversion does *not* trigger at
> `-mbranch-cost=3' setting, which makes original branched code sequences
> cheaper than their branchless equivalents if-conversion would emit.
> 	
> gcc/testsuite/
> 	* gcc.target/riscv/movdibgtu-ventana.c: New test.
> 	* gcc.target/riscv/movdibgtu-zicond.c: New test.
> 	* gcc.target/riscv/movdibltu-ventana.c: New test.
> 	* gcc.target/riscv/movdibltu-zicond.c: New test.
> 	* gcc.target/riscv/movsibgtu-ventana.c: New test.
> 	* gcc.target/riscv/movsibgtu-zicond.c: New test.
> 	* gcc.target/riscv/movsibltu-ventana.c: New test.
> 	* gcc.target/riscv/movsibltu-zicond.c: New test.
OK
jeff

>

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 17/44] RISC-V: Avoid extraneous EQ or NE operation in cond-move expansion
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 17:45 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:38, Maciej W. Rozycki wrote:
> In the non-zero case there is no need for the conditional value used by
> Ventana and Zicond integer conditional operations to be specifically 1.
> Regardless we canonicalize it by producing an extraneous conditional-set
> operation, such as with the sequence below:
> 
> (insn 22 6 23 2 (set (reg:DI 141)
>          (minus:DI (reg/v:DI 135 [ w ])
>              (reg/v:DI 136 [ x ]))) 11 {subdi3}
>       (nil))
> (insn 23 22 24 2 (set (reg:DI 140)
>          (ne:DI (reg:DI 141)
>              (const_int 0 [0]))) 307 {*sne_zero_didi}
>       (nil))
> (insn 24 23 25 2 (set (reg:DI 143)
>          (if_then_else:DI (eq:DI (reg:DI 140)
>                  (const_int 0 [0]))
>              (const_int 0 [0])
>              (reg:DI 13 a3 [ z ]))) 27913 {*czero.eqz.didi}
>       (nil))
> (insn 25 24 26 2 (set (reg:DI 142)
>          (if_then_else:DI (ne:DI (reg:DI 140)
>                  (const_int 0 [0]))
>              (const_int 0 [0])
>              (reg/v:DI 137 [ y ]))) 27914 {*czero.nez.didi}
>       (nil))
> (insn 26 25 18 2 (set (reg/v:DI 138 [ z ])
>          (ior:DI (reg:DI 142)
>              (reg:DI 143))) 105 {iordi3}
>       (nil))
> 
> where insn 23 can well be removed without changing the semantics of the
> sequence.  This is actually fixed up later on by combine and the insn
> does not make it to output meaning no SNEZ (or SEQZ in the reverse case)
> appears in the assembly produced, however it counts towards the cost of
> the sequence calculated by if-conversion, raising the trigger level for
> the branchless sequence to be chosen.  Arguably to emit this extraneous
> operation it can be also considered rather sloppy of our backend's.
> 
> Remove the check for operand 1 being constant 0 in the Ventana/Zicond
> case for equality comparisons then, observing that `riscv_zero_if_equal'
> called via `riscv_emit_int_compare' will canonicalize the comparison if
> required, removing the extraneous insn from output:
> 
> (insn 22 6 23 2 (set (reg:DI 142)
>          (minus:DI (reg/v:DI 135 [ w ])
>              (reg/v:DI 136 [ x ]))) 11 {subdi3}
>       (nil))
> (insn 23 22 24 2 (set (reg:DI 141)
>          (if_then_else:DI (eq:DI (reg:DI 142)
>                  (const_int 0 [0]))
>              (const_int 0 [0])
>              (reg:DI 13 a3 [ z ]))) 27913 {*czero.eqz.didi}
>       (nil))
> (insn 24 23 25 2 (set (reg:DI 140)
>          (if_then_else:DI (ne:DI (reg:DI 142)
>                  (const_int 0 [0]))
>              (const_int 0 [0])
>              (reg/v:DI 137 [ y ]))) 27914 {*czero.nez.didi}
>       (nil))
> (insn 25 24 18 2 (set (reg/v:DI 138 [ z ])
>          (ior:DI (reg:DI 140)
>              (reg:DI 141))) 105 {iordi3}
>       (nil))
> 
> while keeping actual assembly produced the same.
> 
> Adjust branch costs across the test cases affected accordingly.
> 
> 	gcc/
> 	* config/riscv/riscv.cc (riscv_expand_conditional_move): Remove
> 	the check for operand 1 being constant 0 in the Ventana/Zicond
> 	case for equality comparisons.
> 
> 	gcc/testsuite/
> 	* gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c:
> 	Lower `-mbranch-cost=' setting.
> 	* gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c:
> 	Likewise.
> 	* gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c:
> 	Likewise.
> 	* gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c:
> 	Likewise.
> 	* gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c:
> 	Likewise.
> 	* gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c:
> 	Likewise.
OK.  Thanks for catching this!

jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 18/44] RISC-V/testsuite: Add branched cases for equality cond-move operations
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 17:45 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:38, Maciej W. Rozycki wrote:
> Verify, for Ventana and Zicond targets and the equality conditional-move
> operations, that if-conversion does *not* trigger at the respective
> sufficiently low `-mbranch-cost=' settings that make original branched
> code sequences cheaper than their branchless equivalents if-conversion
> would emit.
> 
> 	gcc/testsuite/
> 	* gcc.target/riscv/movdibeq-ventana.c: New test.
> 	* gcc.target/riscv/movdibeq-zicond.c: New test.
> 	* gcc.target/riscv/movdibne-ventana.c: New test.
> 	* gcc.target/riscv/movdibne-zicond.c: New test.
> 	* gcc.target/riscv/movsibeq-ventana.c: New test.
> 	* gcc.target/riscv/movsibeq-zicond.c: New test.
> 	* gcc.target/riscv/movsibne-ventana.c: New test.
> 	* gcc.target/riscv/movsibne-zicond.c: New test.
OK
jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 19/44] RISC-V/testsuite: Add branchless cases for equality cond-move operations
  2023-11-19  5:39 ` [PATCH 19/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
@ 2023-11-19 17:46   ` Jeff Law
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 17:46 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:39, Maciej W. Rozycki wrote:
> Verify, for Ventana and Zicond targets and the equality conditional-move
> operations, that if-conversion triggers via `noce_try_cmove' at the
> respective sufficiently high `-mbranch-cost=' settings that make
> branchless code sequences produced by if-conversion cheaper than their
> original branched equivalents, and that extraneous instructions such as
> SNEZ, etc. are not present in output.
> 
> 	gcc/testsuite/
> 	* gcc.target/riscv/movdieq-ventana.c: New test.
> 	* gcc.target/riscv/movdieq-zicond.c: New test.
> 	* gcc.target/riscv/movdine-ventana.c: New test.
> 	* gcc.target/riscv/movdine-zicond.c: New test.
> 	* gcc.target/riscv/movsieq-ventana.c: New test.
> 	* gcc.target/riscv/movsieq-zicond.c: New test.
> 	* gcc.target/riscv/movsine-ventana.c: New test.
> 	* gcc.target/riscv/movsine-zicond.c: New test.
OK
jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 20/44] RISC-V: Also accept constants for T-Head cond-move comparison operands
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 17:48 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:39, Maciej W. Rozycki wrote:
> There is no need for the requirement for conditional-move comparison
> operands to be stricter for T-Head targets than for other targets and
> limit them to registers only.  Constants will be reloaded if required
> just as with branches or other-target conditional-move operations and
> there is no extra overhead specific to the T-Head case.  This enables
> more opportunities for a branchless sequence to be produced.
> 
> 	gcc/
> 	* config/riscv/riscv.cc (riscv_expand_conditional_move): Also
> 	accept constants for T-Head comparison operands.
OK
jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 21/44] RISC-V: Also accept constants for T-Head cond-move data input operands
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 17:50 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:39, Maciej W. Rozycki wrote:
> There is no need for the requirement for conditional-move data input
> operands to be stricter for T-Head targets than for short forward branch
> targets and limit them to registers only.  They are keyed according to
> the `sfb_alu_operand' predicate, which lets certain constants through.
> Such constants are already forced into a register for the `cons' operand
> in the analogous short forward branch case and we can force them for the
> `alt' operand and T-Head as well.  This enables more opportunities for a
> branchless sequence to be produced.
> 
> 	gcc/
> 	* config/riscv/riscv.cc (riscv_expand_conditional_move): Also
>          accept constants for T-Head data input operands.
OK.

Jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 23/44] RISC-V/testsuite: Add branched cases for T-Head non-equality cond moves
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 17:54 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:40, Maciej W. Rozycki wrote:
> Verify, for T-Head targets and the non-equality integer conditional-move
> operations, that if-conversion does *not* trigger at `-mbranch-cost=1'
> setting, which makes original branched code sequences cheaper than their
> branchless equivalents if-conversion would emit.
> 
> 	gcc/testsuite/
> 	* gcc.target/riscv/movdibge-thead.c: New test.
> 	* gcc.target/riscv/movdibgeu-thead.c: New test.
> 	* gcc.target/riscv/movdibgt-thead.c: New test.
> 	* gcc.target/riscv/movdibgtu-thead.c: New test.
> 	* gcc.target/riscv/movdible-thead.c: New test.
> 	* gcc.target/riscv/movdibleu-thead.c: New test.
> 	* gcc.target/riscv/movdiblt-thead.c: New test.
> 	* gcc.target/riscv/movdibltu-thead.c: New test.
> 	* gcc.target/riscv/movsibge-thead.c: New test.
> 	* gcc.target/riscv/movsibgeu-thead.c: New test.
> 	* gcc.target/riscv/movsibgt-thead.c: New test.
> 	* gcc.target/riscv/movsibgtu-thead.c: New test.
> 	* gcc.target/riscv/movsible-thead.c: New test.
> 	* gcc.target/riscv/movsibleu-thead.c: New test.
> 	* gcc.target/riscv/movsiblt-thead.c: New test.
> 	* gcc.target/riscv/movsibltu-thead.c: New test.
OK.
jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 24/44] RISC-V/testsuite: Add branchless cases for T-Head non-equality cond moves
  2023-11-19  5:40 ` [PATCH 24/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
@ 2023-11-19 17:54   ` Jeff Law
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 17:54 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:40, Maciej W. Rozycki wrote:
> Verify, for T-Head targets and the non-equality integer conditional-move
> operations, that if-conversion triggers via `noce_try_cmove' at
> `-mbranch-cost=2' setting, which makes branchless code sequences
> produced by if-conversion cheaper than their original branched
> equivalents, and that extraneous instructions such as SNEZ, etc. are not
> present in output.
> 
> 	gcc/testsuite/
> 	* gcc.target/riscv/movdige-thead.c: New test.
> 	* gcc.target/riscv/movdigeu-thead.c: New test.
> 	* gcc.target/riscv/movdigt-thead.c: New test.
> 	* gcc.target/riscv/movdigtu-thead.c: New test.
> 	* gcc.target/riscv/movdile-thead.c: New test.
> 	* gcc.target/riscv/movdileu-thead.c: New test.
> 	* gcc.target/riscv/movdilt-thead.c: New test.
> 	* gcc.target/riscv/movdiltu-thead.c: New test.
> 	* gcc.target/riscv/movsige-thead.c: New test.
> 	* gcc.target/riscv/movsigeu-thead.c: New test.
> 	* gcc.target/riscv/movsigt-thead.c: New test.
> 	* gcc.target/riscv/movsigtu-thead.c: New test.
> 	* gcc.target/riscv/movsile-thead.c: New test.
> 	* gcc.target/riscv/movsileu-thead.c: New test.
> 	* gcc.target/riscv/movsilt-thead.c: New test.
> 	* gcc.target/riscv/movsiltu-thead.c: New test.
OK
jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 25/44] RISC-V: Implement `riscv_emit_unary' helper
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 17:54 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:40, Maciej W. Rozycki wrote:
> Add a `riscv_emit_unary' helper for unary operations, complementing
> `riscv_emit_binary'.
> 
> 	gcc/
> 	* config/riscv/riscv-protos.h (riscv_emit_unary): New prototype.
> 	* config/riscv/riscv.cc (riscv_emit_unary): New function.
OK
jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 26/44] RISC-V: Add `movMODEcc' implementation for generic targets
  2023-11-19  5:40 ` [PATCH 26/44] RISC-V: Add `movMODEcc' implementation for generic targets Maciej W. Rozycki
@ 2023-11-19 18:18   ` Jeff Law
  2023-11-23 22:16     ` Maciej W. Rozycki
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Law @ 2023-11-19 18:18 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:40, Maciej W. Rozycki wrote:
> 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.
OK.  Just curious are y'all seeing significant interest in this case 
from customers or is this more a case of rounding out the implementation 
to cover all potential possibilities?



Jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 27/44] RISC-V/testsuite: Add branched cases for generic integer cond moves
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 18:18 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:40, Maciej W. Rozycki wrote:
> Verify, for generic integer conditional-move operations, if-conversion
> *not* to trigger at the respective sufficiently low `-mbranch-cost='
> settings that make original branched code sequences cheaper than their
> branchless equivalents if-conversion would emit.  Cover all integer
> relational operations to make sure no corner case escapes.
> 
> 	gcc/testsuite/
> 	* gcc.target/riscv/movdibeq.c: New test.
> 	* gcc.target/riscv/movdibge.c: New test.
> 	* gcc.target/riscv/movdibgeu.c: New test.
> 	* gcc.target/riscv/movdibgt.c: New test.
> 	* gcc.target/riscv/movdibgtu.c: New test.
> 	* gcc.target/riscv/movdible.c: New test.
> 	* gcc.target/riscv/movdibleu.c: New test.
> 	* gcc.target/riscv/movdiblt.c: New test.
> 	* gcc.target/riscv/movdibltu.c: New test.
> 	* gcc.target/riscv/movdibne.c: New test.
> 	* gcc.target/riscv/movsibeq.c: New test.
> 	* gcc.target/riscv/movsibge.c: New test.
> 	* gcc.target/riscv/movsibgeu.c: New test.
> 	* gcc.target/riscv/movsibgt.c: New test.
> 	* gcc.target/riscv/movsibgtu.c: New test.
> 	* gcc.target/riscv/movsible.c: New test.
> 	* gcc.target/riscv/movsibleu.c: New test.
> 	* gcc.target/riscv/movsiblt.c: New test.
> 	* gcc.target/riscv/movsibltu.c: New test.
> 	* gcc.target/riscv/movsibne.c: New test.
OK
jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 28/44] RISC-V/testsuite: Add branchless cases for generic integer cond moves
  2023-11-19  5:41 ` [PATCH 28/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
@ 2023-11-19 18:19   ` Jeff Law
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 18:19 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:41, Maciej W. Rozycki wrote:
> Verify, for generic integer conditional-move operations, if-conversion
> to trigger via `noce_try_cmove' at the respective sufficiently high
> `-mbranch-cost=' settings that make branchless code sequences produced
> by if-conversion cheaper than their original branched equivalents, and,
> where applicable, that extraneous instructions such as SNEZ, etc. are
> not present in output.  Cover all integer relational operations to make
> sure no corner case escapes.
> 
> 	gcc/testsuite/
> 	* gcc.target/riscv/movdieq.c: New test.
> 	* gcc.target/riscv/movdige.c: New test.
> 	* gcc.target/riscv/movdigeu.c: New test.
> 	* gcc.target/riscv/movdigt.c: New test.
> 	* gcc.target/riscv/movdigtu.c: New test.
> 	* gcc.target/riscv/movdile.c: New test.
> 	* gcc.target/riscv/movdileu.c: New test.
> 	* gcc.target/riscv/movdilt.c: New test.
> 	* gcc.target/riscv/movdiltu.c: New test.
> 	* gcc.target/riscv/movdine.c: New test.
> 	* gcc.target/riscv/movsieq.c: New test.
> 	* gcc.target/riscv/movsige.c: New test.
> 	* gcc.target/riscv/movsigeu.c: New test.
> 	* gcc.target/riscv/movsigt.c: New test.
> 	* gcc.target/riscv/movsigtu.c: New test.
> 	* gcc.target/riscv/movsile.c: New test.
> 	* gcc.target/riscv/movsileu.c: New test.
> 	* gcc.target/riscv/movsilt.c: New test.
> 	* gcc.target/riscv/movsiltu.c: New test.
> 	* gcc.target/riscv/movsine.c: New test.
OK
jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 29/44] RISC-V: Add `addMODEcc' implementation for generic targets
  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
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Law @ 2023-11-19 18:23 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



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

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 30/44] RISC-V/testsuite: Add branched cases for generic integer cond adds
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 18:23 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:41, Maciej W. Rozycki wrote:
> Verify, for generic integer conditional-add operations, if-conversion
> *not* to trigger at the respective sufficiently low `-mbranch-cost='
> settings that make original branched code sequences cheaper than their
> branchless equivalents if-conversion would emit.  Cover all integer
> relational operations to make sure no corner case escapes.
> 	
> gcc/testsuite/
> 	* gcc.target/riscv/adddibeq.c: New test.
> 	* gcc.target/riscv/adddibge.c: New test.
> 	* gcc.target/riscv/adddibgeu.c: New test.
> 	* gcc.target/riscv/adddibgt.c: New test.
> 	* gcc.target/riscv/adddibgtu.c: New test.
> 	* gcc.target/riscv/adddible.c: New test.
> 	* gcc.target/riscv/adddibleu.c: New test.
> 	* gcc.target/riscv/adddiblt.c: New test.
> 	* gcc.target/riscv/adddibltu.c: New test.
> 	* gcc.target/riscv/adddibne.c: New test.
> 	* gcc.target/riscv/addsibeq.c: New test.
> 	* gcc.target/riscv/addsibge.c: New test.
> 	* gcc.target/riscv/addsibgeu.c: New test.
> 	* gcc.target/riscv/addsibgt.c: New test.
> 	* gcc.target/riscv/addsibgtu.c: New test.
> 	* gcc.target/riscv/addsible.c: New test.
> 	* gcc.target/riscv/addsibleu.c: New test.
> 	* gcc.target/riscv/addsiblt.c: New test.
> 	* gcc.target/riscv/addsibltu.c: New test.
> 	* gcc.target/riscv/addsibne.c: New test.
OK
jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 31/44] RISC-V/testsuite: Add branchless cases for generic integer cond adds
  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
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Law @ 2023-11-19 18:25 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:41, Maciej W. Rozycki wrote:
> Verify, for generic integer conditional-add operations, if-conversion
> to trigger via `noce_try_addcc' at the respective sufficiently high
> `-mbranch-cost=' settings that make branchless code sequences produced
> by if-conversion cheaper than their original branched equivalents, and,
> where applicable, that extraneous instructions such as SNEZ, etc. are
> not present in output.  Cover all integer relational operations to make
> sure no corner case escapes.
> 
> The reason to XFAIL SImode tests for RV64 targets is the compiler thinks
> it has to sign-extend addends, which causes if-conversion to give up.
WRT extension and causing if-conversion to give up.  Yes, it's a real 
issue.  In fact when we had Jivan do some analysis work on missed 
if-conversions, better handling of 32bit operations on rv64 was the 
biggest class of missed cases.

We've got a bit of internal code to address that.  But I've been having 
trouble finding the time to clean it up enough to post.

> 
> 	gcc/testsuite/
> 	* gcc.target/riscv/adddieq.c: New test.
> 	* gcc.target/riscv/adddige.c: New test.
> 	* gcc.target/riscv/adddigeu.c: New test.
> 	* gcc.target/riscv/adddigt.c: New test.
> 	* gcc.target/riscv/adddigtu.c: New test.
> 	* gcc.target/riscv/adddile.c: New test.
> 	* gcc.target/riscv/adddileu.c: New test.
> 	* gcc.target/riscv/adddilt.c: New test.
> 	* gcc.target/riscv/adddiltu.c: New test.
> 	* gcc.target/riscv/adddine.c: New test.
> 	* gcc.target/riscv/addsieq.c: New test.
> 	* gcc.target/riscv/addsige.c: New test.
> 	* gcc.target/riscv/addsigeu.c: New test.
> 	* gcc.target/riscv/addsigt.c: New test.
> 	* gcc.target/riscv/addsigtu.c: New test.
> 	* gcc.target/riscv/addsile.c: New test.
> 	* gcc.target/riscv/addsileu.c: New test.
> 	* gcc.target/riscv/addsilt.c: New test.
> 	* gcc.target/riscv/addsiltu.c: New test.
> 	* gcc.target/riscv/addsine.c: New test.
OK
jeff


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 32/44] RISC-V: Only use SUBREG if applicable in `riscv_expand_float_scc'
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 18:26 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:42, Maciej W. Rozycki wrote:
> A subsequent change to enable the processing of conditional moves on a
> floating-point condition by `riscv_expand_conditional_move' will cause
> `riscv_expand_float_scc' to be called for word-mode target RTX with RV64
> targets.  In that case an invalid insn such as:
> 
> (insn 25 24 0 (set (reg:DI 141)
>          (subreg:SI (reg:DI 143) 0)) -1
>       (nil))
> 
> would be produced, which would crash the compiler later on.  Since the
> output operand of the SET operation to be produced already has the same
> mode as the input operand does, just omit the use of SUBREG and assign
> directly.
> 
> 	gcc/
> 	* config/riscv/riscv.cc (riscv_expand_float_scc): Suppress the
> 	use of SUBREG if the conditional-set target is word-mode.
OK
jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 33/44] RISC-V: Also allow FP conditions in `riscv_expand_conditional_move'
  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
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Law @ 2023-11-19 18:30 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:42, Maciej W. Rozycki wrote:
> In `riscv_expand_conditional_move' we only let integer conditions
> through at the moment, even though code has already been prepared to
> handle floating-point conditions as well.
> 
> Lift this restriction and only bail out if a non-word-mode integer
> condition has been requested, as we cannot handle this specific case
> owing to machine instruction set restriction.  We already take care of
> the non-integer, non-floating-point case later on.
> 
> 	gcc/
> 	* config/riscv/riscv.cc (riscv_expand_conditional_move): Don't
> 	bail out in floating-point conditions.
I probably goof'd something when merging up the eswin, vrull and ventana 
changes in this space.  I recall fixing multiple bugs in handling FP 
conditional moves when building/testing spec2017 internally -- so this 
was supposed to be working.


OK for the trunk.

Jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 22/44] RISC-V: Fold all the cond-move variants together
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 18:35 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:40, Maciej W. Rozycki wrote:
> Code in `riscv_expand_conditional_move' for Ventana and Zicond targets
> seems like bolted on as an afterthought rather than properly merged so
> as to handle all the cases together.
You could characterize it that way.  It was mostly a desire to not muck 
up any of the thead or sfb code which I know next to nothing about.  I 
think with the improvements in the testsuite from your series it's a lot 
more feasible to unify the implementations and be sure we haven't broken 
something along the way.


> 
> Fold the existing code pieces together then (observing that for short
> forward branch targets no integer comparisons need to be canonicalized),
> letting T-Head targets produce branchless sequences for all the integer
> comparisons rather than for equality ones only, and preparing for the
> handling of floating-point comparisons here across all conditional-move
> targets.
> 
> 	gcc/
> 	* config/riscv/riscv.cc (riscv_expand_conditional_move): Unify
> 	conditional-move handling across all the relevant targets.
OK

jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 09/44] RISC-V: Rework branch costing model for if-conversion
  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
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Law @ 2023-11-19 18:52 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:36, Maciej W. Rozycki wrote:
> The generic branch costing model for if-conversion assumes a fixed cost
> of COSTS_N_INSNS (2) for a conditional branch, and that one half of that
> cost comes from a preceding condition-set instruction, such as with
> MODE_CC targets, and then the other half of that cost is for the actual
> branch instruction.  This is hardcoded for `if_info.original_cost' in
> `noce_find_if_block' and regardless of the cost set for branches via
> BRANCH_COST.
> 
> Then `default_max_noce_ifcvt_seq_cost' instructs if-conversion to prefer
> a branchless sequence as costly as high as triple the BRANCH_COST value
> set.  This is apparently to make up for the inability to accurately
> guess the branch penalty.
> 
> Consequently for the BRANCH_COST of 3 we commonly set for tuning,
> if-conversion will consider branchless sequences costing 3 * 3 - 2 = 7
> instruction units more than a corresponding branch sequence.  For the
> BRANCH_COST of 4 such as with `sifive-7-series' tuning this is even
> worse, at 3 * 4 - 2 = 10.  Effectively it means a branchless sequence
> will always be chosen if available, even a very inefficient one.
> 
> Rework the branch costing model to better match our architecture,
> observing in particular that we have no preparatory instructions for
> branches so that the cost of a branch is naked BRANCH_COST plus any
> extra overhead the processing of a branch's source RTX might incur.
> 
> Provide TARGET_INSN_COST and TARGET_MAX_NOCE_IFCVT_SEQ_COST handlers
> than that return suitable cost based on BRANCH_COST.  The latter hook
> usually returns a value that is lower than the cost of the corresponding
> branched sequence.  This is because we don't really want to produce a
> branchless sequence that is more expensive than the original branched
> sequence.  If this turns out too conservative for some corner case, then
> this choice might be revisited.
> 
> Then we don't want to fiddle with `noce_find_if_block' without a lot of
> cross-target verification, so add TARGET_NOCE_CONVERSION_PROFITABLE_P
> defined such that it subtracts the fixed COSTS_N_INSNS (2) cost from the
> cost of the original branched sequence supplied and instead adds actual
> branch cost calculated from the conditional branch instruction used.  It
> is then further tweaked according to simple analysis of the replacement
> branchless sequence produced so as to cancel the cost of an extraneous
> zero extend operation produced by `noce_try_store_flag_mask' as observed
> with gcc/testsuite/gcc.target/riscv/pr105314.c.
> 
> Tweak the testsuite accordingly and set `-mbranch-cost=' explicitly for
> the relevant cases so that the expected if-conversion transformation is
> made regardless of the default BRANCH_COST value of tuning in effect.
> Some of these settings will be lowered later on as deficiencies in
> branchless sequence generation have been fixed that lower their cost
> calculated by if-conversion.
As I suspect you know a big part of the problem here is that BRANCH_COST 
and rtx_cost don't have any common scale and thus trying to compare 
BRANCH_COST to RTX_COST doesn't have well defined meaning.

That hasn't kept us from trying to do precisely that and the result has 
always been less than satisfactory.  You're introducing more, but I 
don't think there's a reasonable way out of this mess at this point.


> 
> 	gcc/
> 	* config/riscv/riscv.cc (riscv_insn_cost): New function.
> 	(riscv_max_noce_ifcvt_seq_cost): Likewise.
> 	(riscv_noce_conversion_profitable_p): Likewise.
> 	(TARGET_INSN_COST): New macro.
> 	(TARGET_MAX_NOCE_IFCVT_SEQ_COST): New macro.
> 	(TARGET_NOCE_CONVERSION_PROFITABLE_P: New macro.
> 
> 	gcc/testsuite/
> 	* gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c:
> 	Explicitly set the branch cost.
> 	* gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c:
> 	Likewise.
> 	* gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c:
> 	Likewise.
> 	* gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c:
> 	Likewise.
> 	* gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c:
> 	Likewise.
> 	* gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c:
> 	Likewise.
> ---
> FWIW I don't understand why the test cases absolutely HAD to have such
> overlong names guaranteed to exceed our 80 column limit in any context.
> It's such a pain to handle.
I dislike the long names as well.  I nearly changed them myself as part 
of the eswin submission, but that seemed a bit gratituous to me so I 
left them as-is.

If you wanted to rename them, be my guest, consider it pre-approved ;-)

WRT the extraneous zero-extension.  Isn't that arguably a bug in the scc 
expander for risc-v?  Fixing that isn't a prerequisite here, but it 
probably worth a bit of someone's time.

OK for the trunk.

jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 34/44] RISC-V: Provide FP conditional-branch instructions for if-conversion
  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
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Law @ 2023-11-19 19:42 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:42, Maciej W. Rozycki wrote:
> Do not expand floating-point conditional-branch RTL instructions right
> away that use a comparison operation that is either directly available
> as a machine conditional-set instruction or is NE, which can be emulated
> by EQ.  This is so that if-conversion sees them in their original form
> and can produce fewer operations tried in a branchless code sequence
> compared to when such an instruction has been already converted to a
> sequence of a floating-point conditional-set RTL instruction followed by
> an integer conditional-branch RTL instruction.  Split any floating-point
> conditional-branch RTL instructions still remaining after reload then.
> 
> Adjust the testsuite accordingly: since the middle end uses the inverse
> condition internally, an inverse conditional-set instruction may make it
> to assembly output and also `cond_move_process_if_block' will be used by
> if-conversion rather than `noce_process_if_block', because the latter
> function not yet been updated to handle inverted conditions.
> 
> 	gcc/
> 	* config/riscv/predicates.md (ne_operator): New predicate.
> 	* config/riscv/riscv.cc (riscv_insn_cost): Handle branches on a
> 	floating-point condition.
> 	* config/riscv/riscv.md (@cbranch<mode>4): Rename expander to...
> 	(@cbranch<ANYF:mode>4): ... this.  Only expand the RTX via
> 	`riscv_expand_conditional_branch' for `!signed_order_operator'
> 	operators, otherwise let it through.
> 	(*cbranch<ANYF:mode>4, *cbranch<ANYF:mode>4): New insns and
> 	splitters.
> 
> 	gcc/testsuite/
> 	* gcc.target/riscv/movdifge-sfb.c: Reject "if-conversion
> 	succeeded through" rather than accepting it.
> 	* gcc.target/riscv/movdifge-thead.c: Likewise.
> 	* gcc.target/riscv/movdifge-ventana.c: Likewise.
> 	* gcc.target/riscv/movdifge-zicond.c: Likewise.
> 	* gcc.target/riscv/movdifgt-sfb.c: Likewise.
> 	* gcc.target/riscv/movdifgt-thead.c: Likewise.
> 	* gcc.target/riscv/movdifgt-ventana.c: Likewise.
> 	* gcc.target/riscv/movdifgt-zicond.c: Likewise.
> 	* gcc.target/riscv/movdifle-sfb.c: Likewise.
> 	* gcc.target/riscv/movdifle-thead.c: Likewise.
> 	* gcc.target/riscv/movdifle-ventana.c: Likewise.
> 	* gcc.target/riscv/movdifle-zicond.c: Likewise.
> 	* gcc.target/riscv/movdiflt-sfb.c: Likewise.
> 	* gcc.target/riscv/movdiflt-thead.c: Likewise.
> 	* gcc.target/riscv/movdiflt-ventana.c: Likewise.
> 	* gcc.target/riscv/movdiflt-zicond.c: Likewise.
> 	* gcc.target/riscv/movsifge-sfb.c: Likewise.
> 	* gcc.target/riscv/movsifge-thead.c: Likewise.
> 	* gcc.target/riscv/movsifge-ventana.c: Likewise.
> 	* gcc.target/riscv/movsifge-zicond.c: Likewise.
> 	* gcc.target/riscv/movsifgt-sfb.c: Likewise.
> 	* gcc.target/riscv/movsifgt-thead.c: Likewise.
> 	* gcc.target/riscv/movsifgt-ventana.c: Likewise.
> 	* gcc.target/riscv/movsifgt-zicond.c: Likewise.
> 	* gcc.target/riscv/movsifle-sfb.c: Likewise.
> 	* gcc.target/riscv/movsifle-thead.c: Likewise.
> 	* gcc.target/riscv/movsifle-ventana.c: Likewise.
> 	* gcc.target/riscv/movsifle-zicond.c: Likewise.
> 	* gcc.target/riscv/movsiflt-sfb.c: Likewise.
> 	* gcc.target/riscv/movsiflt-thead.c: Likewise.
> 	* gcc.target/riscv/movsiflt-ventana.c: Likewise.
> 	* gcc.target/riscv/movsiflt-zicond.c: Likewise.
> 	* gcc.target/riscv/smax-ieee.c: Also accept FLT.D.
> 	* gcc.target/riscv/smaxf-ieee.c: Also accept FLT.S.
> 	* gcc.target/riscv/smin-ieee.c: Also accept FGT.D.
> 	* gcc.target/riscv/sminf-ieee.c: Also accept FGT.S.
So this is a more gradual lowering of the FP branches to allow ifcvt to 
do a better job.  Seems generally reasonable.  I don't expect that we're 
missing any significant simplifications, though I probably could 
construct a missed CSE/GCSE if I worked at it for a bit.

Presumably the length computation can't be handled by the generic code 
we've already got in place?

OK for the trunk.

jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 35/44] RISC-V: Avoid extraneous integer comparison for FP comparisons
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 19:44 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:42, Maciej W. Rozycki wrote:
> We have floating-point coditional-set machine instructions for a subset
> of FP comparisons, so avoid going through a comparison against constant
> zero in `riscv_expand_float_scc' where not necessary, preventing an
> extraneous RTL instruction from being produced that counts against the
> cost of the replacement branchless code sequence in if-conversion, e.g.:
> 
> (insn 29 6 30 2 (set (reg:DI 142)
>          (ge:DI (reg/v:DF 135 [ w ])
>              (reg/v:DF 136 [ x ]))) 297 {*cstoredfdi4}
>       (nil))
> (insn 30 29 31 2 (set (reg:DI 143)
>          (ne:DI (reg:DI 142)
>              (const_int 0 [0]))) 319 {*sne_zero_didi}
>       (nil))
> (insn 31 30 32 2 (set (reg:DI 141)
>          (reg:DI 143)) 206 {*movdi_64bit}
>       (nil))
> (insn 32 31 33 2 (set (reg:DI 144)
>          (neg:DI (reg:DI 141))) 15 {negdi2}
>       (nil))
> (insn 33 32 34 2 (set (reg:DI 145)
>          (and:DI (reg:DI 144)
>              (reg/v:DI 137 [ y ]))) 102 {*anddi3}
>       (nil))
> (insn 34 33 35 2 (set (reg:DI 146)
>          (not:DI (reg:DI 144))) 111 {one_cmpldi2}
>       (nil))
> (insn 35 34 36 2 (set (reg:DI 147)
>          (and:DI (reg:DI 146)
>              (reg/v:DI 138 [ z ]))) 102 {*anddi3}
>       (nil))
> (insn 36 35 21 2 (set (reg/v:DI 138 [ z ])
>          (ior:DI (reg:DI 145)
>              (reg:DI 147))) 105 {iordi3}
>       (nil))
> 
> where the second insn effectively just copies its input.  This now gets
> simplified to:
> 
> (insn 29 6 30 2 (set (reg:DI 141)
>          (ge:DI (reg/v:DF 135 [ w ])
>              (reg/v:DF 136 [ x ]))) 297 {*cstoredfdi4}
>       (nil))
> (insn 30 29 31 2 (set (reg:DI 142)
>          (neg:DI (reg:DI 141))) 15 {negdi2}
>       (nil))
> (insn 31 30 32 2 (set (reg:DI 143)
>          (and:DI (reg:DI 142)
>              (reg/v:DI 137 [ y ]))) 102 {*anddi3}
>       (nil))
> (insn 32 31 33 2 (set (reg:DI 144)
>          (not:DI (reg:DI 142))) 111 {one_cmpldi2}
>       (nil))
> (insn 33 32 34 2 (set (reg:DI 145)
>          (and:DI (reg:DI 144)
>              (reg/v:DI 138 [ z ]))) 102 {*anddi3}
>       (nil))
> (insn 34 33 21 2 (set (reg/v:DI 138 [ z ])
>          (ior:DI (reg:DI 143)
>              (reg:DI 145))) 105 {iordi3}
>       (nil))
> 
> lowering the cost of the code sequence produced (even though combine
> would swallow the second insn anyway).
> 
> We still need to produce a comparison against constant zero where the
> instruction following a floating-point coditional-set operation is a
> branch, so add canonicalization to `riscv_expand_conditional_branch'
> instead.
> 
> 	gcc/
> 	* config/riscv/riscv.cc (riscv_emit_float_compare) <NE>: Handle
> 	separately.
> 	<EQ, LE, LT, GE, GT>: Return operands supplied as is.
> 	(riscv_emit_binary): Call `riscv_emit_binary' directly rather
> 	than going through a temporary register for word-mode targets.
> 	(riscv_expand_conditional_branch): Canonicalize the comparison
> 	if not against constant zero.
OK
jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 36/44] RISC-V/testsuite: Add branched cases for generic FP cond moves
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 19:45 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:42, Maciej W. Rozycki wrote:
> Verify, for generic floating-point conditional-move operations that have
> a corresponding conditional-set machine instruction, that if-conversion
> does *not* trigger at `-mbranch-cost=4' setting, which makes original
> branched code sequences cheaper than their branchless equivalents
> if-conversion would emit.  Cover all the relevant floating-point
> relational operations to make sure no corner case escapes.
> 
> 	gcc/testsuite/
> 	* gcc.target/riscv/movdibfge.c: New test.
> 	* gcc.target/riscv/movdibfgt.c: New test.
> 	* gcc.target/riscv/movdibfle.c: New test.
> 	* gcc.target/riscv/movdibflt.c: New test.
> 	* gcc.target/riscv/movdibfne.c: New test.
> 	* gcc.target/riscv/movsibfge.c: New test.
> 	* gcc.target/riscv/movsibfgt.c: New test.
> 	* gcc.target/riscv/movsibfle.c: New test.
> 	* gcc.target/riscv/movsibflt.c: New test.
> 	* gcc.target/riscv/movsibfne.c: New test.
OK
jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 37/44] RISC-V/testsuite: Add branchless cases for generic FP cond moves
  2023-11-19  5:43 ` [PATCH 37/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
@ 2023-11-19 19:46   ` Jeff Law
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 19:46 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:43, Maciej W. Rozycki wrote:
> Verify, for generic floating-point conditional-move operations that have
> a corresponding conditional-set machine instruction, that if-conversion
> triggers (via `cond_move_convert_if_block', which doesn't report) at
> `-mbranch-cost=5' setting, which makes branchless code sequences emitted
> by if-conversion cheaper than their original branched equivalents, and
> that extraneous instructions such as SNEZ, etc. are not present in
> output.
> 
> 	gcc/testsuite/
> 	* gcc.target/riscv/movdifge.c: New test.
> 	* gcc.target/riscv/movdifgt.c: New test.
> 	* gcc.target/riscv/movdifle.c: New test.
> 	* gcc.target/riscv/movdiflt.c: New test.
> 	* gcc.target/riscv/movdifne.c: New test.
> 	* gcc.target/riscv/movsifge.c: New test.
> 	* gcc.target/riscv/movsifgt.c: New test.
> 	* gcc.target/riscv/movsifle.c: New test.
> 	* gcc.target/riscv/movsiflt.c: New test.
> 	* gcc.target/riscv/movsifne.c: New test.
OK
jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 38/44] RISC-V/testsuite: Add branched cases for generic FP cond adds
  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
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 19:46 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:43, Maciej W. Rozycki wrote:
> Verify, for generic floating-point conditional-add operations that have
> a corresponding conditional-set machine instruction, that if-conversion
> does *not* trigger at `-mbranch-cost=2' setting, which makes original
> branched code sequences cheaper than their branchless equivalents
> if-conversion would emit.  Cover all the relevant floating-point
> relational operations to make sure no corner case escapes.
> 
> 	gcc/testsuite/
> 	* gcc.target/riscv/adddibfeq.c: New test.
> 	* gcc.target/riscv/adddibfge.c: New test.
> 	* gcc.target/riscv/adddibfgt.c: New test.
> 	* gcc.target/riscv/adddibfle.c: New test.
> 	* gcc.target/riscv/adddibflt.c: New test.
> 	* gcc.target/riscv/addsibfeq.c: New test.
> 	* gcc.target/riscv/addsibfge.c: New test.
> 	* gcc.target/riscv/addsibfgt.c: New test.
> 	* gcc.target/riscv/addsibfle.c: New test.
> 	* gcc.target/riscv/addsibflt.c: New test.
OK
jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 39/44] RISC-V/testsuite: Add branchless cases for generic FP cond adds
  2023-11-19  5:43 ` [PATCH 39/44] RISC-V/testsuite: Add branchless " Maciej W. Rozycki
@ 2023-11-19 19:47   ` Jeff Law
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Law @ 2023-11-19 19:47 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:43, Maciej W. Rozycki wrote:
> Verify, for generic floating-point conditional-add operations that have
> a corresponding conditional-set machine instruction, that if-conversion
> triggers via `noce_try_addcc' at `-mbranch-cost=3' setting, which makes
> branchless code sequences emitted by if-conversion cheaper than their
> original branched equivalents, and that extraneous instructions such as
> SNEZ, etc. are not present in output.
> 
> The reason to XFAIL SImode tests for RV64 targets is the compiler thinks
> it has to sign-extend addends, which causes if-conversion to give up.
> 
> 	gcc/testsuite/
> 	* gcc.target/riscv/adddifeq.c: New test.
> 	* gcc.target/riscv/adddifge.c: New test.
> 	* gcc.target/riscv/adddifgt.c: New test.
> 	* gcc.target/riscv/adddifle.c: New test.
> 	* gcc.target/riscv/adddiflt.c: New test.
> 	* gcc.target/riscv/addsifeq.c: New test.
> 	* gcc.target/riscv/addsifge.c: New test.
> 	* gcc.target/riscv/addsifgt.c: New test.
> 	* gcc.target/riscv/addsifle.c: New test.
> 	* gcc.target/riscv/addsiflt.c: New test.
OK
jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 40/44] RISC-V: Handle FP NE operator via inversion in cond-operation expansion
  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
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Law @ 2023-11-19 19:51 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches
  Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/18/23 22:43, Maciej W. Rozycki wrote:
> We have no FNE.fmt machine instructions, but we can emulate them for the
> purpose of conditional-move and conditional-add operations by using the
> respective FEQ.fmt instruction and then swapping the data input operands
> or complementing the mask for the conditional addend respectively, so
> update our handlers accordingly.
> 
> 	gcc/
> 	* config/riscv/riscv-protos.h (riscv_expand_float_scc): Add
> 	`invert_ptr' parameter.
> 	* config/riscv/riscv.cc (riscv_emit_float_compare): Add NE
> 	inversion handling.
> 	(riscv_expand_float_scc): Pass `invert_ptr' through to
> 	`riscv_emit_float_compare'.
> 	(riscv_expand_conditional_move): Pass `&invert' to
> 	`riscv_expand_float_scc'.
> 	* config/riscv/riscv.md (add<mode>cc): Likewise.
This and the rest of the patches (41, 42, 43, 44) in this series are OK.

I think between Kito and myself, we've reviewed the whole set, right?

jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 01/44] testsuite: Add cases for conditional-move and conditional-add operations
  2023-11-19  5:52   ` Kito Cheng
@ 2023-11-20 10:16     ` Maciej W. Rozycki
  2023-11-20 12:57       ` Richard Biener
  0 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-20 10:16 UTC (permalink / raw)
  To: Kito Cheng; +Cc: gcc-patches, Andrew Waterman, Jim Wilson, Palmer Dabbelt

On Sun, 19 Nov 2023, Kito Cheng wrote:

> ok

 Thank you for your review, but I think I need a general maintainer's ack 
for this one.

  Maciej

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 01/44] testsuite: Add cases for conditional-move and conditional-add operations
  2023-11-20 10:16     ` Maciej W. Rozycki
@ 2023-11-20 12:57       ` Richard Biener
  2023-11-22  1:33         ` Maciej W. Rozycki
  0 siblings, 1 reply; 101+ messages in thread
From: Richard Biener @ 2023-11-20 12:57 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Kito Cheng, gcc-patches, Andrew Waterman, Jim Wilson, Palmer Dabbelt

On Mon, Nov 20, 2023 at 11:16 AM Maciej W. Rozycki <macro@embecosm.com> wrote:
>
> On Sun, 19 Nov 2023, Kito Cheng wrote:
>
> > ok
>
>  Thank you for your review, but I think I need a general maintainer's ack
> for this one.

OK.

>   Maciej

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 01/44] testsuite: Add cases for conditional-move and conditional-add operations
  2023-11-20 12:57       ` Richard Biener
@ 2023-11-22  1:33         ` Maciej W. Rozycki
  0 siblings, 0 replies; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-22  1:33 UTC (permalink / raw)
  To: Richard Biener
  Cc: Kito Cheng, gcc-patches, Andrew Waterman, Jim Wilson, Palmer Dabbelt

On Mon, 20 Nov 2023, Richard Biener wrote:

> > > ok
> >
> >  Thank you for your review, but I think I need a general maintainer's ack
> > for this one.
> 
> OK.

 I have committed this change now, thank you for your review.

  Maciej

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 40/44] RISC-V: Handle FP NE operator via inversion in cond-operation expansion
  2023-11-19 19:51   ` Jeff Law
@ 2023-11-22  1:37     ` Maciej W. Rozycki
  0 siblings, 0 replies; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-22  1:37 UTC (permalink / raw)
  To: Jeff Law
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

On Sun, 19 Nov 2023, Jeff Law wrote:

> > 	gcc/
> > 	* config/riscv/riscv-protos.h (riscv_expand_float_scc): Add
> > 	`invert_ptr' parameter.
> > 	* config/riscv/riscv.cc (riscv_emit_float_compare): Add NE
> > 	inversion handling.
> > 	(riscv_expand_float_scc): Pass `invert_ptr' through to
> > 	`riscv_emit_float_compare'.
> > 	(riscv_expand_conditional_move): Pass `&invert' to
> > 	`riscv_expand_float_scc'.
> > 	* config/riscv/riscv.md (add<mode>cc): Likewise.
> This and the rest of the patches (41, 42, 43, 44) in this series are OK.

 I have committed the whole patch set now, thank you for your review.  
I'll address the concerns raised in the course separately.

  Maciej

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 09/44] RISC-V: Rework branch costing model for if-conversion
  2023-11-19 18:52   ` Jeff Law
@ 2023-11-23 18:34     ` Maciej W. Rozycki
  2023-11-29  1:19       ` Jeff Law
  0 siblings, 1 reply; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-23 18:34 UTC (permalink / raw)
  To: Jeff Law
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

On Sun, 19 Nov 2023, Jeff Law wrote:

> As I suspect you know a big part of the problem here is that BRANCH_COST and
> rtx_cost don't have any common scale and thus trying to compare BRANCH_COST to
> RTX_COST doesn't have well defined meaning.

 We do have preexisting places using COSTS_N_INSNS (BRANCH_COST ()) 
though, as documented in ifcvt.cc:

     ??? Actually, instead of the branch instruction costs we might want
     to use COSTS_N_INSNS (BRANCH_COST ()) as in other places.  */

so it seems the right direction, and given that we expose this measure to 
the user (and at the very least GCC developers implementing new tuning 
microarchitectures) I think it's the only sane way to do branch costing: 
define the measure in terms of how many ordinary ALU instructions a branch 
is statistically equivalent to.

 We may have to consider whether we want/need higher resolution here, 
effectively branch costs including a fractional part.

> That hasn't kept us from trying to do precisely that and the result has always
> been less than satisfactory.  You're introducing more, but I don't think
> there's a reasonable way out of this mess at this point.

 Ack.

> > FWIW I don't understand why the test cases absolutely HAD to have such
> > overlong names guaranteed to exceed our 80 column limit in any context.
> > It's such a pain to handle.
> I dislike the long names as well.  I nearly changed them myself as part of the
> eswin submission, but that seemed a bit gratituous to me so I left them as-is.
> 
> If you wanted to rename them, be my guest, consider it pre-approved ;-)

 Ack.

> WRT the extraneous zero-extension.  Isn't that arguably a bug in the scc
> expander for risc-v?  Fixing that isn't a prerequisite here, but it probably
> worth a bit of someone's time.

 I've looked at it already and it's the middle end that ends up with the 
zero-extension, specifically `convert_move' invoked from `emit_cstore' 
down the call to `noce_try_store_flag_mask', to widen the output from 
`cstoredi4', so I don't think we can do anything in the backend to prevent 
it from happening.  And neither I think we can do anything useful about 
`cstoredi4' having a SImode output, as it's a pattern matched by name 
rather than RTX, so we can't provide variants having a SImode and a DImode 
output each both at a time, as that would cause a name clash.

 What we could do is adding new named patterns with the output mode spelt 
out explicitly, such as `cstoresidi4', `cstoredidi4', etc., but that would 
be quite a big rewrite.  Maybe worth doing, maybe not, I don't know.  For 
the time being the hack I have made does the trick.

  Maciej

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 11/44] RISC-V/testsuite: Add branchless cases for integer cond-move operations
  2023-11-19  6:47   ` Kito Cheng
@ 2023-11-23 19:18     ` Maciej W. Rozycki
  0 siblings, 0 replies; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-23 19:18 UTC (permalink / raw)
  To: Kito Cheng; +Cc: gcc-patches, Andrew Waterman, Jim Wilson, Palmer Dabbelt

On Sun, 19 Nov 2023, Kito Cheng wrote:

> Just one minor comment, I think we don't really need to check rv64 or
> rv32 for those compiled without any header file test, but I am fine
> with that.

 We need to set `-march=' differently depending on whether verifying for 
rv64 or rv32, and then we don't want to limit testing to one of these 
subarchitectures only, because different code paths are covered in some 
cases depending on the machine word size.  This is especially clear with 
the cases that succeed for rv64 and currently fail for rv32, but it is 
also true elsewhere, e.g. where a SImode intermediate SCC result is 
widened to DImode with rv64, but kept intact with rv64.

  Maciej

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 26/44] RISC-V: Add `movMODEcc' implementation for generic targets
  2023-11-19 18:18   ` Jeff Law
@ 2023-11-23 22:16     ` Maciej W. Rozycki
  0 siblings, 0 replies; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-23 22:16 UTC (permalink / raw)
  To: Jeff Law
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

On Sun, 19 Nov 2023, Jeff Law wrote:

> OK.  Just curious are y'all seeing significant interest in this case from
> customers or is this more a case of rounding out the implementation to cover
> all potential possibilities?

 As in the cover letter: we have a case where the pipeline seems to imply 
high enough a branch penalty for branchless alternatives to be worth 
considering even where built from more than just a couple instructions.  
We yet have to fully evaluate it for our case and it may be that these 
sequences are costlier than branches after all or that the boundary lies 
somewhere in between (or that we end up with Zicond also available in the 
CPU RTL).  However we realised that combined with `-mbranch-cost=' it 
might be a useful tool for performance evaluation for other people as 
well.

 This, combined with the branch costing issues observed earlier and 
attempted to address with 09/44, is also why I chose, conservatively, to 
add the `-mmovcc' option to control this feature: we may choose to flip it 
on by default for some tuning architectures or even globally at one point.  
Especially as it seems like the `addMODEcc' part could be profitable for 
some architectures already.

  Maciej

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 29/44] RISC-V: Add `addMODEcc' implementation for generic targets
  2023-11-19 18:23   ` Jeff Law
@ 2023-11-23 22:36     ` Maciej W. Rozycki
  0 siblings, 0 replies; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-23 22:36 UTC (permalink / raw)
  To: Jeff Law
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

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

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 31/44] RISC-V/testsuite: Add branchless cases for generic integer cond adds
  2023-11-19 18:25   ` Jeff Law
@ 2023-11-23 22:48     ` Maciej W. Rozycki
  0 siblings, 0 replies; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-23 22:48 UTC (permalink / raw)
  To: Jeff Law
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

On Sun, 19 Nov 2023, Jeff Law wrote:

> > The reason to XFAIL SImode tests for RV64 targets is the compiler thinks
> > it has to sign-extend addends, which causes if-conversion to give up.
> WRT extension and causing if-conversion to give up.  Yes, it's a real issue.
> In fact when we had Jivan do some analysis work on missed if-conversions,
> better handling of 32bit operations on rv64 was the biggest class of missed
> cases.

 I have been aware of the issue with extraneous sign-extensions (and how 
our difference from the MIPS ISA makes it a problem in the first place), 
as I fixed some myself in the past and I do remember them being discussed 
at our weekly meetings as well, so I've decided the best course of action 
here will be this kind of test coverage.

> We've got a bit of internal code to address that.  But I've been having
> trouble finding the time to clean it up enough to post.

 Which will hopefully show up nicely as a bunch of XPASS results across 
these test cases once you do.

  Maciej

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 33/44] RISC-V: Also allow FP conditions in `riscv_expand_conditional_move'
  2023-11-19 18:30   ` Jeff Law
@ 2023-11-23 22:55     ` Maciej W. Rozycki
  0 siblings, 0 replies; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-23 22:55 UTC (permalink / raw)
  To: Jeff Law
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

On Sun, 19 Nov 2023, Jeff Law wrote:

> > Lift this restriction and only bail out if a non-word-mode integer
> > condition has been requested, as we cannot handle this specific case
> > owing to machine instruction set restriction.  We already take care of
> > the non-integer, non-floating-point case later on.
> > 
> > 	gcc/
> > 	* config/riscv/riscv.cc (riscv_expand_conditional_move): Don't
> > 	bail out in floating-point conditions.
> I probably goof'd something when merging up the eswin, vrull and ventana
> changes in this space.  I recall fixing multiple bugs in handling FP
> conditional moves when building/testing spec2017 internally -- so this was
> supposed to be working.

 This didn't matter though, because before 34/44 FP conditions could never 
make it here, not at least with pristine upstream code.

  Maciej

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 34/44] RISC-V: Provide FP conditional-branch instructions for if-conversion
  2023-11-19 19:42   ` Jeff Law
@ 2023-11-23 23:26     ` Maciej W. Rozycki
  0 siblings, 0 replies; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-23 23:26 UTC (permalink / raw)
  To: Jeff Law
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

On Sun, 19 Nov 2023, Jeff Law wrote:

> So this is a more gradual lowering of the FP branches to allow ifcvt to do a
> better job.  Seems generally reasonable.  I don't expect that we're missing
> any significant simplifications, though I probably could construct a missed
> CSE/GCSE if I worked at it for a bit.

 I've been thinking about it a little before submitting this patch in its 
final form.  I considered activating the splitter in split1 rather than 
split2, but figured out it would likely make little if any difference.  
We could add another, yet earlier split pass I suppose, somewhere between 
ce1 and cse2.  I'm not sure it would be worth it though.

> Presumably the length computation can't be handled by the generic code we've
> already got in place?

 I disregarded such an option right away at the time of writing this code. 
I'm sure this code could be folded, but not in a straightforward way.  
Notice the different, misaligned branch spans, owing to the machine branch 
instruction being the second in the ultimate instruction pair produced.  
So getting rid of this extra code may not be worth the complication in the 
common "length" attribute value calculation unless, perhaps, we factor the 
branch case out to a C++ function.

  Maciej

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 09/44] RISC-V: Rework branch costing model for if-conversion
  2023-11-23 18:34     ` Maciej W. Rozycki
@ 2023-11-29  1:19       ` Jeff Law
  2023-11-29 12:01         ` Maciej W. Rozycki
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Law @ 2023-11-29  1:19 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt



On 11/23/23 11:34, Maciej W. Rozycki wrote:
> On Sun, 19 Nov 2023, Jeff Law wrote:
> 
>> As I suspect you know a big part of the problem here is that BRANCH_COST and
>> rtx_cost don't have any common scale and thus trying to compare BRANCH_COST to
>> RTX_COST doesn't have well defined meaning.
> 
>   We do have preexisting places using COSTS_N_INSNS (BRANCH_COST ())
> though, as documented in ifcvt.cc:
> 
>       ??? Actually, instead of the branch instruction costs we might want
>       to use COSTS_N_INSNS (BRANCH_COST ()) as in other places.  */
> 
> so it seems the right direction, and given that we expose this measure to
> the user (and at the very least GCC developers implementing new tuning
> microarchitectures) I think it's the only sane way to do branch costing:
> define the measure in terms of how many ordinary ALU instructions a branch
> is statistically equivalent to.
Oh, it probably is the only sane way at this point.  To do anything more 
sane we'd have to disassociate the BRANCH_COST uses during tree/gimple 
from those in RTL-land.

FWIW, I was looking at a regression with our internal tests after your 
changes.   It was quite nice to see how well twiddling -mbranch-cost 
correlated to how many instructions we would allow in a conditional move 
sequence.

The downside is it highlighted the gimple vs RTL use issue.  I'm 
confident that we would like to see a higher branch cost in the RTL 
phases for our uarch, but I'm much less comfortable with how that's 
going to change the decisions made in trees/gimple.  We'll have to 
investigate that at some depth.



> 
>> WRT the extraneous zero-extension.  Isn't that arguably a bug in the scc
>> expander for risc-v?  Fixing that isn't a prerequisite here, but it probably
>> worth a bit of someone's time.
> 
>   I've looked at it already and it's the middle end that ends up with the
> zero-extension, specifically `convert_move' invoked from `emit_cstore'
> down the call to `noce_try_store_flag_mask', to widen the output from
> `cstoredi4', so I don't think we can do anything in the backend to prevent
> it from happening.  And neither I think we can do anything useful about
> `cstoredi4' having a SImode output, as it's a pattern matched by name
> rather than RTX, so we can't provide variants having a SImode and a DImode
> output each both at a time, as that would cause a name clash.
We're actually tracking some of these extraneous extensions.  Do you 
happen to know if the zero-extended object happens to be (subreg:SI 
(reg:DI)) kind of construct?  That's the kind of thing we're chasing 
down right now from various points.  Vineet has already fixed one class 
of them.  Jivan and I are looking at others.

jeff

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 09/44] RISC-V: Rework branch costing model for if-conversion
  2023-11-29  1:19       ` Jeff Law
@ 2023-11-29 12:01         ` Maciej W. Rozycki
  0 siblings, 0 replies; 101+ messages in thread
From: Maciej W. Rozycki @ 2023-11-29 12:01 UTC (permalink / raw)
  To: Jeff Law
  Cc: gcc-patches, Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

On Tue, 28 Nov 2023, Jeff Law wrote:

> FWIW, I was looking at a regression with our internal tests after your
> changes.   It was quite nice to see how well twiddling -mbranch-cost
> correlated to how many instructions we would allow in a conditional move
> sequence.

 I'm a bit concerned though that our interpretation of `-mbranch-cost=0' 
is different from the middle end's, such as in `emit_store_flag':

  /* If we reached here, we can't do this with a scc insn, however there
     are some comparisons that can be done in other ways.  Don't do any
     of these cases if branches are very cheap.  */
  if (BRANCH_COST (optimize_insn_for_speed_p (), false) == 0)
    return 0;

> The downside is it highlighted the gimple vs RTL use issue.  I'm confident
> that we would like to see a higher branch cost in the RTL phases for our
> uarch, but I'm much less comfortable with how that's going to change the
> decisions made in trees/gimple.  We'll have to investigate that at some depth.

 Ack.

> >  I've looked at it already and it's the middle end that ends up with the
> > zero-extension, specifically `convert_move' invoked from `emit_cstore'
> > down the call to `noce_try_store_flag_mask', to widen the output from
> > `cstoredi4', so I don't think we can do anything in the backend to prevent
> > it from happening.  And neither I think we can do anything useful about
> > `cstoredi4' having a SImode output, as it's a pattern matched by name
> > rather than RTX, so we can't provide variants having a SImode and a DImode
> > output each both at a time, as that would cause a name clash.
> We're actually tracking some of these extraneous extensions.  Do you happen to
> know if the zero-extended object happens to be (subreg:SI (reg:DI)) kind of
> construct?  That's the kind of thing we're chasing down right now from various
> points.  Vineet has already fixed one class of them.  Jivan and I are looking
> at others.

 Under GDB it's a plain move from (reg:SI 140) to (reg:DI 139), as in the 
FROM and TO arguments to `convert_move' respectively.  This makes it call 
`convert_mode_scalar', which then chooses between `zext_optab' and 
`sext_optab' as appropriate, under:

  /* If the target has a converter from FROM_MODE to TO_MODE, use it.  */

to produce:

(set (reg:DI 139)
    (zero_extend:DI (reg:SI 140)))

ending up with this complete sequence:

(insn 27 0 28 (set (reg:SI 140)
        (eq:SI (reg/v:DI 137 [ c ])
            (const_int 0 [0]))) -1
     (nil))
(insn 28 27 29 (set (reg:DI 139)
        (zero_extend:DI (reg:SI 140))) -1
     (nil))
(insn 29 28 30 (set (reg:DI 141)
        (neg:DI (reg:DI 139))) -1
     (nil))
(insn 30 29 0 (set (reg/v:DI 134 [ <retval> ])
        (and:DI (reg/v:DI 135 [ a ])
            (reg:DI 141))) -1
     (nil))

passed to `targetm.noce_conversion_profitable_p' right away.  Maybe you 
can teach `emit_cstore' or `convert_move' to use a subreg when it is known
for the particular target that the value produced by the conditional-set 
machine instruction emitted by `cstoreMODE4' is valid unchanged in both 
modes.

 You can fiddle with it by trying:

$ gcc -march=rv64gc -mbranch-cost=3 -O2 -S gcc/testsuite/gcc.target/riscv/pr105314.c

Set a breakpoint at `noce_try_store_flag_mask' and then single-step to see 
how things proceed.

  Maciej

^ permalink raw reply	[flat|nested] 101+ messages in thread

end of thread, other threads:[~2023-11-29 12:01 UTC | newest]

Thread overview: 101+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 26/44] RISC-V: Add `movMODEcc' implementation for generic targets Maciej W. Rozycki
2023-11-19 18:18   ` 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

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).