]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Remove zba check in bitwise and ashift reassociation [PR 115921]
authorXi Ruoyao <xry111@xry111.site>
Mon, 13 Jan 2025 20:11:38 +0000 (13:11 -0700)
committerJeff Law <jlaw@ventanamicro.com>
Mon, 13 Jan 2025 20:11:38 +0000 (13:11 -0700)
The test case

    long
    test (long x, long y)
    {
      return ((x | 0x1ff) << 3) + y;
    }

is now compiled (-O2 -march=rv64g_zba) to

    li      a4,4096
    slliw   a5,a0,3
    addi    a4,a4,-8
    or      a5,a5,a4
    addw    a0,a5,a1
    ret

Despite this check was originally intended to use zba better, now
removing it actually enables the use of zba for this test case (thanks
to late combine):

    ori    a5,a0,511
    sh3add  a0,a5,a1
    ret

Obviously, bitmanip.md does not cover
(any_or (ashift (reg) (imm123)) imm) at all, and even for and it just
seems more natural splitting to (ashift (and (reg) (imm')) (imm123))
first, then let late combine to combine the outer ashift and the plus.

I've not found any test case regressed by the removal.
And "make check-gcc RUNTESTFLAGS=riscv.exp='zba-*.c'" also reports no
failure.

gcc/ChangeLog:

PR target/115921
* config/riscv/riscv.md (<optab>_shift_reverse): Remove
check for TARGET_ZBA.

gcc/testsuite/ChangeLog:

PR target/115921
* gcc.target/riscv/zba-shNadd-08.c: New test.

gcc/config/riscv/riscv.md
gcc/testsuite/gcc.target/riscv/zba-shNadd-08.c [new file with mode: 0644]

index 0a76ed63f0d10227c86279e4db1496d20ed771c6..fd98e0a481ee80e8299eb6a767a6f0fe7bd7dc49 100644 (file)
 ;; for IOR/XOR.  It probably doesn't matter for AND.
 ;;
 ;; We also don't want to do this if the immediate already fits in a simm12
-;; field, or it is a single bit operand and zbs is available, or when we
-;; might be able to generate a shift-add sequence via the splitter in
-;; bitmanip.md for masks that are a run of consecutive ones.
+;; field, or it is a single bit operand and zbs is available.
 (define_insn_and_split "<optab>_shift_reverse<X:mode>"
   [(set (match_operand:X 0 "register_operand" "=r")
     (any_bitwise:X (ashift:X (match_operand:X 1 "register_operand" "r")
   "(!SMALL_OPERAND (INTVAL (operands[3]))
     && SMALL_OPERAND (INTVAL (operands[3]) >> INTVAL (operands[2]))
     && (!TARGET_ZBS || popcount_hwi (INTVAL (operands[3])) > 1)
-    && (!(TARGET_64BIT && TARGET_ZBA)
-       || !consecutive_bits_operand (operands[3], VOIDmode)
-       || !imm123_operand (operands[2], VOIDmode))
     && (INTVAL (operands[3]) & ((1ULL << INTVAL (operands[2])) - 1)) == 0)"
   "#"
   "&& 1"
diff --git a/gcc/testsuite/gcc.target/riscv/zba-shNadd-08.c b/gcc/testsuite/gcc.target/riscv/zba-shNadd-08.c
new file mode 100644 (file)
index 0000000..50c9c4c
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zba -mabi=lp64 -O2" } */
+/* { dg-final { scan-assembler "sh3add" } } */
+
+long
+test (long x, long y)
+{
+  return ((x | 0x1ff) << 3) + y;
+}