2015-12-21 4 views
7

レジスタに渡されるのは、自明ではないコピー・ctorと重要でないdtorのない小さな構造体です。 ARM Procedural Call Standardを引用値で簡単な構造体を渡すときにgccが不要なメモリアクセスを発行するのはなぜですか?

:32ビットよりも大きい

基本タイプがパラメータとして渡される、または関数呼び出しの結果として返されてもよいです。 これらのタイプがコアレジスタにある場合、次のルールが適用されます。  ダブルワードサイズのタイプは、2つの連続するレジスタ(たとえばr0とr1、またはr2とr3)に渡されます。 の内容は、値が単一のLDM命令でメモリ表現からロードされたかのようです。

実際、これはclangで簡単に確認できます。 GCCは、しかし、そのような単純なコードスニペットのためのメモリ・ロードとストアの束を発する:

struct Trivial { 
    int i1; 
    int i2; 
}; 

int foo(Trivial t) 
{ 
    return t.i1 + t.i2; 
} 

$ clang++ arm.cpp -O2 -mabi=aapcs -c -S && cat arm.s 

add r0, r0, r1 
bx lr 

$ g++ arm.cpp -O2 -mabi=aapcs -c -S && cat arm.s 

sub  sp, sp, #8 
add  r3, sp, #8 
stmdb r3, {r0, r1} 
ldmia sp, {r0, r3} 
add  r0, r0, r3 
add  sp, sp, #8 
bx  lr 

Iが実行中、ArchlinuxARMディストリビューションによって供給されるGCCと打ち鳴らすを使用していラズベリー・パイ2(gcc 5.2)でも、gccベースのクロス・コンパイラでも再現しました。

+1

「-O3」でもう一度試してください –

+3

gccの_missed optimization_ typeバグのようなものです。 @MM FYI、それは '-O3'と同じです – Jester

+0

これは少し残念です...私はそれがそれよりもうまくいくと予想しました。 –

答えて

2

これはgccバグhereとして確認されました。

関連する問題