https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79619

            Bug ID: 79619
           Summary: store via pointer obtained from alternate address
                    space offset 0 dropped
           Product: gcc
           Version: 6.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: roland at gnu dot org
                CC: rth at gcc dot gnu.org
  Target Milestone: ---
            Target: x86_64-elf

Given this test code:                          

void bug(void) {                                                                
    *(*(char*__seg_fs*)0) = 1;                                                  
}                                                                               

void nobug(void) {                                                              
    *(*(char*__seg_fs*)0) = 1;                                                  
    *(*(char*__seg_fs*)8) = 1;                                                  
}                                                                               

I get this:

        .text                                                                   
        .globl  bug                                                             
        .type   bug, @function                                                  
bug:                                                                            
.LFB0:                                                                          
        .cfi_startproc                                                          
        rep ret                                                                 
        .cfi_endproc                                                            
.LFE0:                                                                          
        .size   bug, .-bug                                                      
        .globl  nobug                                                           
        .type   nobug, @function                                                
nobug:                                                                          
.LFB1:                                                                          
        .cfi_startproc                                                          
        movq    %fs:0, %rax                                                     
        movb    $1, (%rax)                                                      
        movq    %fs:8, %rax                                                     
        movb    $1, (%rax)                                                      
        ret                                                                     
        .cfi_endproc                                                            
.LFE1:                                                                          
        .size   nobug, .-nobug                                                  
        .ident  "GCC: (GNU) 6.2.0"                                              


x86_64 GCC at -O1 or better silently elides the store in bug.  My guess is that
it's deciding *(TYPE __seg_fs*)0 constitutes a null pointer dereference and is
therefore UB so screw everybody.  But alternate-address-space 0 is not a null
pointer, it's just like any other alternate-address-space pointer value and
should not be treated specially.  (Except that if you wanted to "know" that the
target ABI is that %fs:0 == %fs.base, then you can optimize
(*(char*__seg_fs*)0)[n] accesses to direct "%fs:n"; LLVM does this for x86-64
glibc-based targets.  But that's a missed optimization opportunity unrelated to
this bug.)

But note how the mere presence of a different alternate-address-space reference
not at zero in the same function (nobug) makes it emit both stores!  Definitely
fishy.

Maybe related to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66768 but that's
beyond my ken.

Reply via email to