Skip to content

[RISCV] Don't prefer QC_EXT for SEXT_INREG patterns when Zbb is enabled #144837

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 19, 2025

Conversation

svs-quic
Copy link
Contributor

Zbb has the sext.b and sext.h instructions that are compressible.

@svs-quic svs-quic changed the title [RISCV] Dont prefer QC_EXT for SEXT_INREG patterns when Zbb is enabled [RISCV] Don't prefer QC_EXT for SEXT_INREG patterns when Zbb is enabled Jun 19, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 19, 2025

@llvm/pr-subscribers-backend-risc-v

Author: Sudharsan Veeravalli (svs-quic)

Changes

Zbb has the sext.b and sext.h instructions that are compressible.


Full diff: https://github.com/llvm/llvm-project/pull/144837.diff

2 Files Affected:

  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+6-2)
  • (modified) llvm/test/CodeGen/RISCV/xqcibm-extract.ll (+141)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 09852c6fd5969..529f95c268b57 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -1439,8 +1439,6 @@ def : SelectQCbi<SETUGE, uimm16nonzero, Select_GPRNoX0_Using_CC_UImm16NonZero_QC
 } // let Predicates = [HasVendorXqcibi, IsRV32], AddedComplexity = 2
 
 let Predicates = [HasVendorXqcibm, IsRV32] in {
-def : Pat<(sext_inreg (i32 GPR:$rs1), i16), (QC_EXT GPR:$rs1, 16, 0)>;
-def : Pat<(sext_inreg (i32 GPR:$rs1), i8), (QC_EXT GPR:$rs1, 8, 0)>;
 def : Pat<(sext_inreg (i32 GPR:$rs1), i1), (QC_EXT GPR:$rs1, 1, 0)>;
 
 // Prefer qc.extu to andi for the following cases since the former can be compressed
@@ -1452,6 +1450,12 @@ def : Pat<(i32 (and GPRNoX0:$rs, 1023)), (QC_EXTU GPRNoX0:$rs, 10, 0)>;
 def : Pat<(i32 (and GPRNoX0:$rs, 2047)), (QC_EXTU GPRNoX0:$rs, 11, 0)>;
 } // Predicates = [HasVendorXqcibm, IsRV32]
 
+// If Zbb is enabled sext.b/h is preferred since they are compressible
+let Predicates = [HasVendorXqcibm, NoStdExtZbb, IsRV32] in {
+def : Pat<(sext_inreg (i32 GPR:$rs1), i16), (QC_EXT GPR:$rs1, 16, 0)>;
+def : Pat<(sext_inreg (i32 GPR:$rs1), i8), (QC_EXT GPR:$rs1, 8, 0)>;
+} // Predicates = [HasVendorXqcibm, NoStdExtZbb, IsRV32]
+
 let Predicates = [HasVendorXqcibm, HasStdExtZbb, IsRV32] in {
 def: Pat<(i32 (cttz (not (i32 GPR:$rs1)))), (QC_CTO GPR:$rs1)>;
 def: Pat<(i32 (ctlz (not (i32 GPR:$rs1)))), (QC_CLO GPR:$rs1)>;
diff --git a/llvm/test/CodeGen/RISCV/xqcibm-extract.ll b/llvm/test/CodeGen/RISCV/xqcibm-extract.ll
index edf6e9a2d5019..481bfdd666430 100644
--- a/llvm/test/CodeGen/RISCV/xqcibm-extract.ll
+++ b/llvm/test/CodeGen/RISCV/xqcibm-extract.ll
@@ -3,6 +3,8 @@
 ; RUN:   | FileCheck %s -check-prefixes=RV32I
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcibm -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s -check-prefixes=RV32XQCIBM
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcibm,+zbb -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s -check-prefixes=RV32XQCIBMZBB
 
 define i32 @sexti1_i32(i1 %a) nounwind {
 ; RV32I-LABEL: sexti1_i32:
@@ -15,6 +17,11 @@ define i32 @sexti1_i32(i1 %a) nounwind {
 ; RV32XQCIBM:       # %bb.0:
 ; RV32XQCIBM-NEXT:    qc.ext a0, a0, 1, 0
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: sexti1_i32:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    qc.ext a0, a0, 1, 0
+; RV32XQCIBMZBB-NEXT:    ret
   %sext = sext i1 %a to i32
   ret i32 %sext
 }
@@ -30,6 +37,11 @@ define i32 @sexti1_i32_2(i32 %a) {
 ; RV32XQCIBM:       # %bb.0:
 ; RV32XQCIBM-NEXT:    qc.ext a0, a0, 1, 0
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: sexti1_i32_2:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    qc.ext a0, a0, 1, 0
+; RV32XQCIBMZBB-NEXT:    ret
   %shl = shl i32 %a, 31
   %shr = ashr exact i32 %shl, 31
   ret i32 %shr
@@ -47,6 +59,11 @@ define i32 @sexti8_i32(i8 %a) nounwind {
 ; RV32XQCIBM:       # %bb.0:
 ; RV32XQCIBM-NEXT:    qc.ext a0, a0, 8, 0
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: sexti8_i32:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    sext.b a0, a0
+; RV32XQCIBMZBB-NEXT:    ret
   %sext = sext i8 %a to i32
   ret i32 %sext
 }
@@ -62,6 +79,11 @@ define i32 @sexti8_i32_2(i32 %a) {
 ; RV32XQCIBM:       # %bb.0:
 ; RV32XQCIBM-NEXT:    qc.ext a0, a0, 8, 0
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: sexti8_i32_2:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    sext.b a0, a0
+; RV32XQCIBMZBB-NEXT:    ret
   %shl = shl i32 %a, 24
   %shr = ashr exact i32 %shl, 24
   ret i32 %shr
@@ -78,6 +100,11 @@ define i32 @sexti16_i32(i16 %a) nounwind {
 ; RV32XQCIBM:       # %bb.0:
 ; RV32XQCIBM-NEXT:    qc.ext a0, a0, 16, 0
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: sexti16_i32:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    sext.h a0, a0
+; RV32XQCIBMZBB-NEXT:    ret
   %sext = sext i16 %a to i32
   ret i32 %sext
 }
@@ -93,6 +120,11 @@ define i32 @sexti16_i32_2(i32 %a) {
 ; RV32XQCIBM:       # %bb.0:
 ; RV32XQCIBM-NEXT:    qc.ext a0, a0, 16, 0
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: sexti16_i32_2:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    sext.h a0, a0
+; RV32XQCIBMZBB-NEXT:    ret
   %shl = shl i32 %a, 16
   %shr = ashr exact i32 %shl, 16
   ret i32 %shr
@@ -111,6 +143,12 @@ define i64 @sexti1_i64(i64 %a) {
 ; RV32XQCIBM-NEXT:    qc.ext a0, a0, 1, 0
 ; RV32XQCIBM-NEXT:    mv a1, a0
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: sexti1_i64:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    qc.ext a0, a0, 1, 0
+; RV32XQCIBMZBB-NEXT:    mv a1, a0
+; RV32XQCIBMZBB-NEXT:    ret
   %shl = shl i64 %a, 63
   %shr = ashr exact i64 %shl, 63
   ret i64 %shr
@@ -129,6 +167,12 @@ define i64 @sexti1_i64_2(i1 %a) {
 ; RV32XQCIBM-NEXT:    qc.ext a0, a0, 1, 0
 ; RV32XQCIBM-NEXT:    mv a1, a0
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: sexti1_i64_2:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    qc.ext a0, a0, 1, 0
+; RV32XQCIBMZBB-NEXT:    mv a1, a0
+; RV32XQCIBMZBB-NEXT:    ret
   %1 = sext i1 %a to i64
   ret i64 %1
 }
@@ -146,6 +190,12 @@ define i64 @sexti8_i64(i64 %a) {
 ; RV32XQCIBM-NEXT:    qc.ext a0, a0, 8, 0
 ; RV32XQCIBM-NEXT:    srai a1, a0, 31
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: sexti8_i64:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    sext.b a0, a0
+; RV32XQCIBMZBB-NEXT:    srai a1, a0, 31
+; RV32XQCIBMZBB-NEXT:    ret
   %shl = shl i64 %a, 56
   %shr = ashr exact i64 %shl, 56
   ret i64 %shr
@@ -164,6 +214,12 @@ define i64 @sexti8_i64_2(i8 %a) {
 ; RV32XQCIBM-NEXT:    qc.ext a0, a0, 8, 0
 ; RV32XQCIBM-NEXT:    srai a1, a0, 31
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: sexti8_i64_2:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    sext.b a0, a0
+; RV32XQCIBMZBB-NEXT:    srai a1, a0, 31
+; RV32XQCIBMZBB-NEXT:    ret
   %1 = sext i8 %a to i64
   ret i64 %1
 }
@@ -181,6 +237,12 @@ define i64 @sexti16_i64(i64 %a) {
 ; RV32XQCIBM-NEXT:    qc.ext a0, a0, 16, 0
 ; RV32XQCIBM-NEXT:    srai a1, a0, 31
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: sexti16_i64:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    sext.h a0, a0
+; RV32XQCIBMZBB-NEXT:    srai a1, a0, 31
+; RV32XQCIBMZBB-NEXT:    ret
   %shl = shl i64 %a, 48
   %shr = ashr exact i64 %shl, 48
   ret i64 %shr
@@ -199,6 +261,12 @@ define i64 @sexti16_i64_2(i16 %a) {
 ; RV32XQCIBM-NEXT:    qc.ext a0, a0, 16, 0
 ; RV32XQCIBM-NEXT:    srai a1, a0, 31
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: sexti16_i64_2:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    sext.h a0, a0
+; RV32XQCIBMZBB-NEXT:    srai a1, a0, 31
+; RV32XQCIBMZBB-NEXT:    ret
   %1 = sext i16 %a to i64
   ret i64 %1
 }
@@ -213,6 +281,11 @@ define i64 @sexti32_i64(i64 %a) {
 ; RV32XQCIBM:       # %bb.0:
 ; RV32XQCIBM-NEXT:    srai a1, a0, 31
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: sexti32_i64:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    srai a1, a0, 31
+; RV32XQCIBMZBB-NEXT:    ret
   %shl = shl i64 %a, 32
   %shr = ashr exact i64 %shl, 32
   ret i64 %shr
@@ -228,6 +301,11 @@ define i64 @sexti32_i64_2(i32 %a) {
 ; RV32XQCIBM:       # %bb.0:
 ; RV32XQCIBM-NEXT:    srai a1, a0, 31
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: sexti32_i64_2:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    srai a1, a0, 31
+; RV32XQCIBMZBB-NEXT:    ret
   %1 = sext i32 %a to i64
   ret i64 %1
 }
@@ -243,6 +321,11 @@ define i32 @extu_from_and_i32(i32 %x) {
 ; RV32XQCIBM:       # %bb.0:
 ; RV32XQCIBM-NEXT:    qc.extu a0, a0, 12, 0
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: extu_from_and_i32:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    qc.extu a0, a0, 12, 0
+; RV32XQCIBMZBB-NEXT:    ret
   %a = and i32 %x, 4095
   ret i32 %a
 }
@@ -257,6 +340,11 @@ define i32 @no_extu_from_and_i32(i32 %x) {
 ; RV32XQCIBM:       # %bb.0:
 ; RV32XQCIBM-NEXT:    andi a0, a0, 31
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: no_extu_from_and_i32:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    andi a0, a0, 31
+; RV32XQCIBMZBB-NEXT:    ret
   %a = and i32 %x, 31
   ret i32 %a
 }
@@ -271,6 +359,11 @@ define i32 @extu_from_and_i32_simm12_lb(i32 %x) {
 ; RV32XQCIBM:       # %bb.0:
 ; RV32XQCIBM-NEXT:    qc.extu a0, a0, 6, 0
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: extu_from_and_i32_simm12_lb:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    qc.extu a0, a0, 6, 0
+; RV32XQCIBMZBB-NEXT:    ret
   %a = and i32 %x, 63
   ret i32 %a
 }
@@ -285,6 +378,11 @@ define i32 @extu_from_and_i32_simm12_ub(i32 %x) {
 ; RV32XQCIBM:       # %bb.0:
 ; RV32XQCIBM-NEXT:    qc.extu a0, a0, 11, 0
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: extu_from_and_i32_simm12_ub:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    qc.extu a0, a0, 11, 0
+; RV32XQCIBMZBB-NEXT:    ret
   %a = and i32 %x, 2047
   ret i32 %a
 }
@@ -302,6 +400,12 @@ define i64 @extu_from_and_i64(i64 %x) {
 ; RV32XQCIBM-NEXT:    qc.extu a0, a0, 12, 0
 ; RV32XQCIBM-NEXT:    li a1, 0
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: extu_from_and_i64:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    qc.extu a0, a0, 12, 0
+; RV32XQCIBMZBB-NEXT:    li a1, 0
+; RV32XQCIBMZBB-NEXT:    ret
   %a = and i64 %x, 4095
   ret i64 %a
 }
@@ -317,6 +421,11 @@ define i32 @extu_from_and_lshr_i32(i32 %x) {
 ; RV32XQCIBM:       # %bb.0:
 ; RV32XQCIBM-NEXT:    qc.extu a0, a0, 3, 23
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: extu_from_and_lshr_i32:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    qc.extu a0, a0, 3, 23
+; RV32XQCIBMZBB-NEXT:    ret
   %shifted = lshr i32 %x, 23
   %masked = and i32 %shifted, 7
   ret i32 %masked
@@ -335,6 +444,12 @@ define i64 @extu_from_and_lshr_i64(i64 %x) {
 ; RV32XQCIBM-NEXT:    qc.extu a0, a1, 12, 14
 ; RV32XQCIBM-NEXT:    li a1, 0
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: extu_from_and_lshr_i64:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    qc.extu a0, a1, 12, 14
+; RV32XQCIBMZBB-NEXT:    li a1, 0
+; RV32XQCIBMZBB-NEXT:    ret
   %shifted = lshr i64 %x, 46
   %masked = and i64 %shifted, 4095
   ret i64 %masked
@@ -351,6 +466,11 @@ define i32 @extu_from_lshr_and_i32(i32 %x) {
 ; RV32XQCIBM:       # %bb.0:
 ; RV32XQCIBM-NEXT:    qc.extu a0, a0, 12, 12
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: extu_from_lshr_and_i32:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    qc.extu a0, a0, 12, 12
+; RV32XQCIBMZBB-NEXT:    ret
   %masked = and i32 %x, 16773120
   %shifted = lshr i32 %masked, 12
   ret i32 %shifted
@@ -369,6 +489,12 @@ define i64 @extu_from_lshr_and_i64(i64 %x) {
 ; RV32XQCIBM-NEXT:    qc.extu a0, a0, 12, 12
 ; RV32XQCIBM-NEXT:    li a1, 0
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: extu_from_lshr_and_i64:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    qc.extu a0, a0, 12, 12
+; RV32XQCIBMZBB-NEXT:    li a1, 0
+; RV32XQCIBMZBB-NEXT:    ret
   %masked = and i64 %x, 16773120
   %shifted = lshr i64 %masked, 12
   ret i64 %shifted
@@ -385,6 +511,11 @@ define i32 @ext_from_ashr_shl_i32(i32 %x) {
 ; RV32XQCIBM:       # %bb.0:
 ; RV32XQCIBM-NEXT:    qc.ext a0, a0, 8, 16
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: ext_from_ashr_shl_i32:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    qc.ext a0, a0, 8, 16
+; RV32XQCIBMZBB-NEXT:    ret
   %shl = shl i32 %x, 8
   %ashr = ashr i32 %shl, 24
   ret i32 %ashr
@@ -401,6 +532,11 @@ define i32 @ext_from_ashr_sexti8_i32(i8 %x) {
 ; RV32XQCIBM:       # %bb.0:
 ; RV32XQCIBM-NEXT:    qc.ext a0, a0, 3, 5
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: ext_from_ashr_sexti8_i32:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    qc.ext a0, a0, 3, 5
+; RV32XQCIBMZBB-NEXT:    ret
   %sext = sext i8 %x to i32
   %ashr = ashr i32 %sext, 5
   ret i32 %ashr
@@ -417,6 +553,11 @@ define i32 @ext_from_ashr_sexti16_i32(i16 %x) {
 ; RV32XQCIBM:       # %bb.0:
 ; RV32XQCIBM-NEXT:    qc.ext a0, a0, 1, 15
 ; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: ext_from_ashr_sexti16_i32:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    qc.ext a0, a0, 1, 15
+; RV32XQCIBMZBB-NEXT:    ret
   %sext = sext i16 %x to i32
   %ashr = ashr i32 %sext, 24
   ret i32 %ashr

@svs-quic svs-quic merged commit 26d4b3c into llvm:main Jun 19, 2025
9 checks passed
@svs-quic svs-quic deleted the ext_sext branch June 19, 2025 08:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants