[llvm] [RISCV] Improve constant materialization by using a sequence that end… (PR #66943)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 27 13:00:15 PDT 2023
https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/66943
>From 31b079498a912b2892f776b0a8c6c927c3ec09bb Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Wed, 20 Sep 2023 12:02:26 -0700
Subject: [PATCH 1/4] [RISCV] Improve constant materialization by using a
sequence that ends with 2 addis in some cases.
If the lower 13 bits are something like 0x17ff, we can first
materialize it as 0x1800 followed by an addi to subtract a small
offset. This might be cheaper to materialize since the constant
ending in 0x1800 can use a simm12 immediate for its final addi.
---
.../Target/RISCV/MCTargetDesc/RISCVMatInt.cpp | 21 ++++-
llvm/test/CodeGen/RISCV/imm.ll | 81 ++++++++-----------
2 files changed, 52 insertions(+), 50 deletions(-)
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
index 6c5d0ad5b092708..b9816a077b70832 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
@@ -9,6 +9,8 @@
#include "RISCVMatInt.h"
#include "MCTargetDesc/RISCVMCTargetDesc.h"
#include "llvm/ADT/APInt.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/MathExtras.h"
using namespace llvm;
@@ -257,10 +259,25 @@ InstSeq generateInstSeq(int64_t Val, const FeatureBitset &ActiveFeatures) {
assert(ActiveFeatures[RISCV::Feature64Bit] &&
"Expected RV32 to only need 2 instructions");
+ // If the lower 13 bits are something like 0x17ff, try to turn it into 0x1800
+ // and use a final addi to correct it back to 0x17ff. This will create a
+ // sequence ending in 2 addis.
+ if ((Val & 0xfff) != 0 && (Val & 0x1800) == 0x1000) {
+ int64_t Imm12 = -(0x800 - (Val & 0xfff));
+ int64_t AdjustedVal = Val - Imm12;
+ RISCVMatInt::InstSeq TmpSeq;
+ generateInstSeqImpl(AdjustedVal, ActiveFeatures, TmpSeq);
+
+ // Keep the new sequence if it is an improvement.
+ if ((TmpSeq.size() + 1) < Res.size()) {
+ TmpSeq.emplace_back(RISCV::ADDI, Imm12);
+ Res = TmpSeq;
+ }
+ }
+
// If the constant is positive we might be able to generate a shifted constant
// with no leading zeros and use a final SRLI to restore them.
- if (Val > 0) {
- assert(Res.size() > 2 && "Expected longer sequence");
+ if (Val > 0 && Res.size() > 2) {
generateInstSeqLeadingZeros(Val, ActiveFeatures, Res);
}
diff --git a/llvm/test/CodeGen/RISCV/imm.ll b/llvm/test/CodeGen/RISCV/imm.ll
index 307d19690bff0ec..ae66af726797598 100644
--- a/llvm/test/CodeGen/RISCV/imm.ll
+++ b/llvm/test/CodeGen/RISCV/imm.ll
@@ -1107,46 +1107,41 @@ define i64 @imm_end_2addi_1() nounwind {
; RV64I-LABEL: imm_end_2addi_1:
; RV64I: # %bb.0:
; RV64I-NEXT: li a0, -2047
-; RV64I-NEXT: slli a0, a0, 27
+; RV64I-NEXT: slli a0, a0, 39
+; RV64I-NEXT: addi a0, a0, -2048
; RV64I-NEXT: addi a0, a0, -1
-; RV64I-NEXT: slli a0, a0, 12
-; RV64I-NEXT: addi a0, a0, 2047
; RV64I-NEXT: ret
;
; RV64IZBA-LABEL: imm_end_2addi_1:
; RV64IZBA: # %bb.0:
; RV64IZBA-NEXT: li a0, -2047
-; RV64IZBA-NEXT: slli a0, a0, 27
+; RV64IZBA-NEXT: slli a0, a0, 39
+; RV64IZBA-NEXT: addi a0, a0, -2048
; RV64IZBA-NEXT: addi a0, a0, -1
-; RV64IZBA-NEXT: slli a0, a0, 12
-; RV64IZBA-NEXT: addi a0, a0, 2047
; RV64IZBA-NEXT: ret
;
; RV64IZBB-LABEL: imm_end_2addi_1:
; RV64IZBB: # %bb.0:
; RV64IZBB-NEXT: li a0, -2047
-; RV64IZBB-NEXT: slli a0, a0, 27
+; RV64IZBB-NEXT: slli a0, a0, 39
+; RV64IZBB-NEXT: addi a0, a0, -2048
; RV64IZBB-NEXT: addi a0, a0, -1
-; RV64IZBB-NEXT: slli a0, a0, 12
-; RV64IZBB-NEXT: addi a0, a0, 2047
; RV64IZBB-NEXT: ret
;
; RV64IZBS-LABEL: imm_end_2addi_1:
; RV64IZBS: # %bb.0:
; RV64IZBS-NEXT: li a0, -2047
-; RV64IZBS-NEXT: slli a0, a0, 27
+; RV64IZBS-NEXT: slli a0, a0, 39
+; RV64IZBS-NEXT: addi a0, a0, -2048
; RV64IZBS-NEXT: addi a0, a0, -1
-; RV64IZBS-NEXT: slli a0, a0, 12
-; RV64IZBS-NEXT: addi a0, a0, 2047
; RV64IZBS-NEXT: ret
;
; RV64IXTHEADBB-LABEL: imm_end_2addi_1:
; RV64IXTHEADBB: # %bb.0:
; RV64IXTHEADBB-NEXT: li a0, -2047
-; RV64IXTHEADBB-NEXT: slli a0, a0, 27
+; RV64IXTHEADBB-NEXT: slli a0, a0, 39
+; RV64IXTHEADBB-NEXT: addi a0, a0, -2048
; RV64IXTHEADBB-NEXT: addi a0, a0, -1
-; RV64IXTHEADBB-NEXT: slli a0, a0, 12
-; RV64IXTHEADBB-NEXT: addi a0, a0, 2047
; RV64IXTHEADBB-NEXT: ret
ret i64 -1125350151030785 ; 0xFFFC_007F_FFFF_F7FF
}
@@ -2435,21 +2430,14 @@ define i64 @imm_12900925247761() {
; RV32I-NEXT: addi a1, a1, -1093
; RV32I-NEXT: ret
;
-; RV64-NOPOOL-LABEL: imm_12900925247761:
-; RV64-NOPOOL: # %bb.0:
-; RV64-NOPOOL-NEXT: lui a0, 188
-; RV64-NOPOOL-NEXT: addiw a0, a0, -1093
-; RV64-NOPOOL-NEXT: slli a0, a0, 12
-; RV64-NOPOOL-NEXT: addi a0, a0, 273
-; RV64-NOPOOL-NEXT: slli a0, a0, 12
-; RV64-NOPOOL-NEXT: addi a0, a0, 273
-; RV64-NOPOOL-NEXT: ret
-;
-; RV64I-POOL-LABEL: imm_12900925247761:
-; RV64I-POOL: # %bb.0:
-; RV64I-POOL-NEXT: lui a0, %hi(.LCPI52_0)
-; RV64I-POOL-NEXT: ld a0, %lo(.LCPI52_0)(a0)
-; RV64I-POOL-NEXT: ret
+; RV64I-LABEL: imm_12900925247761:
+; RV64I: # %bb.0:
+; RV64I-NEXT: lui a0, 384478
+; RV64I-NEXT: addiw a0, a0, -1911
+; RV64I-NEXT: slli a0, a0, 13
+; RV64I-NEXT: addi a0, a0, -2048
+; RV64I-NEXT: addi a0, a0, -1775
+; RV64I-NEXT: ret
;
; RV64IZBA-LABEL: imm_12900925247761:
; RV64IZBA: # %bb.0:
@@ -2461,32 +2449,29 @@ define i64 @imm_12900925247761() {
;
; RV64IZBB-LABEL: imm_12900925247761:
; RV64IZBB: # %bb.0:
-; RV64IZBB-NEXT: lui a0, 188
-; RV64IZBB-NEXT: addiw a0, a0, -1093
-; RV64IZBB-NEXT: slli a0, a0, 12
-; RV64IZBB-NEXT: addi a0, a0, 273
-; RV64IZBB-NEXT: slli a0, a0, 12
-; RV64IZBB-NEXT: addi a0, a0, 273
+; RV64IZBB-NEXT: lui a0, 384478
+; RV64IZBB-NEXT: addiw a0, a0, -1911
+; RV64IZBB-NEXT: slli a0, a0, 13
+; RV64IZBB-NEXT: addi a0, a0, -2048
+; RV64IZBB-NEXT: addi a0, a0, -1775
; RV64IZBB-NEXT: ret
;
; RV64IZBS-LABEL: imm_12900925247761:
; RV64IZBS: # %bb.0:
-; RV64IZBS-NEXT: lui a0, 188
-; RV64IZBS-NEXT: addiw a0, a0, -1093
-; RV64IZBS-NEXT: slli a0, a0, 12
-; RV64IZBS-NEXT: addi a0, a0, 273
-; RV64IZBS-NEXT: slli a0, a0, 12
-; RV64IZBS-NEXT: addi a0, a0, 273
+; RV64IZBS-NEXT: lui a0, 384478
+; RV64IZBS-NEXT: addiw a0, a0, -1911
+; RV64IZBS-NEXT: slli a0, a0, 13
+; RV64IZBS-NEXT: addi a0, a0, -2048
+; RV64IZBS-NEXT: addi a0, a0, -1775
; RV64IZBS-NEXT: ret
;
; RV64IXTHEADBB-LABEL: imm_12900925247761:
; RV64IXTHEADBB: # %bb.0:
-; RV64IXTHEADBB-NEXT: lui a0, 188
-; RV64IXTHEADBB-NEXT: addiw a0, a0, -1093
-; RV64IXTHEADBB-NEXT: slli a0, a0, 12
-; RV64IXTHEADBB-NEXT: addi a0, a0, 273
-; RV64IXTHEADBB-NEXT: slli a0, a0, 12
-; RV64IXTHEADBB-NEXT: addi a0, a0, 273
+; RV64IXTHEADBB-NEXT: lui a0, 384478
+; RV64IXTHEADBB-NEXT: addiw a0, a0, -1911
+; RV64IXTHEADBB-NEXT: slli a0, a0, 13
+; RV64IXTHEADBB-NEXT: addi a0, a0, -2048
+; RV64IXTHEADBB-NEXT: addi a0, a0, -1775
; RV64IXTHEADBB-NEXT: ret
ret i64 12900925247761
}
>From 02a69e22cdbcebf3eb66104bb41d3dd0a396ff68 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Wed, 20 Sep 2023 12:11:44 -0700
Subject: [PATCH 2/4] Remove unneeded includes from debugging.
---
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 b9816a077b70832..d54ad9c99b895e5 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
@@ -9,8 +9,6 @@
#include "RISCVMatInt.h"
#include "MCTargetDesc/RISCVMCTargetDesc.h"
#include "llvm/ADT/APInt.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/MathExtras.h"
using namespace llvm;
>From d41946626ffd1b51f43a61135cf5952518a835a9 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Tue, 26 Sep 2023 10:11:20 -0700
Subject: [PATCH 3/4] Improve comment description.
---
llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
index d54ad9c99b895e5..dc00fdfc2146a8a 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
@@ -257,9 +257,11 @@ InstSeq generateInstSeq(int64_t Val, const FeatureBitset &ActiveFeatures) {
assert(ActiveFeatures[RISCV::Feature64Bit] &&
"Expected RV32 to only need 2 instructions");
- // If the lower 13 bits are something like 0x17ff, try to turn it into 0x1800
- // and use a final addi to correct it back to 0x17ff. This will create a
- // sequence ending in 2 addis.
+ // If the lower 13 bits are something like 0x17ff, try to add 1 to change the
+ // lower 13 bits to 0x1800. We can restore this with an ADDI of -1 at the end
+ // of the sequence. Call generateInstSeqImpl on the new constant which may
+ // subtract 0xfffffffffffff800 to create another ADDI. This will leave a
+ // constant with more than 12 trailing zeros for the next recursive step.
if ((Val & 0xfff) != 0 && (Val & 0x1800) == 0x1000) {
int64_t Imm12 = -(0x800 - (Val & 0xfff));
int64_t AdjustedVal = Val - Imm12;
>From 89ecf1dec26ee372899ffc858ddea59622bea59e Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Wed, 27 Sep 2023 12:59:48 -0700
Subject: [PATCH 4/4] Update MC layer test
---
llvm/test/MC/RISCV/rv64i-aliases-valid.s | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/llvm/test/MC/RISCV/rv64i-aliases-valid.s b/llvm/test/MC/RISCV/rv64i-aliases-valid.s
index 67533e944e86a7a..0102a6bbe15706f 100644
--- a/llvm/test/MC/RISCV/rv64i-aliases-valid.s
+++ b/llvm/test/MC/RISCV/rv64i-aliases-valid.s
@@ -161,15 +161,13 @@ li x9, 0x1000FFFFFFFD
# CHECK-ALIAS-NEXT: not a0, a0
li x10, 0xE000000001FFFFFF
# CHECK-INST: addi a1, zero, -2047
-# CHECK-INST-NEXT: slli a1, a1, 27
+# CHECK-INST-NEXT: slli a1, a1, 39
+# CHECK-INST-NEXT: addi a1, a1, -2048
# CHECK-INST-NEXT: addi a1, a1, -1
-# CHECK-INST-NEXT: slli a1, a1, 12
-# CHECK-INST-NEXT: addi a1, a1, 2047
# CHECK-ALIAS: li a1, -2047
-# CHECK-ALIAS-NEXT: slli a1, a1, 27
+# CHECK-ALIAS-NEXT: slli a1, a1, 39
+# CHECK-ALIAS-NEXT: addi a1, a1, -2048
# CHECK-ALIAS-NEXT: addi a1, a1, -1
-# CHECK-ALIAS-NEXT: slli a1, a1, 12
-# CHECK-ALIAS-NEXT: addi a1, a1, 2047
li x11, 0xFFFC007FFFFFF7FF
# CHECK-INST: lui a2, 349525
@@ -398,15 +396,13 @@ lla x9, 0x1000FFFFFFFD
la x10, 0xE000000001FFFFFF
lla x10, 0xE000000001FFFFFF
# CHECK-INST: addi a1, zero, -2047
-# CHECK-INST-NEXT: slli a1, a1, 27
+# CHECK-INST-NEXT: slli a1, a1, 39
+# CHECK-INST-NEXT: addi a1, a1, -2048
# CHECK-INST-NEXT: addi a1, a1, -1
-# CHECK-INST-NEXT: slli a1, a1, 12
-# CHECK-INST-NEXT: addi a1, a1, 2047
# CHECK-ALIAS: li a1, -2047
-# CHECK-ALIAS-NEXT: slli a1, a1, 27
+# CHECK-ALIAS-NEXT: slli a1, a1, 39
+# CHECK-ALIAS-NEXT: addi a1, a1, -2048
# CHECK-ALIAS-NEXT: addi a1, a1, -1
-# CHECK-ALIAS-NEXT: slli a1, a1, 12
-# CHECK-ALIAS-NEXT: addi a1, a1, 2047
la x11, 0xFFFC007FFFFFF7FF
lla x11, 0xFFFC007FFFFFF7FF
More information about the llvm-commits
mailing list