[cfe-dev] libc++ std::cout alignment trouble (was: Re: [llvm] r240144 - [SLP] Vectorize for all-constant entries.)

Dimitry Andric via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 3 07:56:24 PST 2016

On 01 Jan 2016, at 00:07, James Y Knight <jyknight at google.com> wrote:
> On Dec 31, 2015, at 5:03 AM, Dimitry Andric via cfe-dev <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>> wrote:
>> This thread unfortunately died out without any resolution, so we are now
>> nearing 3.8 branching, and the problem is still not fixed.  E.g., the
>> only custom patch we have now left in FreeBSD's version of llvm (which
>> we would really like to get rid of!) is the reversal of r240144: it is a
>> pretty gross workaround, but it works for now.
>> But is there any way that we can get this resolved before 3.8.0 ships,
>> please? :-)
> I believe the summary of the thread is that LLVM has a fundamentally unsound transformation: automatically increasing the required alignment of an externally visible global variable.

Yes, and also that it ignores (or silently drops) an attribute added by the developer, e,g.:

__attribute__((__aligned__(8))) char cout[sizeof(ostream)];

gets transformed into:

@cout = global [24 x i8] zeroinitializer, align 16

> In enforceKnownAlignment in lib/Transforms/Utils/Local.cpp, it checks isStrongDefinitionForLinker() purportedly to ensure that the "memory we set aside for the global" is "the memory used by the final program.". However, even if said predicate returns true, that condition is NOT guaranteed, at least on ELF platforms, because of copy relocations.

Ah yes, I get what you mean.  When isStrongDefinitionForLinker() returns false in this case, the code falls through to the default global object handling code below there, which attempts to increase the alignment the the preferred alignment.  One thing I don't completely understand though, is the comment slightly below it:

    // We can only increase the alignment of the global if it has no alignment
    // specified or if it is not assigned a section.  If it is assigned a
    // section, the global could be densely packed with other objects in the
    // section, increasing the alignment could cause padding issues.
    if (!GO->hasSection() || GO->getAlignment() == 0) {

However, the object certainly does have a specified alignment.  So how is that supposed to work, then? :)

> (There's also very similar-looking alignment-fixing code in CodeGenPrepare::optimizeCallInst, too, I'm not sure why it's duplicated there.)
> Basically, we need to not modify the alignment if:
> if (Subtarget->isTargetELF() &&
>     TM.getRelocationModel() == Reloc::PIC_ &&
>     GV->hasDefaultVisibility() && !GV->hasLocalLinkage())
> The above code snippet appears in X86FastISel.cpp, and equivalent-but-not-identical code appears in several other places, to determine whether a PLT load for the variable is required.
> I'm not sure if isStrongDefinitionForLinker itself ought to be taking that into account, or if there should be a different new predicate for that check. isReallyActuallyTrulyStrongDefinitionForLinker()? :)

It is probably safest to use a new predicate, since isStrongDefinitionForLinker() is called all over the place, also in target-dependent code.  Or does this really apply to everything with ELF?  I mean, is the above set of conditions callable in the context of isStrongDefinitionForLinker()?


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160103/c40ce3d4/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 194 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160103/c40ce3d4/attachment.sig>

More information about the llvm-commits mailing list