Skip to content

Commit ae1af94

Browse files
committed
[TTI][TLI][AArch64] Add isLegalAddScalableImmediate
Adds an interface to determine whether an immediate would be legal within an add instruction, when said immediate is multiplied by vscale.
1 parent ccd1608 commit ae1af94

File tree

7 files changed

+89
-0
lines changed

7 files changed

+89
-0
lines changed

llvm/include/llvm/Analysis/TargetTransformInfo.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,12 @@ class TargetTransformInfo {
696696
/// immediate without having to materialize the immediate into a register.
697697
bool isLegalAddImmediate(int64_t Imm) const;
698698

699+
/// Return true if the specified immediate is legal add of a scalable
700+
/// immediate, that is the target has add instructions which can add a
701+
/// register with the immediate (multiplied by vscale) without having to
702+
/// materialize the immediate into a register.
703+
bool isLegalAddScalableImmediate(int64_t Imm) const;
704+
699705
/// Return true if the specified immediate is legal icmp immediate,
700706
/// that is the target has icmp instructions which can compare a register
701707
/// against the immediate without having to materialize the immediate into a
@@ -1835,6 +1841,7 @@ class TargetTransformInfo::Concept {
18351841
std::function<void(Instruction *, unsigned, APInt, APInt &)>
18361842
SimplifyAndSetOp) = 0;
18371843
virtual bool isLegalAddImmediate(int64_t Imm) = 0;
1844+
virtual bool isLegalAddScalableImmediate(int64_t Imm) = 0;
18381845
virtual bool isLegalICmpImmediate(int64_t Imm) = 0;
18391846
virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
18401847
int64_t BaseOffset, bool HasBaseReg,
@@ -2295,6 +2302,9 @@ class TargetTransformInfo::Model final : public TargetTransformInfo::Concept {
22952302
bool isLegalAddImmediate(int64_t Imm) override {
22962303
return Impl.isLegalAddImmediate(Imm);
22972304
}
2305+
bool isLegalAddScalableImmediate(int64_t Imm) override {
2306+
return Impl.isLegalAddScalableImmediate(Imm);
2307+
}
22982308
bool isLegalICmpImmediate(int64_t Imm) override {
22992309
return Impl.isLegalICmpImmediate(Imm);
23002310
}

llvm/include/llvm/Analysis/TargetTransformInfoImpl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ class TargetTransformInfoImplBase {
216216

217217
bool isLegalAddImmediate(int64_t Imm) const { return false; }
218218

219+
bool isLegalAddScalableImmediate(int64_t Imm) const { return false; }
220+
219221
bool isLegalICmpImmediate(int64_t Imm) const { return false; }
220222

221223
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,

llvm/include/llvm/CodeGen/BasicTTIImpl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,10 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
328328
return getTLI()->isLegalAddImmediate(imm);
329329
}
330330

331+
bool isLegalAddScalableImmediate(int64_t Imm) {
332+
return getTLI()->isLegalAddScalableImmediate(Imm);
333+
}
334+
331335
bool isLegalICmpImmediate(int64_t imm) {
332336
return getTLI()->isLegalICmpImmediate(imm);
333337
}

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2770,6 +2770,12 @@ class TargetLoweringBase {
27702770
return true;
27712771
}
27722772

2773+
/// Return true if the specified immediate is legal add of a scalable
2774+
/// immediate, that is the target has add instructions which can add a
2775+
/// register with the immediate (multiplied by vscale) without having to
2776+
/// materialize the immediate into a register.
2777+
virtual bool isLegalAddScalableImmediate(int64_t) const { return false; }
2778+
27732779
/// Return true if the specified immediate is legal for the value input of a
27742780
/// store instruction.
27752781
virtual bool isLegalStoreImmediate(int64_t Value) const {

llvm/lib/Analysis/TargetTransformInfo.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,10 @@ bool TargetTransformInfo::isLegalAddImmediate(int64_t Imm) const {
395395
return TTIImpl->isLegalAddImmediate(Imm);
396396
}
397397

398+
bool TargetTransformInfo::isLegalAddScalableImmediate(int64_t Imm) const {
399+
return TTIImpl->isLegalAddScalableImmediate(Imm);
400+
}
401+
398402
bool TargetTransformInfo::isLegalICmpImmediate(int64_t Imm) const {
399403
return TTIImpl->isLegalICmpImmediate(Imm);
400404
}

llvm/unittests/Target/AArch64/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ add_llvm_target_unittest(AArch64Tests
2929
MatrixRegisterAliasing.cpp
3030
SMEAttributesTest.cpp
3131
AArch64SVESchedPseudoTest.cpp
32+
Immediates.cpp
3233
)
3334

3435
set_property(TARGET AArch64Tests PROPERTY FOLDER "Tests/UnitTests/TargetTests")
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include "AArch64Subtarget.h"
2+
#include "AArch64TargetMachine.h"
3+
#include "llvm/IR/DataLayout.h"
4+
#include "llvm/MC/TargetRegistry.h"
5+
#include "llvm/Support/TargetSelect.h"
6+
7+
#include "gtest/gtest.h"
8+
#include <initializer_list>
9+
#include <memory>
10+
11+
using namespace llvm;
12+
13+
namespace {
14+
15+
struct TestCase {
16+
int64_t Imm;
17+
bool Result;
18+
};
19+
20+
const std::initializer_list<TestCase> Tests = {
21+
// ScalableImm, Result
22+
// No change, easily 'supported'
23+
{0, false},
24+
25+
// addvl increments by whole registers, range [-32,31]
26+
// +(16 * vscale), one register's worth
27+
{16, false},
28+
// +(8 * vscale), half a register's worth
29+
{8, false},
30+
// -(32 * 16 * vscale)
31+
{-512, false},
32+
// -(33 * 16 * vscale)
33+
{-528, false},
34+
// +(31 * 16 * vscale)
35+
{496, false},
36+
// +(32 * 16 * vscale)
37+
{512, false},
38+
};
39+
} // namespace
40+
41+
TEST(Immediates, Immediates) {
42+
LLVMInitializeAArch64TargetInfo();
43+
LLVMInitializeAArch64Target();
44+
LLVMInitializeAArch64TargetMC();
45+
46+
std::string Error;
47+
auto TT = Triple::normalize("aarch64");
48+
const Target *T = TargetRegistry::lookupTarget(TT, Error);
49+
50+
std::unique_ptr<TargetMachine> TM(T->createTargetMachine(
51+
TT, "generic", "+sve", TargetOptions(), std::nullopt, std::nullopt,
52+
CodeGenOptLevel::Default));
53+
AArch64Subtarget ST(TM->getTargetTriple(), TM->getTargetCPU(),
54+
TM->getTargetCPU(), TM->getTargetFeatureString(), *TM,
55+
true);
56+
57+
auto *TLI = ST.getTargetLowering();
58+
59+
for (const auto &Test : Tests) {
60+
ASSERT_EQ(TLI->isLegalAddScalableImmediate(Test.Imm), Test.Result);
61+
}
62+
}

0 commit comments

Comments
 (0)