[llvm] 5baf58b - [RISCV] Improve use of BSETI/BCLRI in constant materialization. (#91546)
via llvm-commits
llvm-commits at lists.llvm.org
Wed May 8 21:53:19 PDT 2024
Author: Craig Topper
Date: 2024-05-08T21:53:15-07:00
New Revision: 5baf58b628a4488de3f1a6af7c0df180358ba5dc
URL: https://github.com/llvm/llvm-project/commit/5baf58b628a4488de3f1a6af7c0df180358ba5dc
DIFF: https://github.com/llvm/llvm-project/commit/5baf58b628a4488de3f1a6af7c0df180358ba5dc.diff
LOG: [RISCV] Improve use of BSETI/BCLRI in constant materialization. (#91546)
We failed to use BSETI when bit 31 was set and a few bits above bit 31
were set. We also failed to use multiple BSETI when the low 32 bits were
zero.
I've removed the special cases for constants 0x80000000-0xffffffff and
wrote a more generic algorithm for BSETI.
I've rewritten the BCLRI handling to be similar to the new BSETI
algorithm. This picks up cases where bit 31 is 0 and only a few high
bits are 0.
Added:
Modified:
llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
llvm/test/CodeGen/RISCV/imm.ll
llvm/test/CodeGen/RISCV/rv64-legal-i32/imm.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
index c3bae152993ea..0a304d4cb7d90 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
@@ -310,56 +310,45 @@ InstSeq generateInstSeq(int64_t Val, const MCSubtargetInfo &STI) {
}
}
- // Perform optimization with BCLRI/BSETI in the Zbs extension.
+ // Perform optimization with BSETI in the Zbs extension.
if (Res.size() > 2 && STI.hasFeature(RISCV::FeatureStdExtZbs)) {
- // 1. For values in range 0xffffffff 7fffffff ~ 0xffffffff 00000000,
- // call generateInstSeqImpl with Val|0x80000000 (which is expected be
- // an int32), then emit (BCLRI r, 31).
- // 2. For values in range 0x80000000 ~ 0xffffffff, call generateInstSeqImpl
- // with Val&~0x80000000 (which is expected to be an int32), then
- // emit (BSETI r, 31).
- int64_t NewVal;
- unsigned Opc;
- if (Val < 0) {
- Opc = RISCV::BCLRI;
- NewVal = Val | 0x80000000ll;
- } else {
- Opc = RISCV::BSETI;
- NewVal = Val & ~0x80000000ll;
- }
- if (isInt<32>(NewVal)) {
- RISCVMatInt::InstSeq TmpSeq;
- generateInstSeqImpl(NewVal, STI, TmpSeq);
- if ((TmpSeq.size() + 1) < Res.size()) {
- TmpSeq.emplace_back(Opc, 31);
- Res = TmpSeq;
- }
+ // Create a simm32 value for LUI+ADDIW by forcing the upper 33 bits to zero.
+ // Xor that with original value to get which bits should be set by BSETI.
+ uint64_t Lo = Val & 0x7fffffff;
+ uint64_t Hi = Val ^ Lo;
+ assert(Hi != 0);
+ RISCVMatInt::InstSeq TmpSeq;
+
+ if (Lo != 0)
+ generateInstSeqImpl(Lo, STI, TmpSeq);
+
+ if (TmpSeq.size() + llvm::popcount(Hi) < Res.size()) {
+ do {
+ TmpSeq.emplace_back(RISCV::BSETI, llvm::countr_zero(Hi));
+ Hi &= (Hi - 1); // Clear lowest set bit.
+ } while (Hi != 0);
+ Res = TmpSeq;
}
+ }
+
+ // Perform optimization with BCLRI in the Zbs extension.
+ if (Res.size() > 2 && STI.hasFeature(RISCV::FeatureStdExtZbs)) {
+ // Create a simm32 value for LUI+ADDIW by forcing the upper 33 bits to one.
+ // Xor that with original value to get which bits should be cleared by
+ // BCLRI.
+ uint64_t Lo = Val | 0xffffffff80000000;
+ uint64_t Hi = Val ^ Lo;
+ assert(Hi != 0);
- // Try to use BCLRI for upper 32 bits if the original lower 32 bits are
- // negative int32, or use BSETI for upper 32 bits if the original lower
- // 32 bits are positive int32.
- int32_t Lo = Lo_32(Val);
- uint32_t Hi = Hi_32(Val);
- Opc = 0;
RISCVMatInt::InstSeq TmpSeq;
generateInstSeqImpl(Lo, STI, TmpSeq);
- // Check if it is profitable to use BCLRI/BSETI.
- if (Lo > 0 && TmpSeq.size() + llvm::popcount(Hi) < Res.size()) {
- Opc = RISCV::BSETI;
- } else if (Lo < 0 && TmpSeq.size() + llvm::popcount(~Hi) < Res.size()) {
- Opc = RISCV::BCLRI;
- Hi = ~Hi;
- }
- // Search for each bit and build corresponding BCLRI/BSETI.
- if (Opc > 0) {
- while (Hi != 0) {
- unsigned Bit = llvm::countr_zero(Hi);
- TmpSeq.emplace_back(Opc, Bit + 32);
+
+ if (TmpSeq.size() + llvm::popcount(Hi) < Res.size()) {
+ do {
+ TmpSeq.emplace_back(RISCV::BCLRI, llvm::countr_zero(Hi));
Hi &= (Hi - 1); // Clear lowest set bit.
- }
- if (TmpSeq.size() < Res.size())
- Res = TmpSeq;
+ } while (Hi != 0);
+ Res = TmpSeq;
}
}
diff --git a/llvm/test/CodeGen/RISCV/imm.ll b/llvm/test/CodeGen/RISCV/imm.ll
index 0dc5c7ceb500c..c5c1657b526a6 100644
--- a/llvm/test/CodeGen/RISCV/imm.ll
+++ b/llvm/test/CodeGen/RISCV/imm.ll
@@ -4025,9 +4025,8 @@ define i64 @imm64_0x8000080000000() {
;
; RV64IZBS-LABEL: imm64_0x8000080000000:
; RV64IZBS: # %bb.0:
-; RV64IZBS-NEXT: lui a0, 256
-; RV64IZBS-NEXT: addiw a0, a0, 1
-; RV64IZBS-NEXT: slli a0, a0, 31
+; RV64IZBS-NEXT: bseti a0, zero, 31
+; RV64IZBS-NEXT: bseti a0, a0, 51
; RV64IZBS-NEXT: ret
;
; RV64IXTHEADBB-LABEL: imm64_0x8000080000000:
@@ -4083,9 +4082,8 @@ define i64 @imm64_0x10000100000000() {
;
; RV64IZBS-LABEL: imm64_0x10000100000000:
; RV64IZBS: # %bb.0:
-; RV64IZBS-NEXT: lui a0, 256
-; RV64IZBS-NEXT: addi a0, a0, 1
-; RV64IZBS-NEXT: slli a0, a0, 32
+; RV64IZBS-NEXT: bseti a0, zero, 32
+; RV64IZBS-NEXT: bseti a0, a0, 52
; RV64IZBS-NEXT: ret
;
; RV64IXTHEADBB-LABEL: imm64_0x10000100000000:
@@ -4146,10 +4144,9 @@ define i64 @imm64_0xFF7FFFFF7FFFFFFE() {
;
; RV64IZBS-LABEL: imm64_0xFF7FFFFF7FFFFFFE:
; RV64IZBS: # %bb.0:
-; RV64IZBS-NEXT: lui a0, 1044480
-; RV64IZBS-NEXT: addiw a0, a0, -1
-; RV64IZBS-NEXT: slli a0, a0, 31
-; RV64IZBS-NEXT: addi a0, a0, -1
+; RV64IZBS-NEXT: li a0, -1
+; RV64IZBS-NEXT: bclri a0, a0, 31
+; RV64IZBS-NEXT: bclri a0, a0, 55
; RV64IZBS-NEXT: ret
;
; RV64IXTHEADBB-LABEL: imm64_0xFF7FFFFF7FFFFFFE:
diff --git a/llvm/test/CodeGen/RISCV/rv64-legal-i32/imm.ll b/llvm/test/CodeGen/RISCV/rv64-legal-i32/imm.ll
index bac4bb9ce6f1a..561686374a9b9 100644
--- a/llvm/test/CodeGen/RISCV/rv64-legal-i32/imm.ll
+++ b/llvm/test/CodeGen/RISCV/rv64-legal-i32/imm.ll
@@ -2648,9 +2648,8 @@ define i64 @imm64_0x8000080000000() {
;
; RV64IZBS-LABEL: imm64_0x8000080000000:
; RV64IZBS: # %bb.0:
-; RV64IZBS-NEXT: lui a0, 256
-; RV64IZBS-NEXT: addiw a0, a0, 1
-; RV64IZBS-NEXT: slli a0, a0, 31
+; RV64IZBS-NEXT: bseti a0, zero, 31
+; RV64IZBS-NEXT: bseti a0, a0, 51
; RV64IZBS-NEXT: ret
;
; RV64IXTHEADBB-LABEL: imm64_0x8000080000000:
@@ -2686,9 +2685,8 @@ define i64 @imm64_0x10000100000000() {
;
; RV64IZBS-LABEL: imm64_0x10000100000000:
; RV64IZBS: # %bb.0:
-; RV64IZBS-NEXT: lui a0, 256
-; RV64IZBS-NEXT: addi a0, a0, 1
-; RV64IZBS-NEXT: slli a0, a0, 32
+; RV64IZBS-NEXT: bseti a0, zero, 32
+; RV64IZBS-NEXT: bseti a0, a0, 52
; RV64IZBS-NEXT: ret
;
; RV64IXTHEADBB-LABEL: imm64_0x10000100000000:
@@ -2727,10 +2725,9 @@ define i64 @imm64_0xFF7FFFFF7FFFFFFE() {
;
; RV64IZBS-LABEL: imm64_0xFF7FFFFF7FFFFFFE:
; RV64IZBS: # %bb.0:
-; RV64IZBS-NEXT: lui a0, 1044480
-; RV64IZBS-NEXT: addiw a0, a0, -1
-; RV64IZBS-NEXT: slli a0, a0, 31
-; RV64IZBS-NEXT: addi a0, a0, -1
+; RV64IZBS-NEXT: li a0, -1
+; RV64IZBS-NEXT: bclri a0, a0, 31
+; RV64IZBS-NEXT: bclri a0, a0, 55
; RV64IZBS-NEXT: ret
;
; RV64IXTHEADBB-LABEL: imm64_0xFF7FFFFF7FFFFFFE:
More information about the llvm-commits
mailing list