在使用clang实现char8_t方面是否存在缺陷,或者该标准的某个暗角禁止优化?

时间:2019-04-16 14:06:05

标签: c++ clang compiler-optimization c++20

clang 8.0.0从c ++ 20引入了对char8_t类型的支持。但是,我希望以下函数具有相同的编译器输出

#include <algorithm>

bool compare4(char const* pcha, char const* pchB, int n) {
    return std::equal(pcha, pcha+4, pchB);
}

bool compare4(char8_t const* pchA, char8_t const* pchB, int n) {
    return std::equal(pchA, pchA+4, pchB);
}

但是,他们-std=c++2a -O2下的compile

compare4(char const*, char const*, int):   # @compare4(char const*, char const*, int)
        mov     eax, dword ptr [rdi]
        cmp     eax, dword ptr [rsi]
        sete    al
        ret
_Z8compare4PKDuS0_i:                       # @_Z8compare4PKDuS0_i
        mov     al, byte ptr [rdi]
        cmp     al, byte ptr [rsi]
        jne     .LBB1_4
        mov     al, byte ptr [rdi + 1]
        cmp     al, byte ptr [rsi + 1]
        jne     .LBB1_4
        mov     al, byte ptr [rdi + 2]
        cmp     al, byte ptr [rsi + 2]
        jne     .LBB1_4
        mov     al, byte ptr [rdi + 3]
        cmp     al, byte ptr [rsi + 3]
        sete    al
        ret
.LBB1_4:
        xor     eax, eax
        ret
显然,后者的优化程度较差。 是否有原因(我在标准中找不到)或这是clang中的错误?

2 个答案:

答案 0 :(得分:4)

这不是Clang中的“错误”;只是错过的优化机会。

您可以使用相同的函数replicate the Clang compiler output并使用基础类型为enum class的{​​{1}}。相比之下,GCC会识别基础类型为unsigned charunsigned char的枚举数之间的差异。它为char8_tunsigned char发出相同的代码,但为char8_t情况发出更复杂的代码。

因此,关于Clang enum class的实现似乎更多地将其视为用户定义的枚举,而不是基本类型。最好只是将其视为该标准的早期实施。

应注意,char8_tunsigned char之间最重要的区别之一是别名要求。 char8_t指针可能还带有其他别名。相反,unsigned char指针不能。因此,可以合理地预期(在 mature 实现上,而不是超出其实现的市场标准)在不同情况下发出不同的代码。诀窍在于,char8_t代码如果有所不同,则应该更高,因为编译器不再需要发出执行额外工作来处理来自商店的潜在别名的代码。

答案 1 :(得分:4)

  1. 在libstdc ++中,std::equal在检测到参数“简单”时调用__builtin_memcmp,否则将使用朴素的for循环。这里的“简单”表示指向相同整数或指针类型的指针(或指针周围的某些迭代器包装器)。(relevant source code

    • 内部__is_integer特征是否检测到类型是否为整数类型,但是libstdc ++ 8.2.0(godbolt.org上使用的版本)没有专门针对char8_t定义此特征,因此后者未检测为整数类型。(relevant source code
  2. __builtin_memcmp情况相比,
  3. Clang(具有此特定配置)在for循环情况下生成的详细组装。 (但前者不一定在性能上有所优化。请参见Loop_unrolling。)

因此存在这种差异是有原因的,这不是IMO叮当声中的错误。