Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

Lowering of atomic ops doesn't reuse registers #18889

Open Quuxplusone opened 10 years ago

Quuxplusone commented 10 years ago
Bugzilla Link PR18890
Status NEW
Importance P normal
Reported by Jörg Sonnenberger (joerg@NetBSD.org)
Reported on 2014-02-18 17:50:39 -0800
Last modified on 2014-10-08 05:09:20 -0700
Version trunk
Hardware PC Linux
CC hfinkel@anl.gov, llvm-bugs@lists.llvm.org, morisset@google.com
Fixed by commit(s)
Attachments test.c (129 bytes, text/x-csrc)
pr18890.cpp (119 bytes, text/x-c++src)
pr18890.s (632 bytes, application/octet-stream)
Blocks
Blocked by
See also
Created attachment 12084
Test case

Compile the attached test program with -O2 for amd64. Observe that the assembly
is not using known zero value of %rax for the xchg, but creating a new register
for that purpose.

Problem applies to other __sync_* builtins as well.
Quuxplusone commented 10 years ago

Attached test.c (129 bytes, text/x-csrc): Test case

Quuxplusone commented 10 years ago

Attached pr18890.cpp (119 bytes, text/x-c++src): C++ test-case

Quuxplusone commented 10 years ago

Attached pr18890.s (632 bytes, application/octet-stream): Assembly generated by the C++ testcase

Quuxplusone commented 10 years ago

I don't think the problem here is specific to __sync builtins or to C++11 atomics. The issue appears to be that the backend works on a SelectionDAG at a time, and in particular does not see that a constant (here 0) has already been materialized in a register that is still available. I don't know exactly how to fix this, and I suspect it may be rather hard.

Quuxplusone commented 10 years ago
I don't think it is that simple, the backend normally catches things like this,
two possible problems are:
  1. xorl is marked 'as cheap as move', and thus does not trigger coalescing/CSE logic
  2. xorl x, x is not recognized as a constant materialization

As a first step, you might want to figure out why MachineCSE does not get this.