Skip to content

Commit 04354d5

Browse files
committed
[TTI][TLI][NFC] Add 'OffsetIsScalable' to isLegalAddressingMode
Adds a new parameter to the TTI version of the function, along with a matching field in the struct for TLI. This extra bool just indicates that the BaseOffset should be treated as a scalable quantity (meaning that it should be multiplied by 'vscale' to get the real value at runtime).
1 parent ceb744e commit 04354d5

File tree

8 files changed

+71
-13
lines changed

8 files changed

+71
-13
lines changed

llvm/include/llvm/Analysis/TargetTransformInfo.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -710,8 +710,8 @@ class TargetTransformInfo {
710710
/// TODO: Handle pre/postinc as well.
711711
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
712712
bool HasBaseReg, int64_t Scale,
713-
unsigned AddrSpace = 0,
714-
Instruction *I = nullptr) const;
713+
unsigned AddrSpace = 0, Instruction *I = nullptr,
714+
int64_t ScalableOffset = 0) const;
715715

716716
/// Return true if LSR cost of C1 is lower than C2.
717717
bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
@@ -1839,7 +1839,8 @@ class TargetTransformInfo::Concept {
18391839
virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
18401840
int64_t BaseOffset, bool HasBaseReg,
18411841
int64_t Scale, unsigned AddrSpace,
1842-
Instruction *I) = 0;
1842+
Instruction *I,
1843+
int64_t ScalableOffset) = 0;
18431844
virtual bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
18441845
const TargetTransformInfo::LSRCost &C2) = 0;
18451846
virtual bool isNumRegsMajorCostOfLSR() = 0;
@@ -2300,9 +2301,9 @@ class TargetTransformInfo::Model final : public TargetTransformInfo::Concept {
23002301
}
23012302
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
23022303
bool HasBaseReg, int64_t Scale, unsigned AddrSpace,
2303-
Instruction *I) override {
2304+
Instruction *I, int64_t ScalableOffset) override {
23042305
return Impl.isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, Scale,
2305-
AddrSpace, I);
2306+
AddrSpace, I, ScalableOffset);
23062307
}
23072308
bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
23082309
const TargetTransformInfo::LSRCost &C2) override {

llvm/include/llvm/Analysis/TargetTransformInfoImpl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,8 @@ class TargetTransformInfoImplBase {
220220

221221
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
222222
bool HasBaseReg, int64_t Scale, unsigned AddrSpace,
223-
Instruction *I = nullptr) const {
223+
Instruction *I = nullptr,
224+
int64_t ScalableOffset = 0) const {
224225
// Guess that only reg and reg+reg addressing is allowed. This heuristic is
225226
// taken from the implementation of LSR.
226227
return !BaseGV && BaseOffset == 0 && (Scale == 0 || Scale == 1);

llvm/include/llvm/CodeGen/BasicTTIImpl.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,13 +333,15 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
333333
}
334334

335335
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
336-
bool HasBaseReg, int64_t Scale,
337-
unsigned AddrSpace, Instruction *I = nullptr) {
336+
bool HasBaseReg, int64_t Scale, unsigned AddrSpace,
337+
Instruction *I = nullptr,
338+
int64_t ScalableOffset = 0) {
338339
TargetLoweringBase::AddrMode AM;
339340
AM.BaseGV = BaseGV;
340341
AM.BaseOffs = BaseOffset;
341342
AM.HasBaseReg = HasBaseReg;
342343
AM.Scale = Scale;
344+
AM.ScalableOffset = ScalableOffset;
343345
return getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace, I);
344346
}
345347

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2733,6 +2733,7 @@ class TargetLoweringBase {
27332733
int64_t BaseOffs = 0;
27342734
bool HasBaseReg = false;
27352735
int64_t Scale = 0;
2736+
int64_t ScalableOffset = 0;
27362737
AddrMode() = default;
27372738
};
27382739

llvm/lib/Analysis/TargetTransformInfo.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,9 +403,10 @@ bool TargetTransformInfo::isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
403403
int64_t BaseOffset,
404404
bool HasBaseReg, int64_t Scale,
405405
unsigned AddrSpace,
406-
Instruction *I) const {
406+
Instruction *I,
407+
int64_t ScalableOffset) const {
407408
return TTIImpl->isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg,
408-
Scale, AddrSpace, I);
409+
Scale, AddrSpace, I, ScalableOffset);
409410
}
410411

411412
bool TargetTransformInfo::isLSRCostLess(const LSRCost &C1,

llvm/lib/CodeGen/TargetLoweringBase.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2011,6 +2011,10 @@ bool TargetLoweringBase::isLegalAddressingMode(const DataLayout &DL,
20112011
// The default implementation of this implements a conservative RISCy, r+r and
20122012
// r+i addr mode.
20132013

2014+
// Scalable offsets not supported
2015+
if (AM.ScalableOffset)
2016+
return false;
2017+
20142018
// Allows a sign-extended 16-bit immediate field.
20152019
if (AM.BaseOffs <= -(1LL << 16) || AM.BaseOffs >= (1LL << 16)-1)
20162020
return false;

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16673,11 +16673,11 @@ bool AArch64TargetLowering::isLegalAddressingMode(const DataLayout &DL,
1667316673
if (isa<ScalableVectorType>(Ty)) {
1667416674
uint64_t VecElemNumBytes =
1667516675
DL.getTypeSizeInBits(cast<VectorType>(Ty)->getElementType()) / 8;
16676-
return AM.HasBaseReg && !AM.BaseOffs &&
16676+
return AM.HasBaseReg && !AM.BaseOffs && !AM.ScalableOffset &&
1667716677
(AM.Scale == 0 || (uint64_t)AM.Scale == VecElemNumBytes);
1667816678
}
1667916679

16680-
return AM.HasBaseReg && !AM.BaseOffs && !AM.Scale;
16680+
return AM.HasBaseReg && !AM.BaseOffs && !AM.ScalableOffset && !AM.Scale;
1668116681
}
1668216682

1668316683
// check reg + imm case:

llvm/unittests/Target/AArch64/AddressingModes.cpp

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@ using namespace llvm;
1313
namespace {
1414

1515
struct AddrMode : public TargetLowering::AddrMode {
16-
constexpr AddrMode(GlobalValue *GV, int64_t Offs, bool HasBase, int64_t S) {
16+
constexpr AddrMode(GlobalValue *GV, int64_t Offs, bool HasBase, int64_t S,
17+
int64_t SOffs = 0) {
1718
BaseGV = GV;
1819
BaseOffs = Offs;
1920
HasBaseReg = HasBase;
2021
Scale = S;
22+
ScalableOffset = SOffs;
2123
}
2224
};
2325
struct TestCase {
@@ -153,6 +155,45 @@ const std::initializer_list<TestCase> Tests = {
153155
{{nullptr, 4096 + 1, true, 0}, 8, false},
154156

155157
};
158+
159+
struct SVETestCase {
160+
AddrMode AM;
161+
unsigned TypeBits;
162+
unsigned NumElts;
163+
bool Result;
164+
};
165+
166+
const std::initializer_list<SVETestCase> SVETests = {
167+
// {BaseGV, BaseOffs, HasBaseReg, Scale, SOffs}, EltBits, Count, Result
168+
// Test immediate range -- [-8,7] vector's worth.
169+
// <vscale x 16 x i8>, increment by one vector
170+
{{nullptr, 0, true, 0, 16}, 8, 16, false},
171+
// <vscale x 4 x i32>, increment by eight vectors
172+
{{nullptr, 0, true, 0, 128}, 32, 4, false},
173+
// <vscale x 8 x i16>, increment by seven vectors
174+
{{nullptr, 0, true, 0, 112}, 16, 8, false},
175+
// <vscale x 2 x i64>, decrement by eight vectors
176+
{{nullptr, 0, true, 0, -128}, 64, 2, false},
177+
// <vscale x 16 x i8>, decrement by nine vectors
178+
{{nullptr, 0, true, 0, -144}, 8, 16, false},
179+
180+
// Half the size of a vector register, but allowable with extending
181+
// loads and truncating stores
182+
// <vscale x 8 x i8>, increment by three vectors
183+
{{nullptr, 0, true, 0, 24}, 8, 8, false},
184+
185+
// Test invalid types or offsets
186+
// <vscale x 5 x i32>, increment by one vector (base size > 16B)
187+
{{nullptr, 0, true, 0, 20}, 32, 5, false},
188+
// <vscale x 8 x i16>, increment by half a vector
189+
{{nullptr, 0, true, 0, 8}, 16, 8, false},
190+
// <vscale x 3 x i8>, increment by 3 vectors (non-power-of-two)
191+
{{nullptr, 0, true, 0, 9}, 8, 3, false},
192+
193+
// Scalable and fixed offsets
194+
// <vscale x 16 x i8>, increment by 32 then decrement by vscale x 16
195+
{{nullptr, 32, true, 0, -16}, 8, 16, false},
196+
};
156197
} // namespace
157198

158199
TEST(AddressingModes, AddressingModes) {
@@ -179,4 +220,11 @@ TEST(AddressingModes, AddressingModes) {
179220
Type *Typ = Type::getIntNTy(Ctx, Test.TypeBits);
180221
ASSERT_EQ(TLI->isLegalAddressingMode(DL, Test.AM, Typ, 0), Test.Result);
181222
}
223+
224+
for (const auto &SVETest : SVETests) {
225+
Type *Ty = VectorType::get(Type::getIntNTy(Ctx, SVETest.TypeBits),
226+
ElementCount::getScalable(SVETest.NumElts));
227+
ASSERT_EQ(TLI->isLegalAddressingMode(DL, SVETest.AM, Ty, 0),
228+
SVETest.Result);
229+
}
182230
}

0 commit comments

Comments
 (0)