From d1d3a3231e2b03f9446a2ce4a8f9d02045be20b6 Mon Sep 17 00:00:00 2001 From: Jim Lin Date: Sun, 25 May 2025 14:44:44 +0800 Subject: [PATCH 1/3] [RISCV] Pre-commit --- llvm/test/CodeGen/RISCV/rv32xandesperf.ll | 73 +++++++++++++++++++++++ llvm/test/CodeGen/RISCV/rv64xandesperf.ll | 64 ++++++++++++++++++++ 2 files changed, 137 insertions(+) diff --git a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll index efe5b4a306fee..a60251f095cda 100644 --- a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll +++ b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll @@ -2,6 +2,79 @@ ; RUN: llc -O0 -mtriple=riscv32 -mattr=+xandesperf -verify-machineinstrs < %s \ ; RUN: | FileCheck %s +define i32 @bfoz_from_and_i32(i32 %x) { +; CHECK-LABEL: bfoz_from_and_i32: +; 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 @bfoz_from_and_i64(i64 %x) { +; CHECK-LABEL: bfoz_from_and_i64: +; 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 @bfoz_from_and_lshr_i32(i32 %x) { +; CHECK-LABEL: bfoz_from_and_lshr_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: slli a0, a0, 6 +; CHECK-NEXT: srli a0, a0, 29 +; CHECK-NEXT: ret + %shifted = lshr i32 %x, 23 + %masked = and i32 %shifted, 7 + ret i32 %masked +} + +define i64 @bfoz_from_and_lshr_i64(i64 %x) { +; CHECK-LABEL: bfoz_from_and_lshr_i64: +; CHECK: # %bb.0: +; CHECK-NEXT: # kill: def $x12 killed $x11 +; CHECK-NEXT: slli a0, a1, 6 +; CHECK-NEXT: srli a0, a0, 20 +; CHECK-NEXT: li a1, 0 +; CHECK-NEXT: ret + %shifted = lshr i64 %x, 46 + %masked = and i64 %shifted, 4095 + ret i64 %masked +} + +define i32 @bfoz_from_lshr_and_i32(i32 %x) { +; CHECK-LABEL: bfoz_from_lshr_and_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: slli a0, a0, 8 +; CHECK-NEXT: srli a0, a0, 20 +; CHECK-NEXT: ret + %masked = and i32 %x, 16773120 + %shifted = lshr i32 %masked, 12 + ret i32 %shifted +} + +define i64 @bfoz_from_lshr_and_i64(i64 %x) { +; CHECK-LABEL: bfoz_from_lshr_and_i64: +; CHECK: # %bb.0: +; CHECK-NEXT: # kill: def $x12 killed $x11 +; CHECK-NEXT: # kill: def $x12 killed $x10 +; CHECK-NEXT: andi a1, a1, 15 +; CHECK-NEXT: srli a0, a0, 24 +; CHECK-NEXT: slli a1, a1, 8 +; CHECK-NEXT: or a0, a0, a1 +; CHECK-NEXT: li a1, 0 +; CHECK-NEXT: ret + %masked = and i64 %x, 68702699520 + %shifted = lshr i64 %masked, 24 + ret i64 %shifted +} + 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..360a7ba43cd67 100644 --- a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll +++ b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll @@ -2,6 +2,70 @@ ; RUN: llc -mtriple=riscv64 -mattr=+xandesperf -verify-machineinstrs < %s \ ; RUN: | FileCheck %s +define i32 @bfoz_from_and_i32(i32 %x) { +; CHECK-LABEL: bfoz_from_and_i32: +; 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 @bfoz_from_and_i64(i64 %x) { +; CHECK-LABEL: bfoz_from_and_i64: +; 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 i32 @bfoz_from_and_lshr_i32(i32 %x) { +; CHECK-LABEL: bfoz_from_and_lshr_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: slli a0, a0, 38 +; CHECK-NEXT: srli a0, a0, 61 +; CHECK-NEXT: ret + %shifted = lshr i32 %x, 23 + %masked = and i32 %shifted, 7 + ret i32 %masked +} + +define i64 @bfoz_from_and_lshr_i64(i64 %x) { +; CHECK-LABEL: bfoz_from_and_lshr_i64: +; CHECK: # %bb.0: +; CHECK-NEXT: slli a0, a0, 6 +; CHECK-NEXT: srli a0, a0, 52 +; CHECK-NEXT: ret + %shifted = lshr i64 %x, 46 + %masked = and i64 %shifted, 4095 + ret i64 %masked +} + +define i32 @bfoz_from_lshr_and_i32(i32 %x) { +; CHECK-LABEL: bfoz_from_lshr_and_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: slli a0, a0, 40 +; CHECK-NEXT: srli a0, a0, 52 +; CHECK-NEXT: ret + %masked = and i32 %x, 16773120 + %shifted = lshr i32 %masked, 12 + ret i32 %shifted +} + +define i64 @bfoz_from_lshr_and_i64(i64 %x) { +; CHECK-LABEL: bfoz_from_lshr_and_i64: +; CHECK: # %bb.0: +; CHECK-NEXT: slli a0, a0, 28 +; CHECK-NEXT: srli a0, a0, 52 +; CHECK-NEXT: ret + %masked = and i64 %x, 68702699520 + %shifted = lshr i64 %masked, 24 + ret i64 %shifted +} + define signext i32 @sexti1_i32(i32 signext %a) { ; CHECK-LABEL: sexti1_i32: ; CHECK: # %bb.0: From 06cf15dd27968fffee18917a3e882cb1c634d383 Mon Sep 17 00:00:00 2001 From: Jim Lin Date: Sun, 25 May 2025 14:47:59 +0800 Subject: [PATCH 2/3] [RISCV] Select unsigned bitfiled extracts for XAndesPerf The XAndesPerf extension includes unsigned bitfield extraction instruction `NDS.BFOZ`, which can extract the bits from LSB to MSB, places them starting at bit 0, and zero-extends the result. --- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 15 +++++++++------ llvm/test/CodeGen/RISCV/rv32xandesperf.ll | 15 +++++---------- llvm/test/CodeGen/RISCV/rv64xandesperf.ll | 18 ++++++------------ 3 files changed, 20 insertions(+), 28 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 18af1545d5a34..306da41a9c8e4 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -672,14 +672,17 @@ bool RISCVDAGToDAGISel::trySignedBitfieldExtract(SDNode *Node) { bool RISCVDAGToDAGISel::tryUnsignedBitfieldExtract(SDNode *Node, SDLoc DL, MVT VT, SDValue X, unsigned Msb, unsigned Lsb) { - // Only supported with XTHeadBb at the moment. - if (!Subtarget->hasVendorXTHeadBb()) + // Only supported with XTHeadBb/XAndesPerf at the moment. + if (!Subtarget->hasVendorXTHeadBb() && !Subtarget->hasVendorXAndesPerf()) return false; - SDNode *TH_EXTU = CurDAG->getMachineNode( - RISCV::TH_EXTU, DL, VT, X, CurDAG->getTargetConstant(Msb, DL, VT), - CurDAG->getTargetConstant(Lsb, DL, VT)); - ReplaceNode(Node, TH_EXTU); + unsigned Opc = + Subtarget->hasVendorXTHeadBb() ? RISCV::TH_EXTU : RISCV::NDS_BFOZ; + + SDNode *Ube = CurDAG->getMachineNode(Opc, DL, VT, X, + CurDAG->getTargetConstant(Msb, DL, VT), + CurDAG->getTargetConstant(Lsb, DL, VT)); + ReplaceNode(Node, Ube); return true; } diff --git a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll index a60251f095cda..72dddddf9f382 100644 --- a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll +++ b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll @@ -5,8 +5,7 @@ define i32 @bfoz_from_and_i32(i32 %x) { ; CHECK-LABEL: bfoz_from_and_i32: ; 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 @bfoz_from_and_i64(i64 %x) { ; CHECK-LABEL: bfoz_from_and_i64: ; 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 @@ -27,8 +25,7 @@ define i64 @bfoz_from_and_i64(i64 %x) { define i32 @bfoz_from_and_lshr_i32(i32 %x) { ; CHECK-LABEL: bfoz_from_and_lshr_i32: ; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 6 -; CHECK-NEXT: srli a0, a0, 29 +; CHECK-NEXT: nds.bfoz a0, a0, 25, 23 ; CHECK-NEXT: ret %shifted = lshr i32 %x, 23 %masked = and i32 %shifted, 7 @@ -39,8 +36,7 @@ define i64 @bfoz_from_and_lshr_i64(i64 %x) { ; CHECK-LABEL: bfoz_from_and_lshr_i64: ; CHECK: # %bb.0: ; CHECK-NEXT: # kill: def $x12 killed $x11 -; CHECK-NEXT: slli a0, a1, 6 -; CHECK-NEXT: srli a0, a0, 20 +; CHECK-NEXT: nds.bfoz a0, a1, 25, 14 ; CHECK-NEXT: li a1, 0 ; CHECK-NEXT: ret %shifted = lshr i64 %x, 46 @@ -51,8 +47,7 @@ define i64 @bfoz_from_and_lshr_i64(i64 %x) { define i32 @bfoz_from_lshr_and_i32(i32 %x) { ; CHECK-LABEL: bfoz_from_lshr_and_i32: ; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 8 -; CHECK-NEXT: srli a0, a0, 20 +; CHECK-NEXT: nds.bfoz a0, a0, 23, 12 ; CHECK-NEXT: ret %masked = and i32 %x, 16773120 %shifted = lshr i32 %masked, 12 diff --git a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll index 360a7ba43cd67..13c2234071eb1 100644 --- a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll +++ b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll @@ -5,8 +5,7 @@ define i32 @bfoz_from_and_i32(i32 %x) { ; CHECK-LABEL: bfoz_from_and_i32: ; 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 @bfoz_from_and_i32(i32 %x) { define i64 @bfoz_from_and_i64(i64 %x) { ; CHECK-LABEL: bfoz_from_and_i64: ; 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 @@ -25,8 +23,7 @@ define i64 @bfoz_from_and_i64(i64 %x) { define i32 @bfoz_from_and_lshr_i32(i32 %x) { ; CHECK-LABEL: bfoz_from_and_lshr_i32: ; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 38 -; CHECK-NEXT: srli a0, a0, 61 +; CHECK-NEXT: nds.bfoz a0, a0, 25, 23 ; CHECK-NEXT: ret %shifted = lshr i32 %x, 23 %masked = and i32 %shifted, 7 @@ -36,8 +33,7 @@ define i32 @bfoz_from_and_lshr_i32(i32 %x) { define i64 @bfoz_from_and_lshr_i64(i64 %x) { ; CHECK-LABEL: bfoz_from_and_lshr_i64: ; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 6 -; CHECK-NEXT: srli a0, a0, 52 +; CHECK-NEXT: nds.bfoz a0, a0, 57, 46 ; CHECK-NEXT: ret %shifted = lshr i64 %x, 46 %masked = and i64 %shifted, 4095 @@ -47,8 +43,7 @@ define i64 @bfoz_from_and_lshr_i64(i64 %x) { define i32 @bfoz_from_lshr_and_i32(i32 %x) { ; CHECK-LABEL: bfoz_from_lshr_and_i32: ; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 40 -; CHECK-NEXT: srli a0, a0, 52 +; CHECK-NEXT: nds.bfoz a0, a0, 23, 12 ; CHECK-NEXT: ret %masked = and i32 %x, 16773120 %shifted = lshr i32 %masked, 12 @@ -58,8 +53,7 @@ define i32 @bfoz_from_lshr_and_i32(i32 %x) { define i64 @bfoz_from_lshr_and_i64(i64 %x) { ; CHECK-LABEL: bfoz_from_lshr_and_i64: ; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 28 -; CHECK-NEXT: srli a0, a0, 52 +; CHECK-NEXT: nds.bfoz a0, a0, 35, 24 ; CHECK-NEXT: ret %masked = and i64 %x, 68702699520 %shifted = lshr i64 %masked, 24 From 39e549fd858198e35b52b24faf6ce049eace9b26 Mon Sep 17 00:00:00 2001 From: Jim Lin Date: Tue, 27 May 2025 12:50:26 +0800 Subject: [PATCH 3/3] fix testcase --- llvm/test/CodeGen/RISCV/rv64zba.ll | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/llvm/test/CodeGen/RISCV/rv64zba.ll b/llvm/test/CodeGen/RISCV/rv64zba.ll index 6bd808ca9e126..622b302da4c51 100644 --- a/llvm/test/CodeGen/RISCV/rv64zba.ll +++ b/llvm/test/CodeGen/RISCV/rv64zba.ll @@ -126,7 +126,7 @@ define i64 @zextw_i64(i64 %a) nounwind { ; ; RV64XANDESPERF-LABEL: zextw_i64: ; RV64XANDESPERF: # %bb.0: -; RV64XANDESPERF-NEXT: nds.lea.b.ze a0, zero, a0 +; RV64XANDESPERF-NEXT: nds.bfoz a0, a0, 31, 0 ; RV64XANDESPERF-NEXT: ret %and = and i64 %a, 4294967295 ret i64 %and @@ -151,7 +151,7 @@ define i64 @zextw_demandedbits_i64(i64 %0) { ; RV64XANDESPERF-LABEL: zextw_demandedbits_i64: ; RV64XANDESPERF: # %bb.0: ; RV64XANDESPERF-NEXT: ori a0, a0, 1 -; RV64XANDESPERF-NEXT: nds.lea.b.ze a0, zero, a0 +; RV64XANDESPERF-NEXT: nds.bfoz a0, a0, 31, 0 ; RV64XANDESPERF-NEXT: ret %2 = and i64 %0, 4294967294 %3 = or i64 %2, 1 @@ -1577,7 +1577,7 @@ define i64 @adduw_imm(i32 signext %0) nounwind { ; ; RV64XANDESPERF-LABEL: adduw_imm: ; RV64XANDESPERF: # %bb.0: -; RV64XANDESPERF-NEXT: nds.lea.b.ze a0, zero, a0 +; RV64XANDESPERF-NEXT: nds.bfoz a0, a0, 31, 0 ; RV64XANDESPERF-NEXT: addi a0, a0, 5 ; RV64XANDESPERF-NEXT: ret %a = zext i32 %0 to i64 @@ -2324,8 +2324,7 @@ define zeroext i32 @sext_ashr_zext_i8(i8 %a) nounwind { ; RV64XANDESPERF-LABEL: sext_ashr_zext_i8: ; RV64XANDESPERF: # %bb.0: ; RV64XANDESPERF-NEXT: nds.bfos a0, a0, 7, 0 -; RV64XANDESPERF-NEXT: slli a0, a0, 23 -; RV64XANDESPERF-NEXT: srli a0, a0, 32 +; RV64XANDESPERF-NEXT: nds.bfoz a0, a0, 40, 9 ; RV64XANDESPERF-NEXT: ret %ext = sext i8 %a to i32 %1 = ashr i32 %ext, 9 @@ -2473,8 +2472,7 @@ define zeroext i32 @sext_ashr_zext_i16(i16 %a) nounwind { ; RV64XANDESPERF-LABEL: sext_ashr_zext_i16: ; RV64XANDESPERF: # %bb.0: ; RV64XANDESPERF-NEXT: nds.bfos a0, a0, 15, 0 -; RV64XANDESPERF-NEXT: slli a0, a0, 23 -; RV64XANDESPERF-NEXT: srli a0, a0, 32 +; RV64XANDESPERF-NEXT: nds.bfoz a0, a0, 40, 9 ; RV64XANDESPERF-NEXT: ret %ext = sext i16 %a to i32 %1 = ashr i32 %ext, 9