[llvm-bugs] [Bug 33640] New: Xcode 8 possible incorrect output

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Jun 29 06:06:17 PDT 2017


            Bug ID: 33640
           Summary: Xcode 8 possible incorrect output
           Product: clang
           Version: unspecified
          Hardware: Macintosh
                OS: MacOS X
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++
          Assignee: unassignedclangbugs at nondot.org
          Reporter: andreww at blackmagicdesign.com
                CC: dgregor at apple.com, llvm-bugs at lists.llvm.org

Created attachment 18731
  --> https://bugs.llvm.org/attachment.cgi?id=18731&action=edit
tar of code used to generate llvm-ir & asm

I realise this is not strictly clang's problem, it's more of an Xcode problem
as it appears to only affect Xcode 7.3.1 and greater.

I tried reproducing this with clang 3.3 through 4.0 and it appears to work
there :-)

I'm really asking for advice if what they are doing is legal or not as I can't
seem to determine from the ABI spec if this is ok.

What I am seeing is that for x86_64 asm, certain loads of adjacent 32-bit
values from a struct, in preparation for a function call, result in the 64 bit
registers not being truncated to 32-bits as the LLVM IR is instructing them to

For instance, the simple test program I have attached generates the following

; Function Attrs: norecurse optsize ssp uwtable
define i32 @main() local_unnamed_addr #0 {
  %1 = tail call i8* @malloc(i64 32) #3
  %2 = bitcast i8* %1 to <2 x i8*>*
  store <2 x i8*> <i8* inttoptr (i64 3735928559 to i8*), i8* inttoptr (i64
3735928559 to i8*)>, <2 x i8*>* %2, align 8, !tbaa !2
  %3 = getelementptr inbounds i8, i8* %1, i64 16
  %4 = getelementptr inbounds i8, i8* %1, i64 24
  %5 = bitcast i8* %3 to <4 x i32>*
  store <4 x i32> <i32 170, i32 187, i32 204, i32 221>, <4 x i32>* %5, align 8,
!tbaa !6
  %6 = bitcast i8* %3 to i64*
  %7 = load i64, i64* %6, align 8
  %8 = trunc i64 %7 to i32
  %9 = lshr i64 %7, 32
  %10 = trunc i64 %9 to i32
  %11 = bitcast i8* %4 to i64*
  %12 = load i64, i64* %11, align 8
  %13 = trunc i64 %12 to i32
  %14 = lshr i64 %12, 32
  %15 = trunc i64 %14 to i32
  tail call void @_Z4bar1PaS_iiiii(i8* inttoptr (i64 3735928559 to i8*), i8*
inttoptr (i64 3735928559 to i8*), i32 %8, i32 %10, i32 %13, i32 %15, i32 %15)
  ret i32 0

IIUC %7, %8, %9, & %10 should result in registers containing only the 32 bit
values from my struct.

The generated assembly tells a different story:

0000000000000000        pushq   %rbp
0000000000000001        movq    %rsp, %rbp
0000000000000004        subq    $0x10, %rsp
0000000000000008        movl    $0x20, %edi
000000000000000d        callq   0x12
0000000000000012        movaps  0x47(%rip), %xmm0
0000000000000019        movups  %xmm0, (%rax)
000000000000001c        movaps  0x4d(%rip), %xmm0
0000000000000023        movups  %xmm0, 0x10(%rax)
0000000000000027        movq    0x10(%rax), %rdx
000000000000002b        movq    0x18(%rax), %r8
000000000000002f        movq    %rdx, %rcx
0000000000000032        shrq    $0x20, %rcx
0000000000000036        movq    %r8, %r9
0000000000000039        shrq    $0x20, %r9
000000000000003d        movl    %r9d, (%rsp)
0000000000000041        movl    $0xdeadbeef, %edi
0000000000000046        movl    $0xdeadbeef, %esi
000000000000004b        callq   0x50
0000000000000050        xorl    %eax, %eax
0000000000000052        addq    $0x10, %rsp
0000000000000056        popq    %rbp
0000000000000057        retq

Registers r8 & rdx are left containing 2 32 bit values each when the function
call is made.  In the case of r8 it has a copy of r9 in the high bits and in
the case of rdx it has rcx in the high bits.

This is resulting in some wacky results in a called library which I can't
change, it may have been compiled with Intel's compiler and it does load %r8d
when accessing the 32-bit parameter as specified by its function signature, it
accesses %r8.

So, who is in the wrong here?  Should the caller be emitting clean 32-bit
registers over the x86_64 ABI or should the callee be accessing only the 32-bit
register aliases for those parameters specified as 32-bits?

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/20170629/806715c5/attachment.html>

More information about the llvm-bugs mailing list