Bug 78936 - Interprocedural constant propagation miscompiles C++ methods on i686 Windows
Summary: Interprocedural constant propagation miscompiles C++ methods on i686 Windows
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 6.2.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-12-27 23:45 UTC by Reid Kleckner
Modified: 2017-03-27 09:46 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Reid Kleckner 2016-12-27 23:45:16 UTC
The following test case has an issue where some interprocedural optimziation in GCC 6.2.0 appears to have mixed up the calling convention of a C++ thiscall method:
https://drive.google.com/open?id=0B5-KodWdXF4YZ1pVczVQX0tiOGM

When I compile the linked file like so, I get the following assembly snippets, which seem to corrupt the stack pointer:
$ g++ -O2 llvm-subtarget-emitter.cpp -S -o t.s

$ c++filt < t.s | less
...
(anonymous namespace)::SubtargetEmitter::EmitProcessorProp(llvm::raw_ostream&, llvm::Record const*, llvm::StringRef, char) [clone .constprop.544]:
...
        addl    $28, %esp
        .cfi_remember_state
        .cfi_def_cfa_offset 20
        popl    %ebx
        .cfi_restore 3
        .cfi_def_cfa_offset 16
        popl    %esi
        .cfi_restore 6
        .cfi_def_cfa_offset 12
        popl    %edi
        .cfi_restore 7
        .cfi_def_cfa_offset 8
        popl    %ebp
        .cfi_restore 5
        .cfi_def_cfa_offset 4
        ret
        .p2align 4,,10
...
(anonymous namespace)::SubtargetEmitter::EmitSchedModel(llvm::raw_ostream&):
...
        call    (anonymous namespace)::SubtargetEmitter::EmitProcessorProp(llvm::raw_ostream&, llvm::Record const*, llvm::StringRef, char) [clone .constprop.544]
        movl    28(%edi), %edx
        movl    8(%ebp), %eax
        subl    $8, %esp
        movl    $LC170, (%esp)
        movl    $17, 4(%esp)
        call    (anonymous namespace)::SubtargetEmitter::EmitProcessorProp(llvm::raw_ostream&, llvm::Record const*, llvm::StringRef, char) [clone .constprop.544]
        movl    28(%edi), %edx
        movl    8(%ebp), %eax
        subl    $8, %esp
...

Note that the "ret" instruction doesn't match the "sub $8, %esp" instructions after the call sites of SubtargetEmitter::EmitProcessorProp. The callee-cleanup property of the EmitProcessorProp clone seems to have been lost, or the call site hasn't been updated to treat it as a caller cleanup call.

This issue was encountered while building LLVM with the latest GCC provided by mingw-w64: http://lists.llvm.org/pipermail/cfe-dev/2016-December/051980.html

$ g++ --version
g++.exe (i686-posix-dwarf-rev1, Built by MinGW-W64 project) 6.2.0
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Comment 1 Alexandre Pereira Nunes 2017-01-23 18:17:38 UTC
Can you please try with -fno-delete-null-pointer-checks ?
Comment 2 Reid Kleckner 2017-01-23 18:48:13 UTC
That option does not appear to affect the linked portions of the assembly. The " [clone .constprop.544]" transform still appears to fire.

I will run the complete build and get back soon.
Comment 3 Reid Kleckner 2017-01-23 21:31:02 UTC
The compiled code still fails at runtime during an LLVM build in the same way.