[llvm-dev] Expected behavior of lld during LTO for global symbols (Attr Internal/Common)

Reid Kleckner via llvm-dev llvm-dev at lists.llvm.org
Thu Jun 20 08:53:36 PDT 2019


I believe this issue was already reported a month ago as
https://bugs.llvm.org/show_bug.cgi?id=41978. I assume that dependent
changes have landed and it is too late to revert now, but IMO this is a
regression, and would normally be enough cause to revert the change to LLD
(r360841), so please prioritize investigating this.

On Thu, Jun 20, 2019 at 6:18 AM Rui Ueyama via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> It seems that we do not at least set IsUsedInRegularObj for common symbols
> passed to LTO.
>
> On Tue, Jun 11, 2019 at 10:53 PM Teresa Johnson <tejohnson at google.com>
> wrote:
>
>> LTO can, but it is linker driven. I confirmed that when it is a common
>> symbol the resolution indicates that the symbol is exported, and when I add
>> an initializer so that it is a def we no longer think it is exported and
>> are able to internalize. So this seems to be due to a change in what the
>> linker is telling LTO. I would have to dig in the debugger to confirm, but
>> perhaps lld is now indicating that it might be used by a regular obj? I.e.
>> in BitcodeCompiler::add.
>>
>> Teresa
>>
>> On Tue, Jun 11, 2019 at 5:48 AM Rui Ueyama <ruiu at google.com> wrote:
>>
>>> Looks like this is indeed related to r360841.
>>>
>>> In C, there are distinctions between declarations, definitions and
>>> tentative definitions. Global variables declared with "extern" are
>>> declarations. Global variables that don't have "extern" and have
>>> initializers are definitions. If global variables have neither "extern" nor
>>> initializers, they are called tentative definitions.
>>>
>>> Common symbols represent tentative definitions.
>>>
>>> Tentative definition get special treatment in the linker. Usually if you
>>> define the same symbol in two object files, a linker report an error.
>>> However, common symbols are allowed to duplicate. Two or more common
>>> symbols are merged and then placed to the .bss section, so that they will
>>> be zero-initialized at runtime.
>>>
>>> So, a global variable defined as `struct Node* head` is actually a
>>> common symbol.
>>>
>>> I'm not sure why LTO cannot internalize common symbols though. Teresa,
>>> is this expected?
>>>
>>> On Mon, Jun 10, 2019 at 11:06 PM Teresa Johnson <tejohnson at google.com>
>>> wrote:
>>>
>>>> My guess is that it is due to lld change r360841 on that date
>>>> (Introduce CommonSymbol). +Rui for comments.
>>>>
>>>> On Mon, Jun 10, 2019 at 4:45 AM Mani, Suresh via llvm-dev <
>>>> llvm-dev at lists.llvm.org> wrote:
>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Hi ,
>>>>>
>>>>>
>>>>>
>>>>> I have an issue during LTO phase of llvm compiler which is as follows,
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> File t3.c
>>>>>
>>>>> ---------
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> #include <stdio.h>
>>>>>
>>>>> #include <stdlib.h>
>>>>>
>>>>>
>>>>>
>>>>> // A linked list node
>>>>>
>>>>> struct Node {
>>>>>
>>>>>     int data;
>>>>>
>>>>>     struct Node* next;
>>>>>
>>>>>     struct Node* prev;
>>>>>
>>>>> };
>>>>>
>>>>>
>>>>>
>>>>> *struct Node* head;*
>>>>>
>>>>>
>>>>>
>>>>> /* Given a reference (pointer to pointer) to the head of a list
>>>>>
>>>>> and an int, inserts a new node on the front of the list. */
>>>>>
>>>>> void push(struct Node** head_ref, int new_data)
>>>>>
>>>>> {
>>>>>
>>>>>     struct Node* new_node = (struct Node*)malloc(sizeof(struct
>>>>> Node));
>>>>>
>>>>>
>>>>>
>>>>>     new_node->data = new_data;
>>>>>
>>>>>
>>>>>
>>>>>     new_node->next = (*head_ref);
>>>>>
>>>>>     new_node->prev = NULL;
>>>>>
>>>>>
>>>>>
>>>>>     if ((*head_ref) != NULL)
>>>>>
>>>>>         (*head_ref)->prev = new_node;
>>>>>
>>>>>
>>>>>
>>>>>     (*head_ref) = new_node;
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> // This function prints contents of linked list starting from the
>>>>> given node
>>>>>
>>>>> void printList(struct Node* node)
>>>>>
>>>>> {
>>>>>
>>>>>     struct Node* last;
>>>>>
>>>>>     printf("\nTraversal in forward direction \n");
>>>>>
>>>>>     while (node != NULL) {
>>>>>
>>>>>         printf(" %d ", node->data);
>>>>>
>>>>>         last = node;
>>>>>
>>>>>         node = node->next;
>>>>>
>>>>>     }
>>>>>
>>>>>
>>>>>
>>>>>     printf("\nTraversal in reverse direction \n");
>>>>>
>>>>>     while (last != NULL) {
>>>>>
>>>>>         printf(" %d ", last->data);
>>>>>
>>>>>         last = last->prev;
>>>>>
>>>>>     }
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> /* Driver program to test above functions*/
>>>>>
>>>>> int main()
>>>>>
>>>>> {
>>>>>
>>>>>
>>>>>
>>>>>     head = NULL;
>>>>>
>>>>>     push(&head, 7);
>>>>>
>>>>>     push(&head, 1);
>>>>>
>>>>>     push(&head, 4);
>>>>>
>>>>>
>>>>>
>>>>>     printList(head);
>>>>>
>>>>>
>>>>>
>>>>>     return 0;
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Compiler invocation:
>>>>>
>>>>> --------------------
>>>>>
>>>>>
>>>>>
>>>>> clang -flto -fuse-ld=lld -O3 t3.c -o a.out
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Expected behavior during LTO:
>>>>>
>>>>> ------------------------------
>>>>>
>>>>>
>>>>>
>>>>> The compiler optimization during LTO needs to figure out that variable
>>>>> "head" is not referred by any precompiled object or library.
>>>>>
>>>>> Until May-16-2019 variable "head" had internal attribute as follows,
>>>>>
>>>>>
>>>>>
>>>>> @head = internal global %struct.Node* null, align 8
>>>>>
>>>>>
>>>>>
>>>>> And the compiler was rightly able to recognize that "head" is not
>>>>> referred by any external precompiled object or library.
>>>>>
>>>>>
>>>>>
>>>>> But after May-16-2019  the attribute of head was changed as follows,
>>>>>
>>>>>
>>>>>
>>>>> @head = common dso_local global %struct.Node* null, align 8
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Not sure if this is correct behavior?
>>>>>
>>>>>
>>>>>
>>>>> If this is a correct behavior then can you please let me know how
>>>>> could the compiler figure out that variable "head" is not referred by any
>>>>> external precompiled object or library?
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Thanks
>>>>>
>>>>> M Suresh
>>>>> _______________________________________________
>>>>> LLVM Developers mailing list
>>>>> llvm-dev at lists.llvm.org
>>>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>>>
>>>>
>>>>
>>>> --
>>>> Teresa Johnson |  Software Engineer |  tejohnson at google.com |
>>>>
>>>
>>
>> --
>> Teresa Johnson |  Software Engineer |  tejohnson at google.com |
>>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190620/b9687d36/attachment.html>


More information about the llvm-dev mailing list