This is an archive of the discontinued LLVM Phabricator instance.

[TLS] Clamp the alignment of TLS global variables if required by the target
ClosedPublic

Authored by wolfgangp on Dec 15 2022, 10:49 AM.

Details

Summary

Some platforms (e.g. Playstation) limit the alignment of TLS variables (and the sections they're in). It's possible for optimization passes such as the vectorizer to generate code that then requires the promotion of such variables to an alignment that exceeds the maximum. To address this we're suggesting to add a new component to the data layout string that contains the maximum alignment of TLS variables a target allows. This component uses the key 'T', as in ...-T256. In its absence the alignment of TLS variables remains unrestricted.

In this patch the Playstation platform is the only one that uses this component.

Apologies for the somewhat lengthy test case. It's the loop vectorizer pass we're mainly concerned with.

Diff Detail

Event Timeline

wolfgangp created this revision.Dec 15 2022, 10:49 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 15 2022, 10:49 AM
wolfgangp requested review of this revision.Dec 15 2022, 10:49 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 15 2022, 10:49 AM

What is the consequence of having excess alignment?

arsenm added inline comments.Dec 15 2022, 5:27 PM
clang/test/CodeGen/ps-datalayout.c
5 ↗(On Diff #483229)

clang/test/CodeGen/target-data.c has all the rest of these

arsenm added inline comments.Dec 15 2022, 5:29 PM
llvm/lib/Transforms/Utils/Local.cpp
1426–1427

Why wouldn't this be in GlobalObject::canIncreaseAlignment?

What is the consequence of having excess alignment?

In our case the ELF section with the variable was also aligned to 64 bytes and the OS refused to load the executable.

What is the consequence of having excess alignment?

In our case the ELF section with the variable was also aligned to 64 bytes and the OS refused to load the executable.

Isn't that case covered by GlobalObject::canIncreaseAlignment?

// It also has to either not have a section defined, or, not have
// alignment specified. (If it is assigned a section, the global
// could be densely packed with other objects in the section, and
// increasing the alignment could cause padding issues.)
if (hasSection() && getAlign())
  return false;

// On ELF platforms, we'
wolfgangp added inline comments.Dec 15 2022, 5:41 PM
llvm/lib/Transforms/Utils/Local.cpp
1426–1427

Why wouldn't this be in GlobalObject::canIncreaseAlignment?

The way I read it, canIncreaseAlignment() just answers the question whether the alignment of the object can be increased at all. It should be possible to increase the alignment of the TLS variable, just not beyond the max value.

I feel this is too specific and doesn't belong in the datalayout. I think a general maximum global alignment would make a bit more sense? I know very little about object formats

llvm/test/CodeGen/X86/tls-align.ll
61

You should be able to get a simpler patch out of any pass that calls getOrEnforceKnownAlignment (e.g. instcombine)

I feel this is too specific and doesn't belong in the datalayout. I think a general maximum global alignment would make a bit more sense? I know very little about object formats

Our platform is a little bit unusual in that the maximum TLS alignment is not the same as the maximum alignment for globals. We'd rather not constrain alignments any more than we have to.

I feel this is too specific and doesn't belong in the datalayout. I think a general maximum global alignment would make a bit more sense? I know very little about object formats

Another way would be to add an entry into the target options, perhaps. A little less general, but it doesn't look like other platforms suffer from this restriction.

wolfgangp updated this revision to Diff 487628.Jan 9 2023, 6:05 PM

Instead of using the data layout string, we're using a module flag instead to describe the maximum alignment of a TLS variable. This works for LTO as well. As a test case, we're using the instcombine pass to demonstrate that we don't align beyond the maximum.

probinson added inline comments.Jan 10 2023, 8:14 AM
clang/test/CodeGen/tls-maxalign-modflag.c
12–13

I'd feel better if these two lines were tied together. Maybe no practical difference but I think it makes the intent clearer.

Addressed a review comment regarding the clang test (tightening up the module flag check).

wolfgangp marked an inline comment as done.Jan 31 2023, 8:31 AM

ping...

I don't know if this can happen, but what about an LTO scenario with different values for the module flag? I seem to recall module flags needing to provide a merge policy? I might be remembering something else though.
If the result is "fail the compilation" that seems fine.

I don't know if this can happen, but what about an LTO scenario with different values for the module flag? I seem to recall module flags needing to provide a merge policy? I might be remembering something else though.
If the result is "fail the compilation" that seems fine.

Yeah, the module flag is created with behavior "Error" (the first parameter in addModuleFlag), so any conflicting values would cause a module link time error (at LTO time).

probinson accepted this revision.Jan 31 2023, 12:12 PM

LGTM, but you might give @arsenm another day before committing.

This revision is now accepted and ready to land.Jan 31 2023, 12:12 PM
This revision was landed with ongoing or failed builds.Feb 8 2023, 10:40 AM
This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptFeb 8 2023, 10:40 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript

Missing LangRef change?

Missing LangRef change?

Ping?

Missing LangRef change?

Ping?

Added a LangRef entry with 776b7499ea813c06b. There seems to be no separate section for module flags, so I added it to the entry on global variables.

no separate section for module flags

https://llvm.org/docs/LangRef.html#module-flags-metadata ?

That seems to be the description of the metadata for module flags, not the documentation of the flags themselves.

There are subsections for individual flags. Maybe we could mess with the markup to make that a bit more clear...