【问题标题】:Xcode in release mode fails to compile <immintrin.h> - complains about __builtin_ia32_emms()发布模式下的 Xcode 无法编译 <immintrin.h> - 抱怨 __builtin_ia32_emms()
【发布时间】:2021-06-01 19:22:36
【问题描述】:

我是 Xcode 的新手,在 macOS Catalina 10.15.7 上使用 Xcode 12.4 (12D4e) 为 macOS 开发 SIMD(SSE/AVX) 代码。
这段非常简单的代码可以在Debug方案中编译:

#include <immintrin.h>

int main(int argc, const char * argv[]) {
    return 0;
}

但在发布方案中,标头出错:“函数调用的参数太少,预期为 2,有 0”对于这行“mmintrin.h”。

    __builtin_ia32_emms();

如何在 Release 方案中编译它?

【问题讨论】:

  • 这很奇怪; emms 指令不采用任何操作数,而 GCC 对 _mm_empty() 的定义确实使用了 __builtin_ia32_emms(),没有您期望的 args。我的 Linux 桌面上的 mmintrin.h 的主线(不是 Apple)clang 11.0 版本也是如此。 IDK 为什么 clang 会期望 2 个参数。
  • 你确定你有相同的设置吗? CLANG_X86_VECTOR_INSTRUCTIONS 用于调试和发布版本?
  • @PaulR:MMX 是 x86-64 的基线,这个错误似乎与 __builtin 函数有关,不是一个仅由标头有条件地定义的内在函数。 (如果您使用-mno-mmx,则此类内置函数将报告由于特定于目标的选项而内联失败,但我认为这不能解释期望此内置函数采用 2 个参数。)当然,我不使用 MacOS 或Xcode,所以我不能排除产生这些症状的问题的可能性,但这似乎不太可能。 (如果该错误消息被正确引用,那么其他任何事情也没有任何意义。)
  • @PeterCordes:是的,我知道这没有意义,但我最近在 Xcode 项目中遇到了类似的奇怪问题。不幸的是,我不记得细节或修复,但我记得调试和发布构建设置之间存在一些差异。
  • 是的,我认为这与我升级到 Xcode 12 时遇到的问题相同 - Debug 构建默认为当前架构,但 Release 构建尝试构建一个“胖”二进制文件x86 和 ARM 代码,因此如果您有任何特定于 x86 的代码(例如 Intel 内部函数),那么它在构建的 ARM 部分会失败。不幸的是,由此产生的错误消息具有误导性,因此乍一看问题并不明显。

标签: c++ xcode x86-64 simd intrinsics


【解决方案1】:

如果您有任何特定于 Intel 的代码(例如 Intel 内部函数),那么您需要确保您的 Release 版本仅设置为 x86-64 架构。在 Xcode 12 中,默认是在 Release 版本中为 x86-64 和 Apple Silicon 构建,这会在构建的 Apple Silicon 部分遇到 Intel 内部函数时导致虚假错误消息。

【讨论】:

  • 啊,这有点道理。正如您在评论中所说,Debug 构建中的默认值只是当前架构。不过,仍然没有解释为什么它可能认为__builtin_ia32_emms() 在瞄准 ARM 时应该采用 2 个参数!希望未来版本的 xcode 会在 immintrin.h 中添加某种 #if / #error 来告诉您在不针对 x86-64 或 i386 时包含它。
  • 是的,我认为这只会影响相对较小的开发人员子集,他们的项目中包含特定于 x86 的代码并在 Xcode 12 下启动新项目(旧项目应该没问题)。不过,错误消息很奇怪。
  • 谢谢你,保罗。你的描述很清楚,我的问题得到了解决。我发现#ifdef __x86_64__ 可以同时编写 x86_64 代码和 Apple Silicon 代码(即使对于具有标准架构(Apple Silicon、Intel)的发布方案)。
猜你喜欢
  • 2011-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-19
  • 1970-01-01
相关资源
最近更新 更多