Getting GCC/Clang to use CMOV

Getting GCC/Clang to use CMOV

本文关键字:use CMOV to Clang GCC Getting      更新时间:2023-10-16

我有一个简单的标记值联合。取值为int64_tsdoubles。我在这些联合上执行加法,需要注意的是,如果两个参数都表示int64_t值,那么结果也应该具有int64_t值。

代码如下:

#include<stdint.h>
union Value {
  int64_t a;
  double b;
};
enum Type { DOUBLE, LONG };
// Value + type.
struct TaggedValue {
  Type type;
  Value value;
};
void add(const TaggedValue& arg1, const TaggedValue& arg2, TaggedValue* out) {
  const Type type1 = arg1.type;
  const Type type2 = arg2.type;
  // If both args are longs then write a long to the output.
  if (type1 == LONG && type2 == LONG) {
    out->value.a = arg1.value.a + arg2.value.a;
    out->type = LONG;
  } else {
    // Convert argument to a double and add it.
    double op1 = type1 == LONG ? (double)arg1.value.a : arg1.value.b; // Why isn't CMOV used?
    double op2 = type2 == LONG ? (double)arg2.value.a : arg2.value.b; // Why isn't CMOV used? 
    out->value.b = op1 + op2;
    out->type = DOUBLE;
  }
}

gcc在-O2下的输出如下:http://goo.gl/uTve18附在这里,以防链接不工作。

add(TaggedValue const&, TaggedValue const&, TaggedValue*):
    cmp DWORD PTR [rdi], 1
    sete    al
    cmp DWORD PTR [rsi], 1
    sete    cl
    je  .L17
    test    al, al
    jne .L18
.L4:
    test    cl, cl
    movsd   xmm1, QWORD PTR [rdi+8]
    jne .L19
.L6:
    movsd   xmm0, QWORD PTR [rsi+8]
    mov DWORD PTR [rdx], 0
    addsd   xmm0, xmm1
    movsd   QWORD PTR [rdx+8], xmm0
    ret
.L17:
    test    al, al
    je  .L4
    mov rax, QWORD PTR [rdi+8]
    add rax, QWORD PTR [rsi+8]
    mov DWORD PTR [rdx], 1
    mov QWORD PTR [rdx+8], rax
    ret
.L18:
    cvtsi2sd    xmm1, QWORD PTR [rdi+8]
    jmp .L6
.L19:
    cvtsi2sd    xmm0, QWORD PTR [rsi+8]
    addsd   xmm0, xmm1
    mov DWORD PTR [rdx], 0
    movsd   QWORD PTR [rdx+8], xmm0
    ret

它生成了带有许多分支的代码。我知道输入数据是相当随机的,即它有int64_t s和double s的随机组合。我想至少转换成双精度,相当于CMOV指令。有什么方法可以让gcc生成代码吗?理想情况下,我想在实际数据上运行一些基准测试,看看有很多分支的代码与有更少分支但更昂贵的CMOV指令的代码是如何做的。结果可能是GCC默认生成的代码工作得更好,但我想确认这一点。我可以自己内联程序集,但我不希望这样做。

交互式编译器链接是检查程序集的好方法。有什么建议吗?

  1. try -mllvm -x86-cmov-converter=false

  2. 尝试__asm解决方案https://gitflic.ru/project/erthink/bsearch-try