From 9c1d4a1c4c75a2508ac8544b1a43dbf4d8d47e14 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 8 May 2024 15:45:16 -0700 Subject: [PATCH 1/5] [RISCV] Improve use of BSETI in constant materialization. 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. I'm not sure if this adds any new cases we weren't handling before. --- .../Target/RISCV/MCTargetDesc/RISCVMatInt.cpp | 80 +++++++++---------- llvm/test/CodeGen/RISCV/imm.ll | 10 +-- llvm/test/CodeGen/RISCV/rv64-legal-i32/imm.ll | 10 +-- 3 files changed, 44 insertions(+), 56 deletions(-) diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp index c3bae152993ea49..aaa76cab4e5ac4e 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp @@ -10,7 +10,9 @@ #include "MCTargetDesc/RISCVMCTargetDesc.h" #include "llvm/ADT/APInt.h" #include "llvm/MC/MCInstBuilder.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; static int getInstSeqCost(RISCVMatInt::InstSeq &Res, bool HasRVC) { @@ -310,56 +312,46 @@ 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 with by forcing the upper 33 bits to + // zero. Xor that with original value to get which bits need to 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 with by forcing the upper 33 bits to + // one. Xor that with original value to get which bits need to 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 6456401dbb8652e..0f3c820939af5a6 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: diff --git a/llvm/test/CodeGen/RISCV/rv64-legal-i32/imm.ll b/llvm/test/CodeGen/RISCV/rv64-legal-i32/imm.ll index c5bb7289e448a21..9430de61c515b07 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: From ecc89f3f31929bbe56208f8c3312eaf9215eca5c Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 8 May 2024 16:23:23 -0700 Subject: [PATCH 2/5] fixup! New bclri test. --- llvm/test/CodeGen/RISCV/imm.ll | 7 +++---- llvm/test/CodeGen/RISCV/rv64-legal-i32/imm.ll | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/llvm/test/CodeGen/RISCV/imm.ll b/llvm/test/CodeGen/RISCV/imm.ll index 3a2b9b998672a13..c5c1657b526a6be 100644 --- a/llvm/test/CodeGen/RISCV/imm.ll +++ b/llvm/test/CodeGen/RISCV/imm.ll @@ -4144,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 e649868bfee2283..561686374a9b90b 100644 --- a/llvm/test/CodeGen/RISCV/rv64-legal-i32/imm.ll +++ b/llvm/test/CodeGen/RISCV/rv64-legal-i32/imm.ll @@ -2725,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: From 0a16bc42a6ffcfaf7ca3d11430583770af0fc305 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 8 May 2024 18:40:12 -0700 Subject: [PATCH 3/5] fixup! remove unneeded debug headers. --- llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp index aaa76cab4e5ac4e..b29dd8cff33d600 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp @@ -10,9 +10,7 @@ #include "MCTargetDesc/RISCVMCTargetDesc.h" #include "llvm/ADT/APInt.h" #include "llvm/MC/MCInstBuilder.h" -#include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" -#include "llvm/Support/raw_ostream.h" using namespace llvm; static int getInstSeqCost(RISCVMatInt::InstSeq &Res, bool HasRVC) { From 0b7dd3dedc7e050f4d2f9bf4266860fbfee09252 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 8 May 2024 21:38:37 -0700 Subject: [PATCH 4/5] fixup! Fix grammar in comment. --- llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp | 9 ++++----- llvm/lib/Target/RISCV/RISCVPostRAExpandPseudoInsts.cpp | 4 +--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp index b29dd8cff33d600..0a304d4cb7d9077 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp @@ -312,9 +312,8 @@ InstSeq generateInstSeq(int64_t Val, const MCSubtargetInfo &STI) { // Perform optimization with BSETI in the Zbs extension. if (Res.size() > 2 && STI.hasFeature(RISCV::FeatureStdExtZbs)) { - // Create a simm32 value for LUI+ADDIW with by forcing the upper 33 bits to - // zero. Xor that with original value to get which bits need to be set by - // BSETI. + // 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); @@ -334,8 +333,8 @@ InstSeq generateInstSeq(int64_t Val, const MCSubtargetInfo &STI) { // Perform optimization with BCLRI in the Zbs extension. if (Res.size() > 2 && STI.hasFeature(RISCV::FeatureStdExtZbs)) { - // Create a simm32 value for LUI+ADDIW with by forcing the upper 33 bits to - // one. Xor that with original value to get which bits need to be cleared by + // 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; diff --git a/llvm/lib/Target/RISCV/RISCVPostRAExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVPostRAExpandPseudoInsts.cpp index 57b473645ae7a47..52f2ce27164d6e3 100644 --- a/llvm/lib/Target/RISCV/RISCVPostRAExpandPseudoInsts.cpp +++ b/llvm/lib/Target/RISCV/RISCVPostRAExpandPseudoInsts.cpp @@ -31,9 +31,7 @@ class RISCVPostRAExpandPseudo : public MachineFunctionPass { const RISCVInstrInfo *TII; static char ID; - RISCVPostRAExpandPseudo() : MachineFunctionPass(ID) { - initializeRISCVPostRAExpandPseudoPass(*PassRegistry::getPassRegistry()); - } + RISCVPostRAExpandPseudo() : MachineFunctionPass(ID) {} bool runOnMachineFunction(MachineFunction &MF) override; From 36191d99858c7e19116a7234ed9c0345878df75b Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 8 May 2024 21:50:57 -0700 Subject: [PATCH 5/5] fixup! remove stray change --- llvm/lib/Target/RISCV/RISCVPostRAExpandPseudoInsts.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/RISCV/RISCVPostRAExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVPostRAExpandPseudoInsts.cpp index 52f2ce27164d6e3..57b473645ae7a47 100644 --- a/llvm/lib/Target/RISCV/RISCVPostRAExpandPseudoInsts.cpp +++ b/llvm/lib/Target/RISCV/RISCVPostRAExpandPseudoInsts.cpp @@ -31,7 +31,9 @@ class RISCVPostRAExpandPseudo : public MachineFunctionPass { const RISCVInstrInfo *TII; static char ID; - RISCVPostRAExpandPseudo() : MachineFunctionPass(ID) {} + RISCVPostRAExpandPseudo() : MachineFunctionPass(ID) { + initializeRISCVPostRAExpandPseudoPass(*PassRegistry::getPassRegistry()); + } bool runOnMachineFunction(MachineFunction &MF) override;