使用-xSSE4.1标志进行分段错误

时间:2014-04-25 14:28:02

标签: alignment disassembly sse4 icc

我在运行使用-xSSE4.1 compilation-flag构建的可执行文件时遇到分段错误。我在支持SSE4.1,SSE4.2和AVX的机器上运行它。

给出分段错误的内在函数:

m_best_cost_0        = _mm_loadu_si128((__m128i *) &ps_mv_refine_ctxt->i2_tot_cost[0][0]);
m_2nd_best_cost_0    = _mm_loadu_si128((__m128i *) &ps_mv_refine_ctxt->i2_tot_cost[1][0]);

m_best_mv_cost_0     = _mm_loadu_si128((__m128i *) &ps_mv_refine_ctxt->i2_mv_cost[0][0]);
m_2nd_best_mv_cost_0 = _mm_loadu_si128((__m128i *) &ps_mv_refine_ctxt->i2_mv_cost[1][0]);

结构定义:

typedef struct
{
    __declspec(align(16)) WORD16 i2_tot_cost[2][TOT_NUM_PARTS];
    __declspec(align(16)) WORD16 i2_mv_cost[2][TOT_NUM_PARTS];
}mv_refine_ctxt;

TOT_NUM_PARTS是一个值为17的枚举,WORD16枚举为short int。

gdb中的“layout asm”命令显示内部代码段被转换为:

1   ¦0x5cbfec <hme_calc_sad_and_result_num_part_lt_9+108>    mov    0x98(%rdi),%r11                           ¦
2   ¦0x5cbff3 <hme_calc_sad_and_result_num_part_lt_9+115>    mov    0x20(%r12),%r14                           ¦
3   ¦0x5cbff8 <hme_calc_sad_and_result_num_part_lt_9+120>    movslq 0x14(%r12),%rdx                           ¦
4   ¦0x5cbffd <hme_calc_sad_and_result_num_part_lt_9+125>    movslq %eax,%rax                                 ¦
5   ¦0x5cc000 <hme_calc_sad_and_result_num_part_lt_9+128>    movslq %r15d,%r15                                ¦
6   ¦0x5cc003 <hme_calc_sad_and_result_num_part_lt_9+131>    movdqa (%r10),%xmm2                              ¦
7  >¦0x5cc008 <hme_calc_sad_and_result_num_part_lt_9+136>    movdqa 0x22(%r10),%xmm7                          ¦
8   ¦0x5cc00e <hme_calc_sad_and_result_num_part_lt_9+142>    movdqu 0x50(%r10),%xmm11                         ¦
9   ¦0x5cc014 <hme_calc_sad_and_result_num_part_lt_9+148>    movdqu 0x72(%r10),%xmm6 

第7行:

0x5cc008 <hme_calc_sad_and_result_num_part_lt_9+136> movdqa 0x22(%r10),%xmm7

给我一​​个分段错误。

在执行第6行之前,$ r10的值为0x7fffd4f22fe0;这是一个16字节对齐的地址,因此第6行执行没有问题。但是第7行从(0x7fffd4f22fe0 + 0x22)地址加载,该地址不是16字节对齐的。 此外,gdb将&ps_mv_refine_ctxt->i2_tot_cost[0][0]的值打印为0x7fffd4f22fe0,即$ r10。

我关注的是前两个_mm_loadu_si128 movdqu 时被转换为 movdqa 的原因。

当我使用-xSSE4.2或-xAVX编译标志构建时,相同的可执行文件,所有四条_mm_loadu_si128指令都被转换为 movdqu ,因此没有问题。此问题仅在release-build(-O3标志)中可见。

我正在使用英特尔C / C ++编译器。我觉得__declspec(align(16))在结构定义中是不必要的。但它不会导致这种奇怪的行为(通过删除它来测试并发现行为没有变化)。

对不起,很长的帖子。认为这些细节是必要的。

0 个答案:

没有答案