正如我在this question提出的,gcc正在刪除(是的,用-O0
)一行代碼_mm_div_ss(s1, s2);
,可能是因爲結果沒有保存。但是,這個應該觸發一個浮點異常,並提出SIGFPE,如果刪除該調用不會發生。gcc -O0仍然優化了「未使用」的代碼。有沒有編譯標誌來改變它?
問題:是否有一個標誌或多個標誌傳遞給gcc,以便代碼按原樣編譯?我在想像fno-remove-unused
,但我沒有看到類似的東西。理想情況下,這將是一個編譯器標誌,而不必更改我的源代碼,但如果不支持,那麼是否有一些gcc屬性/編譯指示可用?
事情我已經嘗試:
$ gcc --help=optimizers | grep -i remove
沒有結果。
$ gcc --help=optimizers | grep -i unused
沒有結果。
,並明確禁用所有死碼/消除標誌 - 注意,這是毫無無用的代碼警告:
$ gcc -O0 -msse2 -Wall -Wextra -pedantic -Winline \
-fno-dce -fno-dse -fno-tree-dce \
-fno-tree-dse -fno-tree-fre -fno-compare-elim -fno-gcse \
-fno-gcse-after-reload -fno-gcse-las -fno-rerun-cse-after-loop \
-fno-tree-builtin-call-dce -fno-tree-cselim a.c
a.c: In function ‘main’:
a.c:25:5: warning: ISO C90 forbids mixed declarations and code [-Wpedantic]
__m128 s1, s2;
^
$
源程序
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <xmmintrin.h>
static void sigaction_sfpe(int signal, siginfo_t *si, void *arg)
{
printf("%d,%d,%d\n", signal, si!=NULL?1:0, arg!=NULL?1:0);
printf("inside SIGFPE handler\nexit now.\n");
exit(1);
}
int main()
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = sigaction_sfpe;
sa.sa_flags = SA_SIGINFO;
sigaction(SIGFPE, &sa, NULL);
_mm_setcsr(0x00001D80);
__m128 s1, s2;
s1 = _mm_set_ps(1.0, 1.0, 1.0, 1.0);
s2 = _mm_set_ps(0.0, 0.0, 0.0, 0.0);
_mm_div_ss(s1, s2);
printf("done (no error).\n");
return 0;
}
編譯上述程序給出
$ ./a.out
done (no error).
更改線路
_mm_div_ss(s1, s2);
到
s2 = _mm_div_ss(s1, s2); // add "s2 = "
產生預期的結果:
$ ./a.out
inside SIGFPE handler
編輯更多的細節。
這似乎與_mm_div_ss
definition上的__always_inline__
屬性有關。
$ cat t.c
int
div(int b)
{
return 1/b;
}
int main()
{
div(0);
return 0;
}
$ gcc -O0 -Wall -Wextra -pedantic -Winline t.c -o t.out
$
(無警告或錯誤)
$ ./t.out
Floating point exception
$
VS下方(同樣除了功能屬性)
$ cat t.c
__inline int __attribute__((__always_inline__))
div(int b)
{
return 1/b;
}
int main()
{
div(0);
return 0;
}
$ gcc -O0 -Wall -Wextra -pedantic -Winline t.c -o t.out
$
(無警告或錯誤)
$ ./t.out
$
添加函數屬性__warn_unused_result__
至少給出了一個有用的信息:
$ gcc -O0 -Wall -Wextra -pedantic -Winline t.c -o t.out
t.c: In function ‘main’:
t.c:9:5: warning: ignoring return value of ‘div’, declared with attribute warn_unused_result [-Wunused-result]
div(0);
^
編輯:
在gcc mailing list一些討論。最終,我認爲一切都按預期工作。
嘗試使用'__attribute __((used))'所涉及的變量。 –
也許聲明s1和s2爲volatile ... – Malkocoglu