Skip to content

Commit 68ea630

Browse files
committed
[AArch64] Support scalable offsets with isLegalAddressingMode
Given a base register and a scalable offset (multiplied by vscale), return true if the offset corresponds to the valid range for the size of the vector type in memory; e.g. `[X0, #1, mul vl]`
1 parent 04354d5 commit 68ea630

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16671,6 +16671,16 @@ bool AArch64TargetLowering::isLegalAddressingMode(const DataLayout &DL,
1667116671

1667216672
if (Ty->isScalableTy()) {
1667316673
if (isa<ScalableVectorType>(Ty)) {
16674+
// See if we have a foldable vscale-based offset, for vector types which
16675+
// are either legal or smaller than the minimum; more work will be
16676+
// required if we need to consider addressing for types which need
16677+
// legalization by splitting.
16678+
uint64_t VecNumBytes = DL.getTypeSizeInBits(Ty).getKnownMinValue() / 8;
16679+
if (AM.HasBaseReg && !AM.BaseOffs && AM.ScalableOffset && !AM.Scale &&
16680+
(AM.ScalableOffset % VecNumBytes == 0) && VecNumBytes <= 16 &&
16681+
isPowerOf2_64(VecNumBytes))
16682+
return isInt<4>(AM.ScalableOffset / (int64_t)VecNumBytes);
16683+
1667416684
uint64_t VecElemNumBytes =
1667516685
DL.getTypeSizeInBits(cast<VectorType>(Ty)->getElementType()) / 8;
1667616686
return AM.HasBaseReg && !AM.BaseOffs && !AM.ScalableOffset &&
@@ -16680,6 +16690,10 @@ bool AArch64TargetLowering::isLegalAddressingMode(const DataLayout &DL,
1668016690
return AM.HasBaseReg && !AM.BaseOffs && !AM.ScalableOffset && !AM.Scale;
1668116691
}
1668216692

16693+
// No scalable offsets allowed for non-scalable types.
16694+
if (AM.ScalableOffset)
16695+
return false;
16696+
1668316697
// check reg + imm case:
1668416698
// i.e., reg + 0, reg + imm9, reg + SIZE_IN_BYTES * uimm12
1668516699
uint64_t NumBytes = 0;

llvm/unittests/Target/AArch64/AddressingModes.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,20 +167,20 @@ const std::initializer_list<SVETestCase> SVETests = {
167167
// {BaseGV, BaseOffs, HasBaseReg, Scale, SOffs}, EltBits, Count, Result
168168
// Test immediate range -- [-8,7] vector's worth.
169169
// <vscale x 16 x i8>, increment by one vector
170-
{{nullptr, 0, true, 0, 16}, 8, 16, false},
170+
{{nullptr, 0, true, 0, 16}, 8, 16, true},
171171
// <vscale x 4 x i32>, increment by eight vectors
172172
{{nullptr, 0, true, 0, 128}, 32, 4, false},
173173
// <vscale x 8 x i16>, increment by seven vectors
174-
{{nullptr, 0, true, 0, 112}, 16, 8, false},
174+
{{nullptr, 0, true, 0, 112}, 16, 8, true},
175175
// <vscale x 2 x i64>, decrement by eight vectors
176-
{{nullptr, 0, true, 0, -128}, 64, 2, false},
176+
{{nullptr, 0, true, 0, -128}, 64, 2, true},
177177
// <vscale x 16 x i8>, decrement by nine vectors
178178
{{nullptr, 0, true, 0, -144}, 8, 16, false},
179179

180180
// Half the size of a vector register, but allowable with extending
181181
// loads and truncating stores
182182
// <vscale x 8 x i8>, increment by three vectors
183-
{{nullptr, 0, true, 0, 24}, 8, 8, false},
183+
{{nullptr, 0, true, 0, 24}, 8, 8, true},
184184

185185
// Test invalid types or offsets
186186
// <vscale x 5 x i32>, increment by one vector (base size > 16B)

0 commit comments

Comments
 (0)