【发布时间】:2014-07-20 19:57:04
【问题描述】:
以下 LLVM 函数采用三个指向五个双精度数组的指针并计算 C = A*B + C:
define void @my_vector_math(double* %A1, double* %B2, double* %C3) {
entry:
%0 = bitcast double* %C3 to <5 x double>*
%1 = load <5 x double>* %0, align 64
%2 = bitcast double* %B2 to <5 x double>*
%3 = load <5 x double>* %2, align 64
%4 = bitcast double* %A1 to <5 x double>*
%5 = load <5 x double>* %4, align 64
%6 = fmul <5 x double> %3, %5
%7 = fadd <5 x double> %1, %6
store <5 x double> %7, <5 x double>* %0, align 64
ret void
}
它在我的机器上编译成以下程序集(64 位 Ubuntu 13.10,LLVM 3.4):
30: c5 fb 10 42 20 vmovsd 0x20(%rdx),%xmm0
35: c5 fb 10 4e 20 vmovsd 0x20(%rsi),%xmm1
3a: c5 fd 28 16 vmovapd (%rsi),%ymm2
3e: c5 fb 10 5f 20 vmovsd 0x20(%rdi),%xmm3
43: c5 f5 59 cb vmulpd %ymm3,%ymm1,%ymm1
47: c5 ed 59 17 vmulpd (%rdi),%ymm2,%ymm2
4b: c5 fd 58 c1 vaddpd %ymm1,%ymm0,%ymm0
4f: c5 ed 58 0a vaddpd (%rdx),%ymm2,%ymm1
53: c5 fd 29 0a vmovapd %ymm1,(%rdx)
57: c5 f9 13 42 20 vmovlpd %xmm0,0x20(%rdx)
5c: c5 f8 77 vzeroupper
5f: c3 retq
使用大小为 5 的数组调用时,它总是会出现段错误,但有时会在使用过大的数组时产生正确的结果:
int main() {
double A[] = {1,1,1,1,1};
double B[] = {2,2,2,2,2};
double C[] = {3,3,3,3,3};
my_vector_math(A, B, C); // Segfaults
for (int i = 0; i < 5; i++) {
printf("%f\n",C[i]);
}
return 0;
}
我很难弄清楚为什么会发生这种情况,任何指针都将不胜感激。
编辑:
没有经过任何优化的 LLVM IR:
define void @my_vector_math(double* %A1, double* %B2, double* %C3) {
entry:
%a = alloca <5 x double>
%b = alloca <5 x double>
%c = alloca <5 x double>
%C = alloca double*
%B = alloca double*
%A = alloca double*
store double* %A1, double** %A
store double* %B2, double** %B
store double* %C3, double** %C
%C4 = load double** %C
%0 = bitcast double* %C4 to <5 x double>*
%1 = load <5 x double>* %0
store <5 x double> %1, <5 x double>* %c
%B5 = load double** %B
%2 = bitcast double* %B5 to <5 x double>*
%3 = load <5 x double>* %2
store <5 x double> %3, <5 x double>* %b
%A6 = load double** %A
%4 = bitcast double* %A6 to <5 x double>*
%5 = load <5 x double>* %4
store <5 x double> %5, <5 x double>* %a
%c7 = load <5 x double>* %c
%a8 = load <5 x double>* %a
%b9 = load <5 x double>* %b
%6 = fmul <5 x double> %a8, %b9
%7 = fadd <5 x double> %c7, %6
%C10 = load double** %C
%8 = bitcast double* %C10 to <5 x double>*
store <5 x double> %7, <5 x double>* %8
ret void
}
【问题讨论】:
标签: segmentation-fault llvm x86-64 vectorization