[llvm] [RISCV][P-ext] Use pli.b when only the lower 2 bytes are used. (PR #192400)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 15 23:27:38 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Craig Topper (topperc)
<details>
<summary>Changes</summary>
If the lower 2 bytes are the same and are the only bytes used we
can use pli.b instead of lui+addi.
---
Full diff: https://github.com/llvm/llvm-project/pull/192400.diff
3 Files Affected:
- (modified) llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp (+25-11)
- (modified) llvm/test/CodeGen/RISCV/rv32p.ll (+16-6)
- (modified) llvm/test/CodeGen/RISCV/rv64p.ll (+10)
``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index e7be2938c2256..acdb05ae546c0 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -1133,17 +1133,31 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
else if (!isInt<16>(Imm) && isUInt<16>(Imm) &&
isInt<12>(SignExtend64<16>(Imm)) && hasAllHUsers(Node))
Imm = SignExtend64<16>(Imm);
- // If the upper 32-bits are not used try to convert this into a simm32 by
- // sign extending bit 32.
- else if (!isInt<32>(Imm) && isUInt<32>(Imm) && hasAllWUsers(Node))
- Imm = SignExtend64<32>(Imm);
-
- if (VT == MVT::i64 && Subtarget->hasStdExtP() && isApplicableToPLI(Imm) &&
- hasAllWUsers(Node)) {
- // If it's 4 packed 8-bit integers or 2 packed signed 16-bit integers, we
- // can simply copy lower 32 bits to higher 32 bits to make it able to
- // rematerialize to PLI_B or PLI_H
- Imm = ((uint64_t)Imm << 32) | (Imm & 0xFFFFFFFF);
+
+ // If the upper XLen-16 bits are not used, the lower 2 bytes are the same,
+ // and we can't use li, convert to an xlen splat so we can use pli.b.
+ if (Subtarget->hasStdExtP() && !isInt<12>(Imm) &&
+ (Imm & 0xff) == ((Imm >> 8) & 0xff) && hasAllHUsers(Node)) {
+ // Splat the lower 16 bits to XLen. Sign extend for RV32.
+ uint64_t Splat = Imm & 0xffff;
+ Splat = (Splat << 16) | Splat;
+ if (VT == MVT::i64)
+ Imm = Splat << 32 | Splat;
+ else
+ Imm = SignExtend64<32>(Splat);
+ } else {
+ // If the upper 32-bits are not used try to convert this into a simm32 by
+ // sign extending bit 32.
+ if (!isInt<32>(Imm) && isUInt<32>(Imm) && hasAllWUsers(Node))
+ Imm = SignExtend64<32>(Imm);
+
+ if (VT == MVT::i64 && Subtarget->hasStdExtP() && isApplicableToPLI(Imm) &&
+ hasAllWUsers(Node)) {
+ // If it's 4 packed 8-bit integers or 2 packed signed 16-bit integers, we
+ // can simply copy lower 32 bits to higher 32 bits to make it able to
+ // rematerialize to PLI_B or PLI_H
+ Imm = ((uint64_t)Imm << 32) | (Imm & 0xFFFFFFFF);
+ }
}
ReplaceNode(Node, selectImm(CurDAG, DL, VT, Imm, *Subtarget).getNode());
diff --git a/llvm/test/CodeGen/RISCV/rv32p.ll b/llvm/test/CodeGen/RISCV/rv32p.ll
index 154319f221d2a..ebec3f57cae5c 100644
--- a/llvm/test/CodeGen/RISCV/rv32p.ll
+++ b/llvm/test/CodeGen/RISCV/rv32p.ll
@@ -58,6 +58,16 @@ define void @pli_b_store_i32(ptr %p) {
ret void
}
+define void @pli_b_store_i16(ptr %p) {
+; CHECK-LABEL: pli_b_store_i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: pli.b a1, -127
+; CHECK-NEXT: sh a1, 0(a0)
+; CHECK-NEXT: ret
+ store i16 u0x8181, ptr %p
+ ret void
+}
+
define i32 @plui_h_i32(ptr %p) {
; CHECK-LABEL: plui_h_i32:
; CHECK: # %bb.0:
@@ -190,16 +200,16 @@ define i64 @cls_i64(i64 %x) {
; CHECK-LABEL: cls_i64:
; CHECK: # %bb.0:
; CHECK-NEXT: srai a2, a1, 31
-; CHECK-NEXT: bne a1, a2, .LBB16_2
+; CHECK-NEXT: bne a1, a2, .LBB17_2
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: xor a0, a0, a2
; CHECK-NEXT: clz a0, a0
; CHECK-NEXT: addi a0, a0, 32
-; CHECK-NEXT: j .LBB16_3
-; CHECK-NEXT: .LBB16_2:
+; CHECK-NEXT: j .LBB17_3
+; CHECK-NEXT: .LBB17_2:
; CHECK-NEXT: xor a1, a1, a2
; CHECK-NEXT: clz a0, a1
-; CHECK-NEXT: .LBB16_3:
+; CHECK-NEXT: .LBB17_3:
; CHECK-NEXT: li a1, 1
; CHECK-NEXT: wsubu a0, a0, a1
; CHECK-NEXT: ret
@@ -217,7 +227,7 @@ define i64 @cls_i64_2(i64 %x) {
; CHECK-NEXT: xor a1, a1, a2
; CHECK-NEXT: xor a0, a0, a2
; CHECK-NEXT: nsrli a1, a0, 31
-; CHECK-NEXT: bnez a1, .LBB17_2
+; CHECK-NEXT: bnez a1, .LBB18_2
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: slli a0, a0, 1
; CHECK-NEXT: addi a0, a0, 1
@@ -225,7 +235,7 @@ define i64 @cls_i64_2(i64 %x) {
; CHECK-NEXT: addi a0, a0, 32
; CHECK-NEXT: li a1, 0
; CHECK-NEXT: ret
-; CHECK-NEXT: .LBB17_2:
+; CHECK-NEXT: .LBB18_2:
; CHECK-NEXT: clz a0, a1
; CHECK-NEXT: li a1, 0
; CHECK-NEXT: ret
diff --git a/llvm/test/CodeGen/RISCV/rv64p.ll b/llvm/test/CodeGen/RISCV/rv64p.ll
index d4a5e054d312d..21630c8dbb37f 100644
--- a/llvm/test/CodeGen/RISCV/rv64p.ll
+++ b/llvm/test/CodeGen/RISCV/rv64p.ll
@@ -173,6 +173,16 @@ define void @pli_b_store_i32(ptr %p) {
ret void
}
+define void @pli_b_store_i16(ptr %p) {
+; CHECK-LABEL: pli_b_store_i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: pli.b a1, -127
+; CHECK-NEXT: sh a1, 0(a0)
+; CHECK-NEXT: ret
+ store i16 u0x8181, ptr %p
+ ret void
+}
+
define i64 @plui_h_i64() {
; CHECK-LABEL: plui_h_i64:
; CHECK: # %bb.0:
``````````
</details>
https://github.com/llvm/llvm-project/pull/192400
More information about the llvm-commits
mailing list