diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md
index 2844cb02ff09526c9f69615f5becfc4b0427fed4..872c542e90652a92b2947fdb9ff42700838b4bf6 100644
--- a/gcc/config/riscv/iterators.md
+++ b/gcc/config/riscv/iterators.md
@@ -233,6 +233,8 @@
 (define_code_iterator any_ge [ge geu])
 (define_code_iterator any_lt [lt ltu])
 (define_code_iterator any_le [le leu])
+;; Iterators for conditions we can emit a sCC against 0 or a reg directly
+(define_code_iterator scc_0  [eq ne gt gtu])
 
 ; atomics code iterator
 (define_code_iterator any_atomic [plus ior xor and])
diff --git a/gcc/config/riscv/zicond.md b/gcc/config/riscv/zicond.md
index 3876be7f9d297511474676d07b2029172aa42c7d..ab1a5337ee53822c2b8f44c7f991e60a89004b99 100644
--- a/gcc/config/riscv/zicond.md
+++ b/gcc/config/riscv/zicond.md
@@ -124,3 +124,115 @@
 {
   operands[2] = GEN_INT (1 << UINTVAL(operands[2]));
 })
+
+;; In some cases gimple can give us a sequence with a logical and
+;; of two sCC insns.  This can be implemented an sCC feeding a
+;; conditional zero.
+(define_split
+  [(set (match_operand:X 0 "register_operand")
+	(and:X (ne:X (match_operand:X 1 "register_operand") (const_int 0))
+	       (scc_0:X (match_operand:X 2 "register_operand")
+			(match_operand:X 3 "reg_or_0_operand"))))
+   (clobber (match_operand:X 4 "register_operand"))]
+  "TARGET_ZICOND_LIKE || TARGET_XTHEADCONDMOV"
+  [(set (match_dup 4) (scc_0:X (match_dup 2) (match_dup 3)))
+   (set (match_dup 0) (if_then_else:X (eq:X (match_dup 1) (const_int 0))
+				      (const_int 0)
+				      (match_dup 4)))])
+
+;; Similarly but GE/GEU which requires (const_int 1) as an operand.
+(define_split
+  [(set (match_operand:X 0 "register_operand")
+	(and:X (ne:X (match_operand:X 1 "register_operand") (const_int 0))
+	       (any_ge:X (match_operand:X 2 "register_operand")
+			 (const_int 1))))
+   (clobber (match_operand:X 3 "register_operand"))]
+  "TARGET_ZICOND_LIKE || TARGET_XTHEADCONDMOV"
+  [(set (match_dup 3) (any_ge:X (match_dup 2) (const_int 1)))
+   (set (match_dup 0) (if_then_else:X (eq:X (match_dup 1) (const_int 0))
+				      (const_int 0)
+				      (match_dup 3)))])
+
+;; Similarly but LU/LTU which allows an arith_operand
+(define_split
+  [(set (match_operand:X 0 "register_operand")
+	(and:X (ne:X (match_operand:X 1 "register_operand") (const_int 0))
+	       (any_lt:X (match_operand:X 2 "register_operand")
+			 (match_operand:X 3 "arith_operand"))))
+   (clobber (match_operand:X 4 "register_operand"))]
+  "TARGET_ZICOND_LIKE || TARGET_XTHEADCONDMOV"
+  [(set (match_dup 4) (any_lt:X (match_dup 2) (match_dup 3)))
+   (set (match_dup 0) (if_then_else:X (eq:X (match_dup 1) (const_int 0))
+				      (const_int 0)
+				      (match_dup 4)))])
+
+;; Finally LE/LEU which requires sle_operand.
+(define_split
+  [(set (match_operand:X 0 "register_operand")
+	(and:X (ne:X (match_operand:X 1 "register_operand") (const_int 0))
+	       (any_le:X (match_operand:X 2 "register_operand")
+			 (match_operand:X 3 "sle_operand"))))
+   (clobber (match_operand:X 4 "register_operand"))]
+  "TARGET_ZICOND_LIKE || TARGET_XTHEADCONDMOV"
+  [(set (match_dup 4) (any_le:X (match_dup 2) (match_dup 3)))
+   (set (match_dup 0) (if_then_else:X (eq:X (match_dup 1) (const_int 0))
+				      (const_int 0)
+				      (match_dup 4)))])
+
+
+;; Inverted versions from above.  I tried to get this to work with
+;; iterators, but didn't have any success disambiguating the code attr
+;; for the eq/ne flip we have to do.
+(define_split
+  [(set (match_operand:X 0 "register_operand")
+	(and:X (eq:X (match_operand:X 1 "register_operand") (const_int 0))
+	       (scc_0:X (match_operand:X 2 "register_operand")
+			(match_operand:X 3 "reg_or_0_operand"))))
+   (clobber (match_operand:X 4 "register_operand"))]
+  "TARGET_ZICOND_LIKE || TARGET_XTHEADCONDMOV"
+  [(set (match_dup 4) (scc_0:X (match_dup 2) (match_dup 3)))
+   (set (match_dup 0) (if_then_else:X (ne:X (match_dup 1) (const_int 0))
+				      (const_int 0)
+				      (match_dup 4)))])
+
+;; Similarly but GE/GEU which requires (const_int 1) as an operand.
+(define_split
+  [(set (match_operand:X 0 "register_operand")
+	(and:X (eq:X (match_operand:X 1 "register_operand") (const_int 0))
+	       (any_ge:X (match_operand:X 2 "register_operand")
+			 (const_int 1))))
+   (clobber (match_operand:X 3 "register_operand"))]
+  "TARGET_ZICOND_LIKE || TARGET_XTHEADCONDMOV"
+  [(set (match_dup 3) (any_ge:X (match_dup 2) (const_int 1)))
+   (set (match_dup 0) (if_then_else:X (ne:X (match_dup 1) (const_int 0))
+				      (const_int 0)
+				      (match_dup 3)))])
+
+;; Similarly but LU/LTU which allows an arith_operand
+(define_split
+  [(set (match_operand:X 0 "register_operand")
+	(and:X (eq:X (match_operand:X 1 "register_operand") (const_int 0))
+	       (any_lt:X (match_operand:X 2 "register_operand")
+			 (match_operand:X 3 "arith_operand"))))
+   (clobber (match_operand:X 4 "register_operand"))]
+  "TARGET_ZICOND_LIKE || TARGET_XTHEADCONDMOV"
+  [(set (match_dup 4) (any_lt:X (match_dup 2) (match_dup 3)))
+   (set (match_dup 0) (if_then_else:X (ne:X (match_dup 1) (const_int 0))
+				      (const_int 0)
+				      (match_dup 4)))])
+
+;; Finally LE/LEU which requires sle_operand.
+(define_split
+  [(set (match_operand:X 0 "register_operand")
+	(and:X (eq:X (match_operand:X 1 "register_operand") (const_int 0))
+	       (any_le:X (match_operand:X 2 "register_operand")
+			 (match_operand:X 3 "sle_operand"))))
+   (clobber (match_operand:X 4 "register_operand"))]
+  "TARGET_ZICOND_LIKE || TARGET_XTHEADCONDMOV"
+  [(set (match_dup 4) (any_le:X (match_dup 2) (match_dup 3)))
+   (set (match_dup 0) (if_then_else:X (ne:X (match_dup 1) (const_int 0))
+				      (const_int 0)
+				      (match_dup 4)))])
+
+
+
diff --git a/gcc/testsuite/gcc.target/riscv/cset-sext-sfb.c b/gcc/testsuite/gcc.target/riscv/cset-sext-sfb.c
index 1a3e7104bd8c1b5ab25bf811ad443efe5c83f556..6e9f8cc61de09e6f73a53ebfebda6e83befcf2a6 100644
--- a/gcc/testsuite/gcc.target/riscv/cset-sext-sfb.c
+++ b/gcc/testsuite/gcc.target/riscv/cset-sext-sfb.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
-/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
-/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */
-/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" } } */
+/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fno-ssa-phiopt -fdump-rtl-ce1" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fno-ssa-phiopt -fdump-rtl-ce1" { target { rv64 } } } */
 
 int
 foo (long a, long b)
@@ -22,7 +22,7 @@ foo (long a, long b)
 1:
  */
 
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove_arith" 1 "ce1" { xfail { rv32 && { any-opts "-O1" } } } } } */
+/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove_arith" 1 "ce1" } }
 /* { dg-final { scan-assembler-times "\\ssnez\\s" 1 } } */
-/* { dg-final { scan-assembler-times "\\sbne\\s\[^\\s\]+\\s# movcc\\s" 1 { xfail { rv32 && { any-opts "-O1" } } } } } */
-/* { dg-final { scan-assembler-not "\\sbeq\\s" { xfail { rv32 && { any-opts "-O1" } } } } } */
+/* { dg-final { scan-assembler-times "\\sbne\\s\[^\\s\]+\\s# movcc\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\sbeq\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cset-sext-thead.c b/gcc/testsuite/gcc.target/riscv/cset-sext-thead.c
index 45b94704aaf6f17948f751b3f5097517855f109b..74cae71d7a0bb21c4d689df74977701759140a5d 100644
--- a/gcc/testsuite/gcc.target/riscv/cset-sext-thead.c
+++ b/gcc/testsuite/gcc.target/riscv/cset-sext-thead.c
@@ -1,7 +1,7 @@
 /* { 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" } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1" } */
 
 int
 foo (long a, long b)
@@ -20,7 +20,6 @@ foo (long a, long b)
 	th.mveqz	a0,zero,a1
  */
 
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove_arith" 1 "ce1" } } */
 /* { dg-final { scan-assembler-times "\\ssnez\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */
 /* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cset-sext-ventana.c b/gcc/testsuite/gcc.target/riscv/cset-sext-ventana.c
index eac1e1376cb4e119b7f7bb6fe11dda3fa4608cbe..8c3ca98bc2fcec9118556968e850db4a2d09cb0f 100644
--- a/gcc/testsuite/gcc.target/riscv/cset-sext-ventana.c
+++ b/gcc/testsuite/gcc.target/riscv/cset-sext-ventana.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target rv64 } */
 /* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
-/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */
+/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=1" } */
 
 int
 foo (long a, long b)
@@ -20,7 +20,6 @@ foo (long a, long b)
 	vt.maskc	a0,a0,a1
  */
 
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove_arith" 1 "ce1" } } */
 /* { dg-final { scan-assembler-times "\\ssnez\\s" 1 } } */
 /* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */
 /* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cset-sext-zicond.c b/gcc/testsuite/gcc.target/riscv/cset-sext-zicond.c
index a526b0c3d5a68570354f7abf2ce316d0dd534805..ec715254d4e21c52d693e351243dbd78808d1013 100644
--- a/gcc/testsuite/gcc.target/riscv/cset-sext-zicond.c
+++ b/gcc/testsuite/gcc.target/riscv/cset-sext-zicond.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
-/* { 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 } } } */
+/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=1" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=1" { target { rv32 } } } */
 
 int
 foo (long a, long b)
@@ -20,7 +20,6 @@ foo (long a, long b)
 	czero.eqz	a0,a0,a1
  */
 
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove_arith" 1 "ce1" { xfail { rv32 && { any-opts "-O1" "-Os" "-Oz" } } } } } */
 /* { dg-final { scan-assembler-times "\\ssnez\\s" 1 } } */
-/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 { xfail { rv32 && { any-opts "-O1" "-Os" "-Oz" } } } } } */
-/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail { rv32 && { any-opts "-O1" "-Os" "-Oz" } } } } } */
+/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cset-sext.c b/gcc/testsuite/gcc.target/riscv/cset-sext.c
index a1293cd62ea7eae5fd262a8603dd0732d303d383..e1c3239d146107fc10f23584a6e4e74fa7bf0542 100644
--- a/gcc/testsuite/gcc.target/riscv/cset-sext.c
+++ b/gcc/testsuite/gcc.target/riscv/cset-sext.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
-/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */
-/* { 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=1 -mmovcc" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=1 -mmovcc" { target { rv64 } } } */
 
 int
 foo (long a, long b)
@@ -17,11 +17,10 @@ foo (long a, long b)
 /* Expect branchless assembly like:
 
 	snez	a1,a1
-	neg	a1,a1
 	snez	a0,a0
 	and	a0,a1,a0
  */
 
-/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove_arith" 1 "ce1" { xfail { rv32 && { any-opts "-O1" } } } } } */
-/* { dg-final { scan-assembler-times "\\ssnez\\s" 2 { xfail { rv32 && { any-opts "-O1" } } } } } */
-/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail { rv32 && { any-opts "-O1" } } } } } */
+/* { dg-final { scan-assembler-times "\\ssnez\\s" 2 } } */
+/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */
+/* { dg-final { scan-assembler-not "\\sneg\\s" } } */