【发布时间】:2019-05-07 09:00:00
【问题描述】:
编译cos.c
void func() {
double a = __builtin_cos(3.0);
}
使用
clang -S -emit-llvm -c cos.c
我有
define dso_local void @func() {
%1 = alloca double, align 8
%2 = call double @cos(double 3.000000e+00)
store double %2, double* %1, align 8
ret void
}
declare dso_local double @cos(double)
但我想获得 cos 的 llvm 内在函数 @llvm.fcos.f64 而不是 @cos,即生成的代码应该是这样的
...
%2 = call double @llvm.fcos.f64(double 3.000000e+00)
...
}
declare double @llvm.cos.f64(double)
如何强制clang 这样做?也许我应该使用另一个函数而不是__builtin_cos?
【问题讨论】:
-
我想也许我们可以通过告诉 clang 在没有 SSE 的情况下为 32 位 x86 编译来获得它,因此它可能会将
cos内联为 x87fcos指令。 (这就是 LLVMfcos.f64吗?)但是不,它仍然想调用库cos()。 godbolt.org/z/Z70ug0 即使使用-O3 -ffast-math -m32 -mno-sse(对于运行时变量函数 arg,因此它不能通过cos进行常量传播而只返回一个常量。) -
@PeterCordes 我认为使用
__builtin_cos不好,因为这个函数有副作用(它设置errno代码) -
-ffast-math应包括-fno-math-errno。 (它适用于 GCC,但我对 clang 不太熟悉。) -
@PeterCordes 您能否将您的评论作为答案,因为它是正确的:
-ffast-math强制clang生成@llvm.cos.f64。非常感谢。 -
我的第一条评论是错误的,原来我有正确的答案但没有仔细阅读,哎呀! (我通常只看 x86 asm,而不是 LLVM-IR)。毕竟不需要强制 32 位 no-sse。
标签: clang llvm intrinsics trigonometry