【问题标题】:Force clang to generate intrinsic cos强制 clang 生成内在 cos
【发布时间】: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 内联为 x87 fcos 指令。 (这就是 LLVM fcos.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


【解决方案1】:

使用-ffast-math(暗示-fno-math-errno,clang -O3 将内联__builtin_cos@llvm.cos.f64

double func(double in) {
    double a = __builtin_cos(in);
    return a;
}

clang -O3 -ffast-math -emit-llvmon Godbolt(已删除调试内容)

define dso_local double @_Z4funcd(double) local_unnamed_addr #0 !dbg !7 {
  %2 = tail call fast double @llvm.cos.f64(double %0), !dbg !15
  ret double %2, !dbg !17
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    • 2012-09-17
    • 1970-01-01
    • 2013-01-23
    • 2018-03-13
    相关资源
    最近更新 更多