From 4d5c0f4bc6a8c0d86f7d2aa8a9f7e1df98112b52 Mon Sep 17 00:00:00 2001 From: Jim Lin Date: Tue, 3 Jun 2025 14:58:36 +0800 Subject: [PATCH 1/4] [RISCV] Pre-commit --- llvm/test/CodeGen/RISCV/rv32xandesperf.ll | 56 ++++++++++++ llvm/test/CodeGen/RISCV/rv64xandesperf.ll | 100 ++++++++++++++++++++++ 2 files changed, 156 insertions(+) diff --git a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll index 71473ab5dfb58..c1e31c74f06a7 100644 --- a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll +++ b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll @@ -2,6 +2,10 @@ ; RUN: llc -O0 -mtriple=riscv32 -mattr=+xandesperf -verify-machineinstrs < %s \ ; RUN: | FileCheck %s +; NDS.BFOZ + +; MSB >= LSB + define i32 @bfoz_from_and_i32(i32 %x) { ; CHECK-LABEL: bfoz_from_and_i32: ; CHECK: # %bb.0: @@ -70,6 +74,58 @@ define i64 @bfoz_from_lshr_and_i64(i64 %x) { ret i64 %shifted } +; MSB = 0 + +define i32 @bfoz_from_and_shl_with_msb_zero_i32(i32 %x) { +; CHECK-LABEL: bfoz_from_and_shl_with_msb_zero_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: slli a0, a0, 31 +; CHECK-NEXT: srli a0, a0, 16 +; CHECK-NEXT: ret + %shifted = shl i32 %x, 15 + %masked = and i32 %shifted, 32768 + ret i32 %masked +} + +define i32 @bfoz_from_lshr_shl_with_msb_zero_i32(i32 %x) { +; CHECK-LABEL: bfoz_from_lshr_shl_with_msb_zero_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: slli a0, a0, 31 +; CHECK-NEXT: srli a0, a0, 13 +; CHECK-NEXT: ret + %shl = shl i32 %x, 31 + %lshr = lshr i32 %shl, 13 + ret i32 %lshr +} + +; MSB < LSB + +define i32 @bfoz_from_and_shl_i32(i32 %x) { +; CHECK-LABEL: bfoz_from_and_shl_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: slli a0, a0, 20 +; CHECK-NEXT: srli a0, a0, 8 +; CHECK-NEXT: ret + %shifted = shl i32 %x, 12 + %masked = and i32 %shifted, 16773120 + ret i32 %masked +} + +define i32 @bfoz_from_lshr_shl_i32(i32 %x) { +; CHECK-LABEL: bfoz_from_lshr_shl_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: slli a0, a0, 26 +; CHECK-NEXT: srli a0, a0, 7 +; CHECK-NEXT: ret + %shl = shl i32 %x, 26 + %lshr = lshr i32 %shl, 7 + ret i32 %lshr +} + +; NDS.BFOS + +; MSB >= LSB + define i32 @bfos_from_ashr_shl_i32(i32 %x) { ; CHECK-LABEL: bfos_from_ashr_shl_i32: ; CHECK: # %bb.0: diff --git a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll index 260d30be686dc..600b2edcfbbeb 100644 --- a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll +++ b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll @@ -2,6 +2,10 @@ ; RUN: llc -mtriple=riscv64 -mattr=+xandesperf -verify-machineinstrs < %s \ ; RUN: | FileCheck %s +; NDS.BFOZ + +; MSB >= LSB + define i32 @bfoz_from_and_i32(i32 %x) { ; CHECK-LABEL: bfoz_from_and_i32: ; CHECK: # %bb.0: @@ -60,6 +64,102 @@ define i64 @bfoz_from_lshr_and_i64(i64 %x) { ret i64 %shifted } +; MSB = 0 + +define i32 @bfoz_from_and_shl_with_msb_zero_i32(i32 %x) { +; CHECK-LABEL: bfoz_from_and_shl_with_msb_zero_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: slli a0, a0, 63 +; CHECK-NEXT: srli a0, a0, 48 +; CHECK-NEXT: ret + %shifted = shl i32 %x, 15 + %masked = and i32 %shifted, 32768 + ret i32 %masked +} + +define i64 @bfoz_from_and_shl_with_msb_zero_i64(i64 %x) { +; CHECK-LABEL: bfoz_from_and_shl_with_msb_zero_i64: +; CHECK: # %bb.0: +; CHECK-NEXT: slli a0, a0, 63 +; CHECK-NEXT: srli a0, a0, 15 +; CHECK-NEXT: ret + %shifted = shl i64 %x, 48 + %masked = and i64 %shifted, 281474976710656 + ret i64 %masked +} + +define i32 @bfoz_from_lshr_shl_with_msb_zero_i32(i32 %x) { +; CHECK-LABEL: bfoz_from_lshr_shl_with_msb_zero_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: slli a0, a0, 63 +; CHECK-NEXT: srli a0, a0, 45 +; CHECK-NEXT: ret + %shl = shl i32 %x, 31 + %lshr = lshr i32 %shl, 13 + ret i32 %lshr +} + +define i64 @bfoz_from_lshr_shl_with_msb_zero_i64(i64 %x) { +; CHECK-LABEL: bfoz_from_lshr_shl_with_msb_zero_i64: +; CHECK: # %bb.0: +; CHECK-NEXT: slli a0, a0, 63 +; CHECK-NEXT: srli a0, a0, 19 +; CHECK-NEXT: ret + %shl = shl i64 %x, 63 + %lshr = lshr i64 %shl, 19 + ret i64 %lshr +} + +; MSB < LSB + +define i32 @bfoz_from_and_shl_i32(i32 %x) { +; CHECK-LABEL: bfoz_from_and_shl_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: slli a0, a0, 52 +; CHECK-NEXT: srli a0, a0, 40 +; CHECK-NEXT: ret + %shifted = shl i32 %x, 12 + %masked = and i32 %shifted, 16773120 + ret i32 %masked +} + +define i64 @bfoz_from_and_shl_i64(i64 %x) { +; CHECK-LABEL: bfoz_from_and_shl_i64: +; CHECK: # %bb.0: +; CHECK-NEXT: slli a0, a0, 52 +; CHECK-NEXT: srli a0, a0, 28 +; CHECK-NEXT: ret + %shifted = shl i64 %x, 24 + %masked = and i64 %shifted, 68702699520 + ret i64 %masked +} + +define i32 @bfoz_from_lshr_shl_i32(i32 %x) { +; CHECK-LABEL: bfoz_from_lshr_shl_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: slli a0, a0, 58 +; CHECK-NEXT: srli a0, a0, 39 +; CHECK-NEXT: ret + %shl = shl i32 %x, 26 + %lshr = lshr i32 %shl, 7 + ret i32 %lshr +} + +define i64 @bfoz_from_lshr_shl_i64(i64 %x) { +; CHECK-LABEL: bfoz_from_lshr_shl_i64: +; CHECK: # %bb.0: +; CHECK-NEXT: slli a0, a0, 40 +; CHECK-NEXT: srli a0, a0, 15 +; CHECK-NEXT: ret + %shl = shl i64 %x, 40 + %lshr = lshr i64 %shl, 15 + ret i64 %lshr +} + +; NDS.BFOS + +; MSB >= LSB + define i32 @bfos_from_ashr_shl_i32(i32 %x) { ; CHECK-LABEL: bfos_from_ashr_shl_i32: ; CHECK: # %bb.0: From 27d670fc5abb4457314368b0e82acff7832a68d4 Mon Sep 17 00:00:00 2001 From: Jim Lin Date: Tue, 3 Jun 2025 17:13:52 +0800 Subject: [PATCH 2/4] [RISCV] Select unsigned bitfield insert for XAndesPerf The XAndesPerf extension includes unsigned bitfield extraction instruction `NDS.BFOZ`, which can extract the bits from 0 to Len -1, place them starting at bit Msb, and zero-fills the remaining bits. This patch handles the cases where Msb < Lsb. Instruction Sytax: nds.bfoz Rd, Rs1, Msb, Lsb The operation is: if Msb < Lsb: Lenm1 = Lsb - Msb; Rd[Lsb:Msb] = Rs1[Lenm1:0]; if (Lsb < (XLen -1)) Rd[XLen-1:Lsb+1]=0; Rd[Msb-1:0]=0; When Len == 1, it is a special case where the Msb is set to 0 instead of being equal to the Lsb. --- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 34 +++++++++++++++++++++ llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h | 2 ++ llvm/test/CodeGen/RISCV/rv32xandesperf.ll | 12 +++----- llvm/test/CodeGen/RISCV/rv64xandesperf.ll | 24 +++++---------- llvm/test/CodeGen/RISCV/rv64zba.ll | 3 +- 5 files changed, 49 insertions(+), 26 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 4f6aa41d1e03b..4c4b475ed3898 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -688,6 +688,23 @@ bool RISCVDAGToDAGISel::tryUnsignedBitfieldExtract(SDNode *Node, SDLoc DL, return true; } +bool RISCVDAGToDAGISel::tryUnsignedBitfieldInsertInZero(SDNode *Node, SDLoc DL, + MVT VT, SDValue X, + unsigned Msb, + unsigned Lsb) { + // Only supported with XAndesPerf at the moment. + if (!Subtarget->hasVendorXAndesPerf()) + return false; + + unsigned Opc = RISCV::NDS_BFOZ; + + SDNode *Ubi = CurDAG->getMachineNode(Opc, DL, VT, X, + CurDAG->getTargetConstant(Msb, DL, VT), + CurDAG->getTargetConstant(Lsb, DL, VT)); + ReplaceNode(Node, Ubi); + return true; +} + bool RISCVDAGToDAGISel::tryIndexedLoad(SDNode *Node) { // Target does not support indexed loads. if (!Subtarget->hasVendorXTHeadMemIdx()) @@ -1324,6 +1341,23 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) { return; } + // Try to use an unsigned bitfield insert (e.g., nds.bfoz) if + // available. + // Transform (and (shl x, c2), c1) + // -> ( x, msb, lsb) + // e.g. + // (and (shl x, 12), 0x00fff000) + // If XLen = 32 and C2 = 12, then + // Len = 32 - 8 - 12 = 12, + // Lsb = 32 - 8 - 1 = 23 and Msb = 12 + // -> nds.bfoz x, 12, 23 + const unsigned Len = XLen - Leading - C2; + const unsigned Lsb = XLen - Leading - 1; + // If Len is 1, the Msb will be 0 instead of C2. + unsigned Msb = Len == 1 ? 0 : C2; + if (tryUnsignedBitfieldInsertInZero(Node, DL, VT, X, Msb, Lsb)) + return; + // (srli (slli c2+c3), c3) if (OneUseOrZExtW && !IsCANDI) { SDNode *SLLI = CurDAG->getMachineNode( diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h index 11d62e5edad3f..f199c2031b9a9 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h @@ -79,6 +79,8 @@ class RISCVDAGToDAGISel : public SelectionDAGISel { bool trySignedBitfieldExtract(SDNode *Node); bool tryUnsignedBitfieldExtract(SDNode *Node, SDLoc DL, MVT VT, SDValue X, unsigned Msb, unsigned Lsb); + bool tryUnsignedBitfieldInsertInZero(SDNode *Node, SDLoc DL, MVT VT, + SDValue X, unsigned Msb, unsigned Lsb); bool tryIndexedLoad(SDNode *Node); bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt); diff --git a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll index c1e31c74f06a7..3996420d477b2 100644 --- a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll +++ b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll @@ -79,8 +79,7 @@ define i64 @bfoz_from_lshr_and_i64(i64 %x) { define i32 @bfoz_from_and_shl_with_msb_zero_i32(i32 %x) { ; CHECK-LABEL: bfoz_from_and_shl_with_msb_zero_i32: ; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 31 -; CHECK-NEXT: srli a0, a0, 16 +; CHECK-NEXT: nds.bfoz a0, a0, 0, 15 ; CHECK-NEXT: ret %shifted = shl i32 %x, 15 %masked = and i32 %shifted, 32768 @@ -90,8 +89,7 @@ define i32 @bfoz_from_and_shl_with_msb_zero_i32(i32 %x) { define i32 @bfoz_from_lshr_shl_with_msb_zero_i32(i32 %x) { ; CHECK-LABEL: bfoz_from_lshr_shl_with_msb_zero_i32: ; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 31 -; CHECK-NEXT: srli a0, a0, 13 +; CHECK-NEXT: nds.bfoz a0, a0, 0, 18 ; CHECK-NEXT: ret %shl = shl i32 %x, 31 %lshr = lshr i32 %shl, 13 @@ -103,8 +101,7 @@ define i32 @bfoz_from_lshr_shl_with_msb_zero_i32(i32 %x) { define i32 @bfoz_from_and_shl_i32(i32 %x) { ; CHECK-LABEL: bfoz_from_and_shl_i32: ; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 20 -; CHECK-NEXT: srli a0, a0, 8 +; CHECK-NEXT: nds.bfoz a0, a0, 12, 23 ; CHECK-NEXT: ret %shifted = shl i32 %x, 12 %masked = and i32 %shifted, 16773120 @@ -114,8 +111,7 @@ define i32 @bfoz_from_and_shl_i32(i32 %x) { define i32 @bfoz_from_lshr_shl_i32(i32 %x) { ; CHECK-LABEL: bfoz_from_lshr_shl_i32: ; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 26 -; CHECK-NEXT: srli a0, a0, 7 +; CHECK-NEXT: nds.bfoz a0, a0, 19, 24 ; CHECK-NEXT: ret %shl = shl i32 %x, 26 %lshr = lshr i32 %shl, 7 diff --git a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll index 600b2edcfbbeb..af7c300a92d1f 100644 --- a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll +++ b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll @@ -69,8 +69,7 @@ define i64 @bfoz_from_lshr_and_i64(i64 %x) { define i32 @bfoz_from_and_shl_with_msb_zero_i32(i32 %x) { ; CHECK-LABEL: bfoz_from_and_shl_with_msb_zero_i32: ; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 63 -; CHECK-NEXT: srli a0, a0, 48 +; CHECK-NEXT: nds.bfoz a0, a0, 0, 15 ; CHECK-NEXT: ret %shifted = shl i32 %x, 15 %masked = and i32 %shifted, 32768 @@ -80,8 +79,7 @@ define i32 @bfoz_from_and_shl_with_msb_zero_i32(i32 %x) { define i64 @bfoz_from_and_shl_with_msb_zero_i64(i64 %x) { ; CHECK-LABEL: bfoz_from_and_shl_with_msb_zero_i64: ; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 63 -; CHECK-NEXT: srli a0, a0, 15 +; CHECK-NEXT: nds.bfoz a0, a0, 0, 48 ; CHECK-NEXT: ret %shifted = shl i64 %x, 48 %masked = and i64 %shifted, 281474976710656 @@ -91,8 +89,7 @@ define i64 @bfoz_from_and_shl_with_msb_zero_i64(i64 %x) { define i32 @bfoz_from_lshr_shl_with_msb_zero_i32(i32 %x) { ; CHECK-LABEL: bfoz_from_lshr_shl_with_msb_zero_i32: ; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 63 -; CHECK-NEXT: srli a0, a0, 45 +; CHECK-NEXT: nds.bfoz a0, a0, 0, 18 ; CHECK-NEXT: ret %shl = shl i32 %x, 31 %lshr = lshr i32 %shl, 13 @@ -102,8 +99,7 @@ define i32 @bfoz_from_lshr_shl_with_msb_zero_i32(i32 %x) { define i64 @bfoz_from_lshr_shl_with_msb_zero_i64(i64 %x) { ; CHECK-LABEL: bfoz_from_lshr_shl_with_msb_zero_i64: ; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 63 -; CHECK-NEXT: srli a0, a0, 19 +; CHECK-NEXT: nds.bfoz a0, a0, 0, 44 ; CHECK-NEXT: ret %shl = shl i64 %x, 63 %lshr = lshr i64 %shl, 19 @@ -115,8 +111,7 @@ define i64 @bfoz_from_lshr_shl_with_msb_zero_i64(i64 %x) { define i32 @bfoz_from_and_shl_i32(i32 %x) { ; CHECK-LABEL: bfoz_from_and_shl_i32: ; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 52 -; CHECK-NEXT: srli a0, a0, 40 +; CHECK-NEXT: nds.bfoz a0, a0, 12, 23 ; CHECK-NEXT: ret %shifted = shl i32 %x, 12 %masked = and i32 %shifted, 16773120 @@ -126,8 +121,7 @@ define i32 @bfoz_from_and_shl_i32(i32 %x) { define i64 @bfoz_from_and_shl_i64(i64 %x) { ; CHECK-LABEL: bfoz_from_and_shl_i64: ; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 52 -; CHECK-NEXT: srli a0, a0, 28 +; CHECK-NEXT: nds.bfoz a0, a0, 24, 35 ; CHECK-NEXT: ret %shifted = shl i64 %x, 24 %masked = and i64 %shifted, 68702699520 @@ -137,8 +131,7 @@ define i64 @bfoz_from_and_shl_i64(i64 %x) { define i32 @bfoz_from_lshr_shl_i32(i32 %x) { ; CHECK-LABEL: bfoz_from_lshr_shl_i32: ; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 58 -; CHECK-NEXT: srli a0, a0, 39 +; CHECK-NEXT: nds.bfoz a0, a0, 19, 24 ; CHECK-NEXT: ret %shl = shl i32 %x, 26 %lshr = lshr i32 %shl, 7 @@ -148,8 +141,7 @@ define i32 @bfoz_from_lshr_shl_i32(i32 %x) { define i64 @bfoz_from_lshr_shl_i64(i64 %x) { ; CHECK-LABEL: bfoz_from_lshr_shl_i64: ; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 40 -; CHECK-NEXT: srli a0, a0, 15 +; CHECK-NEXT: nds.bfoz a0, a0, 25, 48 ; CHECK-NEXT: ret %shl = shl i64 %x, 40 %lshr = lshr i64 %shl, 15 diff --git a/llvm/test/CodeGen/RISCV/rv64zba.ll b/llvm/test/CodeGen/RISCV/rv64zba.ll index a4d3b80edbd58..c93dc1f502f23 100644 --- a/llvm/test/CodeGen/RISCV/rv64zba.ll +++ b/llvm/test/CodeGen/RISCV/rv64zba.ll @@ -24,8 +24,7 @@ define i64 @slliuw(i64 %a) nounwind { ; ; RV64XANDESPERF-LABEL: slliuw: ; RV64XANDESPERF: # %bb.0: -; RV64XANDESPERF-NEXT: slli a0, a0, 32 -; RV64XANDESPERF-NEXT: srli a0, a0, 31 +; RV64XANDESPERF-NEXT: nds.bfoz a0, a0, 1, 32 ; RV64XANDESPERF-NEXT: ret %conv1 = shl i64 %a, 1 %shl = and i64 %conv1, 8589934590 From de9c8cee8e9aba2df9282c42487bd5cc50ef3e38 Mon Sep 17 00:00:00 2001 From: Jim Lin Date: Thu, 5 Jun 2025 14:37:17 +0800 Subject: [PATCH 3/4] Make the lsb/msb arguments/variables to truly be least significant bit and most significant bit of the insertion. --- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 4c4b475ed3898..452725febcb85 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -699,8 +699,8 @@ bool RISCVDAGToDAGISel::tryUnsignedBitfieldInsertInZero(SDNode *Node, SDLoc DL, unsigned Opc = RISCV::NDS_BFOZ; SDNode *Ubi = CurDAG->getMachineNode(Opc, DL, VT, X, - CurDAG->getTargetConstant(Msb, DL, VT), - CurDAG->getTargetConstant(Lsb, DL, VT)); + CurDAG->getTargetConstant(Lsb, DL, VT), + CurDAG->getTargetConstant(Msb, DL, VT)); ReplaceNode(Node, Ubi); return true; } @@ -1348,13 +1348,10 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) { // e.g. // (and (shl x, 12), 0x00fff000) // If XLen = 32 and C2 = 12, then - // Len = 32 - 8 - 12 = 12, - // Lsb = 32 - 8 - 1 = 23 and Msb = 12 - // -> nds.bfoz x, 12, 23 - const unsigned Len = XLen - Leading - C2; - const unsigned Lsb = XLen - Leading - 1; - // If Len is 1, the Msb will be 0 instead of C2. - unsigned Msb = Len == 1 ? 0 : C2; + // Msb = 32 - 8 - 1 = 23 and Lsb = 12 + const unsigned Msb = XLen - Leading - 1; + // If Msb is equal to C2, the Lsb will be 0 instead of C2. + unsigned Lsb = Msb == C2 ? 0 : C2; if (tryUnsignedBitfieldInsertInZero(Node, DL, VT, X, Msb, Lsb)) return; From 1c38d740063d528b0012c0c5a79ba5cf54085fbb Mon Sep 17 00:00:00 2001 From: Jim Lin Date: Thu, 5 Jun 2025 14:54:47 +0800 Subject: [PATCH 4/4] Move the selection of 0 into `tryUnsignedBitfieldInsertInZero` --- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 452725febcb85..e835de47f7dae 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -698,6 +698,9 @@ bool RISCVDAGToDAGISel::tryUnsignedBitfieldInsertInZero(SDNode *Node, SDLoc DL, unsigned Opc = RISCV::NDS_BFOZ; + // If the Lsb is equal to the Msb, then the Lsb should be 0. + if (Lsb == Msb) + Lsb = 0; SDNode *Ubi = CurDAG->getMachineNode(Opc, DL, VT, X, CurDAG->getTargetConstant(Lsb, DL, VT), CurDAG->getTargetConstant(Msb, DL, VT)); @@ -1350,8 +1353,7 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) { // If XLen = 32 and C2 = 12, then // Msb = 32 - 8 - 1 = 23 and Lsb = 12 const unsigned Msb = XLen - Leading - 1; - // If Msb is equal to C2, the Lsb will be 0 instead of C2. - unsigned Lsb = Msb == C2 ? 0 : C2; + const unsigned Lsb = C2; if (tryUnsignedBitfieldInsertInZero(Node, DL, VT, X, Msb, Lsb)) return;