[LLVMbugs] [Bug 23108] New: Potential bad code generation with TLS and PowerPC

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Thu Apr 2 16:10:43 PDT 2015


https://llvm.org/bugs/show_bug.cgi?id=23108

            Bug ID: 23108
           Summary: Potential bad code generation with TLS and PowerPC
           Product: new-bugs
           Version: 3.5
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: matt.davis at pgroup.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

Hello,

I have discovered a potential inconsistency with LLVM and TLS code generation
for PowerPC, specifically Power8.

This test program exists as two object files,
test.o which references an external TLS variable "y", which belongs to
test_a.o. 
These two .o files are linked together to create my test application. I am not
compiling this example with -relocation-model=pic

The variable in question, "y", is located in the initialized data section of
the
resulting executable.  Now, on to my issue:

I have an external TLS integer variable, "y" which is declared as the following
from my test.c source file.
    @y = external thread_local global i32 ,section ".comm" , align 4


When my code first tries to access this external variable, my compiler emits
the following
code sequence in llvm to access and then add the value of another int to 'y':
Build:
    llc ./test.ll -mcpu=native -o ./test.s
Result: 
    %41 = load i32* @y, align 4, !dbg !20
    ...
    %57 = add i32 %41, %56, !dbg !20


This generates the following asm:
Build:
    /usr/bin/as ./test.s -mpower8 -o test.o
Result:
    ld 0, y at got@tprel at l(6)
    addis 7, 2, x at got@tprel at ha
    lwz 30, -120(1)                 
    lwz 29, -116(1)
    add 28, 0, y at tls                
    lwz 0, -96(1)
    lwz 28, 0(28)
    ld 27, x at got@tprel at l(7)
    lwz 26, -76(1)
    lwz 25, -80(1)                  
    lwz 24, -84(1)
    lwz 23, -88(1)
    add 26, 26, 25


Since GNU-ld can manipulate TLS instructions (for optimization purposes) the
following is the resulting object code after linking:
    <+360>:   addis   r7,r13,0
    <+364>:   lwz     r8,-112(r1)
    <+368>:   lwz     r11,-124(r1)
    <+372>:   addi    r7,r7,-28664
    <+376>:   lwz     r12,0(r7)
    <+380>:   addis   r0,r13,0
    <+384>:   nop
    <+388>:   lwz     r30,-120(r1)
    <+392>:   lwz     r29,-116(r1)
    <+396>:   li      r28,-28668
    <+400>:   lwz     r0,-96(r1)
    <+404>:   lwz     r28,0(r28)

What concerns me, and is causing a segfault is offset +396 to +400.  
The linker transforms the asm to object code:
     add 28, 0, y at tls transformed--> li r28,-28668

The following lwz at +404 in the object code will try to load r28 (which is a
negative value/not-an-address).  This segfaults my application.

Looking at the Power8 ABI for TLS and the specific "add 28, 0, y at tls"
instruction.
1) This appears to be the following relocation: R_PPC64_TLS  (y + 0)
2) The Power8 ABI specifies that the "add" and "r9" registers are to be used.
   It is not clear to me if the explicit register values as noted in the ABI
   have to be used, but it would seem that way.

I have noticed there appears to be a clobber of a register if I specify PIC
compilation.

So is there a code generation fault on behalf of LLVM, or is there something I
have missed?

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20150402/17de1d39/attachment.html>


More information about the llvm-bugs mailing list