https://gcc.gnu.org/g:635d3209171d20bce4de35041097064a3afeff66

commit r17-5640-g635d3209171d20bce4de35041097064a3afeff66
Author: Jiawei <[email protected]>
Date:   Tue Oct 27 07:32:07 2026 -0600

    [PATCH 3/3] RISC-V: Fix Zbkb packh cost and instruction selection
    
    Fix missed packh generation when Zbb and Zbkb are both enabled.
    Correct the cost model and prevent the generic shift-reverse pattern
    from taking precedence over the existing packh pattern.
    
    gcc/ChangeLog:
    
            * config/riscv/riscv.cc (riscv_rtx_costs): Cost the masked byte
            shift matching packh as one instruction when Zbkb is enabled.
            * config/riscv/riscv.md (<optab>_shift_reverse<X:mode>): Exclude
            the masked byte shift handled by packh when Zbkb is enabled.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/packh32.c: Enable Zbb alongside Zbkb.

Diff:
---
 gcc/config/riscv/riscv.cc                | 17 +++++++++++++++++
 gcc/config/riscv/riscv.md                |  2 ++
 gcc/testsuite/gcc.target/riscv/packh32.c |  2 +-
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index ec3a03421962..cc96cc0ad8bf 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -4730,6 +4730,23 @@ riscv_rtx_costs (rtx x, machine_mode mode, int 
outer_code, int opno ATTRIBUTE_UN
       return false;
 
     case AND:
+      /* The masked byte shift can be implemented with packh and a zero
+        first operand.  Cost it as one instruction so that combine can
+        use it as a bridge to the two-register packh pattern, even when
+        Zbb makes the separate zero extension inexpensive.  */
+      if (TARGET_ZBKB
+         && mode == word_mode
+         && GET_CODE (XEXP (x, 0)) == ASHIFT
+         && register_operand (XEXP (XEXP (x, 0), 0), mode)
+         && CONST_INT_P (XEXP (XEXP (x, 0), 1))
+         && INTVAL (XEXP (XEXP (x, 0), 1)) == 8
+         && CONST_INT_P (XEXP (x, 1))
+         && INTVAL (XEXP (x, 1)) == 0xff00)
+       {
+         *total = COSTS_N_INSNS (1);
+         return true;
+       }
+
       /* Andes bfo patterns.  */
       if (TARGET_XANDESPERF && GET_CODE (XEXP (x, 0)) == ASHIFT)
        {
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 898fa85ea626..24a9d5fbfd86 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3156,6 +3156,8 @@
   "(!SMALL_OPERAND (INTVAL (operands[3]))
     && SMALL_OPERAND (INTVAL (operands[3]) >> INTVAL (operands[2]))
     && (!TARGET_ZBS || popcount_hwi (INTVAL (operands[3])) > 1)
+    && !(TARGET_ZBKB && <CODE> == AND
+         && INTVAL (operands[2]) == 8 && INTVAL (operands[3]) == 0xff00)
     && (INTVAL (operands[3]) & ((1ULL << INTVAL (operands[2])) - 1)) == 0)"
   "#"
   "&& 1"
diff --git a/gcc/testsuite/gcc.target/riscv/packh32.c 
b/gcc/testsuite/gcc.target/riscv/packh32.c
index 803224189d50..cdcdee70d2e4 100644
--- a/gcc/testsuite/gcc.target/riscv/packh32.c
+++ b/gcc/testsuite/gcc.target/riscv/packh32.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -march=rv32gc_zbkb -mabi=ilp32" } */
+/* { dg-options "-O2 -march=rv32gc_zbb_zbkb -mabi=ilp32" } */
 /* { dg-skip-if "" { *-*-* } { "-g" "-flto" "-O0" } } */
 
 #include <stdint-gcc.h>

Reply via email to