[llvm-bugs] [Bug 28726] New: std::pair<int, float> are combined as an int64 first before being stored to memory
via llvm-bugs
llvm-bugs at lists.llvm.org
Tue Jul 26 18:06:07 PDT 2016
https://llvm.org/bugs/show_bug.cgi?id=28726
Bug ID: 28726
Summary: std::pair<int, float> are combined as an int64 first
before being stored to memory
Product: libraries
Version: trunk
Hardware: PC
OS: All
Status: NEW
Severity: normal
Priority: P
Component: Scalar Optimizations
Assignee: unassignedbugs at nondot.org
Reporter: wmi at google.com
CC: llvm-bugs at lists.llvm.org
Classification: Unclassified
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.
--
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/20160727/7c063f3b/attachment.html>
More information about the llvm-bugs
mailing list