[llvm] [RISCV] Fold LI 1 / SLLI into BSETI during i64 materialization (PR #142348)
Piotr Fusik via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 2 01:57:21 PDT 2025
https://github.com/pfusik updated https://github.com/llvm/llvm-project/pull/142348
>From 31ee86acc30a57cd5111b3a109a7752663403446 Mon Sep 17 00:00:00 2001
From: Piotr Fusik <p.fusik at samsung.com>
Date: Mon, 2 Jun 2025 10:41:38 +0200
Subject: [PATCH 1/3] [RISCV][test] Add i64 materialization tests for BSETI
---
llvm/test/CodeGen/RISCV/imm.ll | 126 +++++++++++++++++++++++++++++++++
1 file changed, 126 insertions(+)
diff --git a/llvm/test/CodeGen/RISCV/imm.ll b/llvm/test/CodeGen/RISCV/imm.ll
index f324a9bc120ef..fc3af22f082d7 100644
--- a/llvm/test/CodeGen/RISCV/imm.ll
+++ b/llvm/test/CodeGen/RISCV/imm.ll
@@ -4637,3 +4637,129 @@ define i64 @imm64_0xFF7FFFFF7FFFFFFE() {
; RV64-REMAT-NEXT: ret
ret i64 -36028799166447617 ; 0xFF7FFFFF7FFFFFFE
}
+
+define i64 @imm64_0xFFFFFFFF0() {
+; RV32I-LABEL: imm64_0xFFFFFFFF0:
+; RV32I: # %bb.0:
+; RV32I-NEXT: li a0, -16
+; RV32I-NEXT: li a1, 15
+; RV32I-NEXT: ret
+;
+; RV32IXQCILI-LABEL: imm64_0xFFFFFFFF0:
+; RV32IXQCILI: # %bb.0:
+; RV32IXQCILI-NEXT: li a0, -16
+; RV32IXQCILI-NEXT: li a1, 15
+; RV32IXQCILI-NEXT: ret
+;
+; RV64I-LABEL: imm64_0xFFFFFFFF0:
+; RV64I: # %bb.0:
+; RV64I-NEXT: li a0, 1
+; RV64I-NEXT: slli a0, a0, 36
+; RV64I-NEXT: addi a0, a0, -16
+; RV64I-NEXT: ret
+;
+; RV64IZBA-LABEL: imm64_0xFFFFFFFF0:
+; RV64IZBA: # %bb.0:
+; RV64IZBA-NEXT: li a0, 1
+; RV64IZBA-NEXT: slli a0, a0, 36
+; RV64IZBA-NEXT: addi a0, a0, -16
+; RV64IZBA-NEXT: ret
+;
+; RV64IZBB-LABEL: imm64_0xFFFFFFFF0:
+; RV64IZBB: # %bb.0:
+; RV64IZBB-NEXT: li a0, 1
+; RV64IZBB-NEXT: slli a0, a0, 36
+; RV64IZBB-NEXT: addi a0, a0, -16
+; RV64IZBB-NEXT: ret
+;
+; RV64IZBS-LABEL: imm64_0xFFFFFFFF0:
+; RV64IZBS: # %bb.0:
+; RV64IZBS-NEXT: li a0, 1
+; RV64IZBS-NEXT: slli a0, a0, 36
+; RV64IZBS-NEXT: addi a0, a0, -16
+; RV64IZBS-NEXT: ret
+;
+; RV64IXTHEADBB-LABEL: imm64_0xFFFFFFFF0:
+; RV64IXTHEADBB: # %bb.0:
+; RV64IXTHEADBB-NEXT: li a0, 1
+; RV64IXTHEADBB-NEXT: slli a0, a0, 36
+; RV64IXTHEADBB-NEXT: addi a0, a0, -16
+; RV64IXTHEADBB-NEXT: ret
+;
+; RV32-REMAT-LABEL: imm64_0xFFFFFFFF0:
+; RV32-REMAT: # %bb.0:
+; RV32-REMAT-NEXT: li a0, -16
+; RV32-REMAT-NEXT: li a1, 15
+; RV32-REMAT-NEXT: ret
+;
+; RV64-REMAT-LABEL: imm64_0xFFFFFFFF0:
+; RV64-REMAT: # %bb.0:
+; RV64-REMAT-NEXT: li a0, 1
+; RV64-REMAT-NEXT: slli a0, a0, 36
+; RV64-REMAT-NEXT: addi a0, a0, -16
+; RV64-REMAT-NEXT: ret
+ ret i64 68719476720 ; 0xFFFFFFFF0
+}
+
+define i64 @imm64_0x1FFFFFF08() {
+; RV32I-LABEL: imm64_0x1FFFFFF08:
+; RV32I: # %bb.0:
+; RV32I-NEXT: li a0, -248
+; RV32I-NEXT: li a1, 1
+; RV32I-NEXT: ret
+;
+; RV32IXQCILI-LABEL: imm64_0x1FFFFFF08:
+; RV32IXQCILI: # %bb.0:
+; RV32IXQCILI-NEXT: li a0, -248
+; RV32IXQCILI-NEXT: li a1, 1
+; RV32IXQCILI-NEXT: ret
+;
+; RV64I-LABEL: imm64_0x1FFFFFF08:
+; RV64I: # %bb.0:
+; RV64I-NEXT: li a0, 1
+; RV64I-NEXT: slli a0, a0, 33
+; RV64I-NEXT: addi a0, a0, -248
+; RV64I-NEXT: ret
+;
+; RV64IZBA-LABEL: imm64_0x1FFFFFF08:
+; RV64IZBA: # %bb.0:
+; RV64IZBA-NEXT: li a0, 1
+; RV64IZBA-NEXT: slli a0, a0, 33
+; RV64IZBA-NEXT: addi a0, a0, -248
+; RV64IZBA-NEXT: ret
+;
+; RV64IZBB-LABEL: imm64_0x1FFFFFF08:
+; RV64IZBB: # %bb.0:
+; RV64IZBB-NEXT: li a0, 1
+; RV64IZBB-NEXT: slli a0, a0, 33
+; RV64IZBB-NEXT: addi a0, a0, -248
+; RV64IZBB-NEXT: ret
+;
+; RV64IZBS-LABEL: imm64_0x1FFFFFF08:
+; RV64IZBS: # %bb.0:
+; RV64IZBS-NEXT: li a0, 1
+; RV64IZBS-NEXT: slli a0, a0, 33
+; RV64IZBS-NEXT: addi a0, a0, -248
+; RV64IZBS-NEXT: ret
+;
+; RV64IXTHEADBB-LABEL: imm64_0x1FFFFFF08:
+; RV64IXTHEADBB: # %bb.0:
+; RV64IXTHEADBB-NEXT: li a0, 1
+; RV64IXTHEADBB-NEXT: slli a0, a0, 33
+; RV64IXTHEADBB-NEXT: addi a0, a0, -248
+; RV64IXTHEADBB-NEXT: ret
+;
+; RV32-REMAT-LABEL: imm64_0x1FFFFFF08:
+; RV32-REMAT: # %bb.0:
+; RV32-REMAT-NEXT: li a0, -248
+; RV32-REMAT-NEXT: li a1, 1
+; RV32-REMAT-NEXT: ret
+;
+; RV64-REMAT-LABEL: imm64_0x1FFFFFF08:
+; RV64-REMAT: # %bb.0:
+; RV64-REMAT-NEXT: li a0, 1
+; RV64-REMAT-NEXT: slli a0, a0, 33
+; RV64-REMAT-NEXT: addi a0, a0, -248
+; RV64-REMAT-NEXT: ret
+ ret i64 8589934344 ; 0x1FFFFFF08
+}
>From 470ef492abc5235fd8131537a6793d5d8a7d8fbd Mon Sep 17 00:00:00 2001
From: Piotr Fusik <p.fusik at samsung.com>
Date: Mon, 2 Jun 2025 10:41:59 +0200
Subject: [PATCH 2/3] [RISCV] Fold LI 1 / SLLI into BSETI during i64
materialization
My first approach was to avoid emitting LI 1 / SLLI in the first place.
Unfortunately, that favors BSETI C / ADDI -1 over LI -1 / SRLI 64-C
even though the latter has both instructions compressible.
This is because the code assumes in several places that a two-instruction
sequence (here: BSETI + ADDI) cannot be improved.
Another possible approach would be to keep LI 1 / SLLI if it is to be
later replaced with SRLI. This would be harder to grasp than simply
patching LI 1 / SLLI with BSETI.
---
llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp | 7 +++++++
llvm/test/CodeGen/RISCV/imm.ll | 6 ++----
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
index 8ea2548258fdb..f239129617b97 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
@@ -353,6 +353,13 @@ InstSeq generateInstSeq(int64_t Val, const MCSubtargetInfo &STI) {
} while (Hi != 0);
Res = TmpSeq;
}
+
+ // Fold LI 1 + SLLI into BSETI.
+ if (Res[0].getOpcode() == RISCV::ADDI && Res[0].getImm() == 1 &&
+ Res[1].getOpcode() == RISCV::SLLI) {
+ Res.erase(Res.begin()); // Remove ADDI.
+ Res.front() = Inst(RISCV::BSETI, Res.front().getImm()); // Patch SLLI.
+ }
}
// Perform optimization with BCLRI in the Zbs extension.
diff --git a/llvm/test/CodeGen/RISCV/imm.ll b/llvm/test/CodeGen/RISCV/imm.ll
index fc3af22f082d7..418407d9b7cd6 100644
--- a/llvm/test/CodeGen/RISCV/imm.ll
+++ b/llvm/test/CodeGen/RISCV/imm.ll
@@ -4674,8 +4674,7 @@ define i64 @imm64_0xFFFFFFFF0() {
;
; RV64IZBS-LABEL: imm64_0xFFFFFFFF0:
; RV64IZBS: # %bb.0:
-; RV64IZBS-NEXT: li a0, 1
-; RV64IZBS-NEXT: slli a0, a0, 36
+; RV64IZBS-NEXT: bseti a0, zero, 36
; RV64IZBS-NEXT: addi a0, a0, -16
; RV64IZBS-NEXT: ret
;
@@ -4737,8 +4736,7 @@ define i64 @imm64_0x1FFFFFF08() {
;
; RV64IZBS-LABEL: imm64_0x1FFFFFF08:
; RV64IZBS: # %bb.0:
-; RV64IZBS-NEXT: li a0, 1
-; RV64IZBS-NEXT: slli a0, a0, 33
+; RV64IZBS-NEXT: bseti a0, zero, 33
; RV64IZBS-NEXT: addi a0, a0, -248
; RV64IZBS-NEXT: ret
;
>From 31ef10c52e7d81bbce5b8d8ac7057535dd6b026f Mon Sep 17 00:00:00 2001
From: Piotr Fusik <p.fusik at samsung.com>
Date: Mon, 2 Jun 2025 10:56:57 +0200
Subject: [PATCH 3/3] [RISCV] clang-format
---
llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
index f239129617b97..323bcfc11625a 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
@@ -357,7 +357,7 @@ InstSeq generateInstSeq(int64_t Val, const MCSubtargetInfo &STI) {
// Fold LI 1 + SLLI into BSETI.
if (Res[0].getOpcode() == RISCV::ADDI && Res[0].getImm() == 1 &&
Res[1].getOpcode() == RISCV::SLLI) {
- Res.erase(Res.begin()); // Remove ADDI.
+ Res.erase(Res.begin()); // Remove ADDI.
Res.front() = Inst(RISCV::BSETI, Res.front().getImm()); // Patch SLLI.
}
}
More information about the llvm-commits
mailing list