Skip to content

Commit 053949d

Browse files
kasuga-fjshiltian
authored andcommitted
[LoopVectorize] Add test for follow-up metadata for loops (NFC) (#131337)
When pragma of loop transformations are encoded in LLVM IR, follow-up metadata is used if multiple transformations are specified. They are used to explicitly express the order of the transformations. However, they are not properly processed on each transformation pass, so now only the first one is attempted to be applied. This is a pre-commit to add a test that causes the problem. ref: #127474 (comment)
1 parent c53caae commit 053949d

File tree

5 files changed

+77
-19
lines changed

5 files changed

+77
-19
lines changed

clang/lib/Basic/Targets/AMDGPU.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ static const char *const DataLayoutStringR600 =
3232
"-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1";
3333

3434
static const char *const DataLayoutStringAMDGCN =
35-
"e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32"
36-
"-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:"
37-
"32-v48:64-v96:128"
35+
"e-p:64:64-p1:64:64-p2:32:32:32:32:f-p3:32:32:32:32:f-p4:64:64"
36+
"-p5:32:32:32:32:f-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32"
37+
"-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
3838
"-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1"
3939
"-ni:7:8:9";
4040

llvm/docs/LangRef.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3134,7 +3134,7 @@ as follows:
31343134
``A<address space>``
31353135
Specifies the address space of objects created by '``alloca``'.
31363136
Defaults to the default address space of 0.
3137-
``p[n]:<size>:<abi>[:<pref>][:<idx>]``
3137+
``p[<n>]:<size>:<abi>[:<pref>[:<idx>[:<sentinel>]]]``
31383138
This specifies the *size* of a pointer and its ``<abi>`` and
31393139
``<pref>``\erred alignments for address space ``n``. ``<pref>`` is optional
31403140
and defaults to ``<abi>``. The fourth parameter ``<idx>`` is the size of the
@@ -3143,7 +3143,10 @@ as follows:
31433143
specified, the default index size is equal to the pointer size. All sizes
31443144
are in bits. The address space, ``n``, is optional, and if not specified,
31453145
denotes the default address space 0. The value of ``n`` must be
3146-
in the range [1,2^24).
3146+
in the range [1,2^24). The fifth parameter ``<sentinel>`` specifies the
3147+
sentinel value of the pointer for the corresponding address space. It
3148+
currently accepts two values: ``0`` for an all-zero value and ``f`` for a
3149+
full-bit set value. The default sentinel pointer value is all-zero.
31473150
``i<size>:<abi>[:<pref>]``
31483151
This specifies the alignment for an integer type of a given bit
31493152
``<size>``. The value of ``<size>`` must be in the range [1,2^24).

llvm/include/llvm/IR/DataLayout.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class DataLayout {
7878
Align ABIAlign;
7979
Align PrefAlign;
8080
uint32_t IndexBitWidth;
81+
APInt SentinelValue;
8182
/// Pointers in this address space don't have a well-defined bitwise
8283
/// representation (e.g. may be relocated by a copying garbage collector).
8384
/// Additionally, they may also be non-integral (i.e. containing additional
@@ -148,7 +149,7 @@ class DataLayout {
148149
/// Sets or updates the specification for pointer in the given address space.
149150
void setPointerSpec(uint32_t AddrSpace, uint32_t BitWidth, Align ABIAlign,
150151
Align PrefAlign, uint32_t IndexBitWidth,
151-
bool IsNonIntegral);
152+
APInt SentinelValue, bool IsNonIntegral);
152153

153154
/// Internal helper to get alignment for integer of given bitwidth.
154155
Align getIntegerAlignment(uint32_t BitWidth, bool abi_or_pref) const;
@@ -552,6 +553,11 @@ class DataLayout {
552553
///
553554
/// This includes an explicitly requested alignment (if the global has one).
554555
Align getPreferredAlign(const GlobalVariable *GV) const;
556+
557+
/// Returns the sentinel pointer value for a given address space. If the
558+
/// address space is invalid, it defaults to the sentinel pointer value of
559+
/// address space 0, aligning with the behavior of \p getPointerSpec.
560+
APInt getSentinelPointerValue(unsigned AS) const;
555561
};
556562

557563
inline DataLayout *unwrap(LLVMTargetDataRef P) {

llvm/lib/IR/DataLayout.cpp

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ bool DataLayout::PointerSpec::operator==(const PointerSpec &Other) const {
152152
return AddrSpace == Other.AddrSpace && BitWidth == Other.BitWidth &&
153153
ABIAlign == Other.ABIAlign && PrefAlign == Other.PrefAlign &&
154154
IndexBitWidth == Other.IndexBitWidth &&
155+
SentinelValue == Other.SentinelValue &&
155156
IsNonIntegral == Other.IsNonIntegral;
156157
}
157158

@@ -206,9 +207,10 @@ constexpr DataLayout::PrimitiveSpec DefaultVectorSpecs[] = {
206207
};
207208

208209
// Default pointer type specifications.
209-
constexpr DataLayout::PointerSpec DefaultPointerSpecs[] = {
210-
// p0:64:64:64:64
211-
{0, 64, Align::Constant<8>(), Align::Constant<8>(), 64, false},
210+
const DataLayout::PointerSpec DefaultPointerSpecs[] = {
211+
// p0:64:64:64:64:0
212+
{0, 64, Align::Constant<8>(), Align::Constant<8>(), 64, APInt(64, 0),
213+
false},
212214
};
213215

214216
DataLayout::DataLayout()
@@ -296,6 +298,22 @@ static Error parseSize(StringRef Str, unsigned &BitWidth,
296298
return Error::success();
297299
}
298300

301+
static Error parseSentinelValue(StringRef Str, APInt &V) {
302+
if (Str.empty())
303+
return createStringError("sentinel value component cannot be empty");
304+
if (Str.size() != 1)
305+
return createStringError("sentinel value component must be a '0' or 'f'");
306+
if (Str[0] == '0') {
307+
V.clearAllBits();
308+
return Error::success();
309+
}
310+
if (Str[0] == 'f') {
311+
V.setAllBits();
312+
return Error::success();
313+
}
314+
return createStringError("sentinel value component must be a '0' or 'f'");
315+
}
316+
299317
/// Attempts to parse an alignment component of a specification.
300318
///
301319
/// On success, returns the value converted to byte amount in \p Alignment.
@@ -409,13 +427,14 @@ Error DataLayout::parseAggregateSpec(StringRef Spec) {
409427
}
410428

411429
Error DataLayout::parsePointerSpec(StringRef Spec) {
412-
// p[<n>]:<size>:<abi>[:<pref>[:<idx>]]
430+
// p[<n>]:<size>:<abi>[:<pref>[:<idx>[:<sentinel>]]]
413431
SmallVector<StringRef, 5> Components;
414432
assert(Spec.front() == 'p');
415433
Spec.drop_front().split(Components, ':');
416434

417-
if (Components.size() < 3 || Components.size() > 5)
418-
return createSpecFormatError("p[<n>]:<size>:<abi>[:<pref>[:<idx>]]");
435+
if (Components.size() < 3 || Components.size() > 6)
436+
return createSpecFormatError(
437+
"p[<n>]:<size>:<abi>[:<pref>[:<idx>[:<sentinel>]]]");
419438

420439
// Address space. Optional, defaults to 0.
421440
unsigned AddrSpace = 0;
@@ -454,8 +473,14 @@ Error DataLayout::parsePointerSpec(StringRef Spec) {
454473
return createStringError(
455474
"index size cannot be larger than the pointer size");
456475

476+
APInt SentinelValue(BitWidth, 0);
477+
if (Components.size() > 5) {
478+
if (Error Err = parseSentinelValue(Components[5], SentinelValue))
479+
return Err;
480+
}
481+
457482
setPointerSpec(AddrSpace, BitWidth, ABIAlign, PrefAlign, IndexBitWidth,
458-
false);
483+
SentinelValue, /*IsNonIntegral=*/false);
459484
return Error::success();
460485
}
461486

@@ -631,7 +656,7 @@ Error DataLayout::parseLayoutString(StringRef LayoutString) {
631656
// the spec for AS0, and we then update that to mark it non-integral.
632657
const PointerSpec &PS = getPointerSpec(AS);
633658
setPointerSpec(AS, PS.BitWidth, PS.ABIAlign, PS.PrefAlign, PS.IndexBitWidth,
634-
true);
659+
PS.SentinelValue, /*IsNonIntegral=*/true);
635660
}
636661

637662
return Error::success();
@@ -679,16 +704,19 @@ DataLayout::getPointerSpec(uint32_t AddrSpace) const {
679704

680705
void DataLayout::setPointerSpec(uint32_t AddrSpace, uint32_t BitWidth,
681706
Align ABIAlign, Align PrefAlign,
682-
uint32_t IndexBitWidth, bool IsNonIntegral) {
707+
uint32_t IndexBitWidth, APInt SentinelValue,
708+
bool IsNonIntegral) {
683709
auto I = lower_bound(PointerSpecs, AddrSpace, LessPointerAddrSpace());
684710
if (I == PointerSpecs.end() || I->AddrSpace != AddrSpace) {
685711
PointerSpecs.insert(I, PointerSpec{AddrSpace, BitWidth, ABIAlign, PrefAlign,
686-
IndexBitWidth, IsNonIntegral});
712+
IndexBitWidth, SentinelValue,
713+
IsNonIntegral});
687714
} else {
688715
I->BitWidth = BitWidth;
689716
I->ABIAlign = ABIAlign;
690717
I->PrefAlign = PrefAlign;
691718
I->IndexBitWidth = IndexBitWidth;
719+
I->SentinelValue = SentinelValue;
692720
I->IsNonIntegral = IsNonIntegral;
693721
}
694722
}
@@ -1020,3 +1048,10 @@ Align DataLayout::getPreferredAlign(const GlobalVariable *GV) const {
10201048
}
10211049
return Alignment;
10221050
}
1051+
1052+
APInt DataLayout::getSentinelPointerValue(unsigned AS) const {
1053+
auto I = lower_bound(PointerSpecs, AS, LessPointerAddrSpace());
1054+
if (I != PointerSpecs.end() || I->AddrSpace == AS)
1055+
return I->SentinelValue;
1056+
return PointerSpecs[0].SentinelValue;
1057+
}

llvm/unittests/IR/DataLayoutTest.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,11 +313,12 @@ TEST(DataLayout, ParsePointerSpec) {
313313
EXPECT_THAT_EXPECTED(DataLayout::parse(Str), Succeeded());
314314

315315
for (StringRef Str :
316-
{"p", "p0", "p:32", "p0:32", "p:32:32:32:32:32", "p0:32:32:32:32:32"})
316+
{"p", "p0", "p:32", "p0:32", "p:32:32:32:32:32:0", "p0:32:32:32:32:32:0"})
317317
EXPECT_THAT_EXPECTED(
318318
DataLayout::parse(Str),
319-
FailedWithMessage("malformed specification, must be of the form "
320-
"\"p[<n>]:<size>:<abi>[:<pref>[:<idx>]]\""));
319+
FailedWithMessage(
320+
"malformed specification, must be of the form "
321+
"\"p[<n>]:<size>:<abi>[:<pref>[:<idx>[:<sentinel>]]]\""));
321322

322323
// address space
323324
for (StringRef Str : {"p0x0:32:32", "px:32:32:32", "p16777216:32:32:32:32"})
@@ -401,6 +402,19 @@ TEST(DataLayout, ParsePointerSpec) {
401402
EXPECT_THAT_EXPECTED(
402403
DataLayout::parse(Str),
403404
FailedWithMessage("index size cannot be larger than the pointer size"));
405+
406+
// sentinel value
407+
for (StringRef Str :
408+
{"p:32:32:32:32:a", "p0:32:32:32:32:ab", "p42:32:32:32:32:123"})
409+
EXPECT_THAT_EXPECTED(
410+
DataLayout::parse(Str),
411+
FailedWithMessage("sentinel value component must be a '0' or 'f'"));
412+
413+
for (StringRef Str :
414+
{"p:32:32:32:32:", "p0:32:32:32:32:", "p42:32:32:32:32:"})
415+
EXPECT_THAT_EXPECTED(
416+
DataLayout::parse(Str),
417+
FailedWithMessage("sentinel value component cannot be empty"));
404418
}
405419

406420
TEST(DataLayoutTest, ParseNativeIntegersSpec) {

0 commit comments

Comments
 (0)