私はしばらくの間、これに頭を悩ませてきました。私はGCC4.4.4を使用しています(GCC 3.4.6、4.4.6、および4.6.3をチェックしました)。実行していた数学で問題が発生しました。この例を次の自己完結型プログラムにまとめました。
#include <stdio.h>
int main()
{
float something[4] = { 1.0f, 2.0f, 3.0f, 4.0f };
asm volatile
(
"movups %0, %%xmm0 \n\t"
"movups %%xmm0, %0 \n\t"
: "=m" (*something)
:
: "memory", "xmm0"
);
printf("%.0f %.0f %.0f %.0f\n",
something[0], something[1], something[2], something[3]);
return 0;
}
で簡単にコンパイル
gcc -msse -O -o something something.c
どういうわけか最初の配列要素が破損して失敗します(私が試したGCC 3.4.6を除いて...そこでは正常に動作します)。私の人生の間、ここで根本的に間違っているものを見ることはできません。
代わりに、問題のASMブロックを次のように変更します。
_mm_storeu_ps(something, _mm_loadu_ps(something));
それはうまくいきます。生成されたアセンブリコードを確認したところ、ASMブロックを含むバージョンには、SSE部分に至るまでのストア操作が1つ少ないことがわかりました。
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $64, %esp
movl $0x40000000, 52(%esp)
movl $0x40400000, 56(%esp)
movl $0x40800000, 60(%esp)
対より正確(組み込み関数を使用したコード):
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $64, %esp
movl $0x3f800000, 48(%esp)
movl $0x40000000, 52(%esp)
movl $0x40400000, 56(%esp)
movl $0x40800000, 60(%esp)
WTFは私またはGCCのどちらかで間違っていますか?
(これは、私が追跡した根本的な問題を示す、要約された簡潔な例です。ASMブロックとvolatileキーワードには理由がありますが、これらはすべて、私が置いている主な懸念事項に実際には対応していないようです。ここに転送します。)