[llvm] RISCV] Select NDS_BFOZ for and with trailing ones mask (PR #141398)

Jim Lin via llvm-commits llvm-commits at lists.llvm.org
Sun May 25 00:29:48 PDT 2025


https://github.com/tclin914 created https://github.com/llvm/llvm-project/pull/141398

Select NDS_BFOS for and operation with trailing ones mask. The msb 
operand is calculated as the number of trailing ones minus one.

>From 5fb9e9bd421942fdcf014f1eec8f8bb024756613 Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Sun, 25 May 2025 14:44:44 +0800
Subject: [PATCH 1/2] [RISCV] Pre-commit

---
 llvm/test/CodeGen/RISCV/rv32xandesperf.ll | 22 ++++++++++++++++++++++
 llvm/test/CodeGen/RISCV/rv64xandesperf.ll | 20 ++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
index efe5b4a306fee..63fb95fe0f5af 100644
--- a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
+++ b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
@@ -2,6 +2,28 @@
 ; RUN: llc -O0 -mtriple=riscv32 -mattr=+xandesperf -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s
 
+define i32 @and32_0xfff(i32 %x) {
+; CHECK-LABEL: and32_0xfff:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    slli a0, a0, 20
+; CHECK-NEXT:    srli a0, a0, 20
+; CHECK-NEXT:    ret
+  %a = and i32 %x, 4095
+  ret i32 %a
+}
+
+define i64 @and64_0xfff(i64 %x) {
+; CHECK-LABEL: and64_0xfff:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    # kill: def $x11 killed $x10
+; CHECK-NEXT:    slli a0, a0, 20
+; CHECK-NEXT:    srli a0, a0, 20
+; CHECK-NEXT:    li a1, 0
+; CHECK-NEXT:    ret
+  %a = and i64 %x, 4095
+  ret i64 %a
+}
+
 define i32 @sexti1_i32(i32 %a) {
 ; CHECK-LABEL: sexti1_i32:
 ; CHECK:       # %bb.0:
diff --git a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
index 9cc95ce886133..cf9662a768107 100644
--- a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
+++ b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
@@ -2,6 +2,26 @@
 ; RUN: llc -mtriple=riscv64 -mattr=+xandesperf -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s
 
+define i32 @and32_0xfff(i32 %x) {
+; CHECK-LABEL: and32_0xfff:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    slli a0, a0, 52
+; CHECK-NEXT:    srli a0, a0, 52
+; CHECK-NEXT:    ret
+  %a = and i32 %x, 4095
+  ret i32 %a
+}
+
+define i64 @and64_0xfff(i64 %x) {
+; CHECK-LABEL: and64_0xfff:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    slli a0, a0, 52
+; CHECK-NEXT:    srli a0, a0, 52
+; CHECK-NEXT:    ret
+  %a = and i64 %x, 4095
+  ret i64 %a
+}
+
 define signext i32 @sexti1_i32(i32 signext %a) {
 ; CHECK-LABEL: sexti1_i32:
 ; CHECK:       # %bb.0:

>From e3fc88c476104027ae1cc068010c6b5ab5c4644c Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Sun, 25 May 2025 14:47:59 +0800
Subject: [PATCH 2/2] [RISCV] Select NDS_BFOZ for and with trailing ones mask

Select NDS_BFOS for and operation with trailing ones mask. The msb
operand is calculated as the number of trailing ones minus one.
---
 llvm/lib/Target/RISCV/RISCVInstrInfo.td       | 5 +++++
 llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td | 3 +++
 llvm/test/CodeGen/RISCV/rv32xandesperf.ll     | 6 ++----
 llvm/test/CodeGen/RISCV/rv64xandesperf.ll     | 6 ++----
 4 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 9058934557b54..8dc04d6dcd852 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -564,6 +564,11 @@ def XLenSubTrailingOnes : SDNodeXForm<imm, [{
 def GIXLenSubTrailingOnes : GICustomOperandRenderer<"renderXLenSubTrailingOnes">,
   GISDNodeXFormEquiv<XLenSubTrailingOnes>;
 
+def TrailingOnesSubOne : SDNodeXForm<imm, [{
+  return CurDAG->getTargetConstant(llvm::countr_one(N->getZExtValue()) - 1,
+                                   SDLoc(N), N->getValueType(0));
+}]>;
+
 // Checks if this mask is a non-empty sequence of ones starting at the
 // most/least significant bit with the remainder zero and exceeds simm32/simm12.
 def LeadingOnesMask : ImmLeaf<XLenVT, [{
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
index ec883cd1d3157..686cc0bc47be8 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
@@ -466,6 +466,9 @@ def NDS_VD4DOTSU_VV : NDSRVInstVD4DOT<0b000101, "nds.vd4dotsu">;
 
 let Predicates = [HasVendorXAndesPerf] in {
 
+def : Pat<(XLenVT (and GPR:$rs, TrailingOnesMask:$mask)),
+          (NDS_BFOZ $rs, (TrailingOnesSubOne imm:$mask), 0)>;
+
 def : Pat<(sext_inreg (XLenVT GPR:$rs1), i16), (NDS_BFOS GPR:$rs1, 15, 0)>;
 def : Pat<(sext_inreg (XLenVT GPR:$rs1), i8), (NDS_BFOS GPR:$rs1, 7, 0)>;
 def : Pat<(sext_inreg (XLenVT GPR:$rs1), i1), (NDS_BFOS GPR:$rs1, 0, 0)>;
diff --git a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
index 63fb95fe0f5af..d15725a3b3b3b 100644
--- a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
+++ b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
@@ -5,8 +5,7 @@
 define i32 @and32_0xfff(i32 %x) {
 ; CHECK-LABEL: and32_0xfff:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    slli a0, a0, 20
-; CHECK-NEXT:    srli a0, a0, 20
+; CHECK-NEXT:    nds.bfoz a0, a0, 11, 0
 ; CHECK-NEXT:    ret
   %a = and i32 %x, 4095
   ret i32 %a
@@ -16,8 +15,7 @@ define i64 @and64_0xfff(i64 %x) {
 ; CHECK-LABEL: and64_0xfff:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    # kill: def $x11 killed $x10
-; CHECK-NEXT:    slli a0, a0, 20
-; CHECK-NEXT:    srli a0, a0, 20
+; CHECK-NEXT:    nds.bfoz a0, a0, 11, 0
 ; CHECK-NEXT:    li a1, 0
 ; CHECK-NEXT:    ret
   %a = and i64 %x, 4095
diff --git a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
index cf9662a768107..1b6d2a8287de7 100644
--- a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
+++ b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
@@ -5,8 +5,7 @@
 define i32 @and32_0xfff(i32 %x) {
 ; CHECK-LABEL: and32_0xfff:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    slli a0, a0, 52
-; CHECK-NEXT:    srli a0, a0, 52
+; CHECK-NEXT:    nds.bfoz a0, a0, 11, 0
 ; CHECK-NEXT:    ret
   %a = and i32 %x, 4095
   ret i32 %a
@@ -15,8 +14,7 @@ define i32 @and32_0xfff(i32 %x) {
 define i64 @and64_0xfff(i64 %x) {
 ; CHECK-LABEL: and64_0xfff:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    slli a0, a0, 52
-; CHECK-NEXT:    srli a0, a0, 52
+; CHECK-NEXT:    nds.bfoz a0, a0, 11, 0
 ; CHECK-NEXT:    ret
   %a = and i64 %x, 4095
   ret i64 %a



More information about the llvm-commits mailing list