<html>
<head>
<base href="https://llvm.org/bugs/" />
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW --- - std::pair<int, float> are combined as an int64 first before being stored to memory"
href="https://llvm.org/bugs/show_bug.cgi?id=28726">28726</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>std::pair<int, float> are combined as an int64 first before being stored to memory
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Scalar Optimizations
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>wmi@google.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>testcase 1.cc
------------------------------------------------------
#include <utility>
void goo(const std::pair<int, float> &pr);
void foo(int index_offset, int i, float dsqs[]) {
float tmp = dsqs[0] + 3.0;
goo(std::make_pair(index_offset + i + 0, tmp));
asm volatile ("":::"memory");
}
------------------------------------------------------
The last asm stmt is to prevent llvm from doing tail call opt (gcc doesn't do
tail call opt), so as to make instructions comparison between llvm and gcc a
little easier.
~/workarea/gcc-r233722/build/install/bin/g++ -O2 -S 1.cc
gcc code:
.cfi_startproc
subq $24, %rsp
.cfi_def_cfa_offset 32
addl %esi, %edi
movss .LC0(%rip), %xmm0
movl %edi, (%rsp)
movq %rsp, %rdi
addss (%rdx), %xmm0
movss %xmm0, 4(%rsp)
call _Z3gooRKSt4pairIifE
addq $24, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc
~/workarea/llvm-r275818/dbuild/bin/clang++ -O2 -S 1.cc
llvm code:
.cfi_startproc
# BB#0: # %entry
pushq %rax
.Ltmp0:
.cfi_def_cfa_offset 16
movss (%rdx), %xmm0 # xmm0 = mem[0],zero,zero,zero
addss .LCPI0_0(%rip), %xmm0
movd %xmm0, %eax
addl %esi, %edi
shlq $32, %rax
orq %rax, %rdi
movq %rdi, (%rsp)
leaq (%rsp), %rdi
callq _Z3gooRKSt4pairIifE
popq %rax
retq
gcc generates two instructions less than llvm.
>From asm code, we can see that llvm tries to bundle an int and a float into a
int64 and store the int64 into memory. It is better to save int and float into
memory using separate stores so the bitwise instructions to generate the int64
can be removed.
The bitwise instructions to generate the int64 bundle are generated by SROA for
std::make_pair, but I think SROA generates correct code there because frontend
already uses i64 as the return type of std::make_pair. Since SROA for
std::make_pair is done before std::make_pair is inlined into foo, it is
impossible for SROA to know the i64 returned by std::make_pair has only been
used in a store.
The return value of std::make_pair has already been i64 from the very beginning
of llvm pipeline:
*** IR Dump After Module Verifier ***
define linkonce_odr i64 @_ZSt9make_pairIifESt4pairIT_T0_ES1_S2_(i32 %__x, float
%__y) local_unnamed_addr #3 comdat {
...
}
I guess it is instcombine to be enhanced to split the int64 store because it
can see the combined int64 value has not been used elsewhere other than in the
store after std::make_pair is inlined.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>