LLVMでSSE組み込み関数を使う
現在LLVMがマイブームである。今日ふと思い立ってSSE組み込み関数が含まれたC++のコードがllvm-g++でどのように変換されるのか試してみた。元のC++ソースコードは以下の通り。
#include <nmmintrin.h> void add(float* x, float* y, float*z) { _mm_storeu_ps(z, _mm_add_ps(_mm_loadu_ps(x), _mm_loadu_ps(y))); }
そして変換後のLLVMのコードが以下の通り。
; ModuleID = 'sse.cpp' target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" target triple = "i386-mingw32" define void @_Z3addPfS_S_(float* %x, float* %y, float* %z) nounwind { entry: %0 = bitcast float* %y to i8* ; <i8*> [#uses=1] %1 = tail call <4 x float> @llvm.x86.sse.loadu.ps(i8* %0) nounwind readonly ; <<4 x float>> [#uses=1] %2 = bitcast float* %x to i8* ; <i8*> [#uses=1] %3 = tail call <4 x float> @llvm.x86.sse.loadu.ps(i8* %2) nounwind readonly ; <<4 x float>> [#uses=1] %tmp.i = fadd <4 x float> %3, %1 ; <<4 x float>> [#uses=1] %4 = bitcast float* %z to i8* ; <i8*> [#uses=1] tail call void @llvm.x86.sse.storeu.ps(i8* %4, <4 x float> %tmp.i) nounwind ret void } declare <4 x float> @llvm.x86.sse.loadu.ps(i8*) nounwind readonly declare void @llvm.x86.sse.storeu.ps(i8*, <4 x float>) nounwind
_mm_loadu_ps()等が組み込み関数やベクトル演算に変換されているのがわかる。さすがLLVMだ。