diff options
-rw-r--r-- | gcc/config/riscv/bitmanip.md | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/zbb-andn-orn-01.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/zbb-andn-orn-02.c | 17 |
3 files changed, 46 insertions, 0 deletions
diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 0d126a8..0f45bad 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -215,6 +215,18 @@ [(set_attr "type" "bitmanip") (set_attr "mode" "<X:MODE>")]) +(define_insn_and_split "*<optab>_not_const<mode>" + [(set (match_operand:X 0 "register_operand" "=r") + (bitmanip_bitwise:X (not:X (match_operand:X 1 "register_operand" "r")) + (match_operand:X 2 "const_arith_operand" "I"))) + (clobber (match_scratch:X 3 "=&r"))] + "(TARGET_ZBB || TARGET_ZBKB) && !TARGET_ZCB + && !optimize_function_for_size_p (cfun)" + "#" + "&& reload_completed" + [(set (match_dup 3) (match_dup 2)) + (set (match_dup 0) (bitmanip_bitwise:X (not:X (match_dup 1)) (match_dup 3)))]) + ;; '(a >= 0) ? b : 0' is emitted branchless (from if-conversion). Without a ;; bit of extra help for combine (i.e., the below split), we end up emitting ;; not/srai/and instead of combining the not into an andn. diff --git a/gcc/testsuite/gcc.target/riscv/zbb-andn-orn-01.c b/gcc/testsuite/gcc.target/riscv/zbb-andn-orn-01.c new file mode 100644 index 0000000..f9f3222 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zbb-andn-orn-01.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zbb -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-g" "-Oz" "-Os" } } */ + +int foo1(int rs1) +{ + return 100 & ~rs1; +} + +int foo2(int rs1) +{ + return 100 | ~rs1; +} + +/* { dg-final { scan-assembler-times "andn\t" 1 } } */ +/* { dg-final { scan-assembler-times "orn\t" 1 } } */ +/* { dg-final { scan-assembler-times "li\t" 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zbb-andn-orn-02.c b/gcc/testsuite/gcc.target/riscv/zbb-andn-orn-02.c new file mode 100644 index 0000000..112c0fa --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zbb-andn-orn-02.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zbb -mabi=ilp32" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-g" "-Oz" "-Os" } } */ + +int foo1(int rs1) +{ + return 100 & ~rs1; +} + +int foo2(int rs1) +{ + return 100 | ~rs1; +} + +/* { dg-final { scan-assembler-times "andn\t" 1 } } */ +/* { dg-final { scan-assembler-times "orn\t" 1 } } */ +/* { dg-final { scan-assembler-times "li\t" 2 } } */ |