@@ -233,6 +233,8 @@ (define_code_iterator any_gt [gt gtu])
(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])
@@ -124,3 +125,115 @@ (define_split
{
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)))])
+
+
+
@@ -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)
@@ -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" } } */
@@ -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=3" } */
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" } } */
@@ -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=3" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3" { 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" } } */
@@ -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=6 -mmovcc" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc" { target { rv64 } } } */
int
foo (long a, long b)
@@ -22,6 +22,6 @@ foo (long a, long b)
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" } } */