3

从命令行可以告诉 clang 禁用某些功能,例如-mno-mmx-mno-popcnt. 但是,虽然cmov是 llvm 跟踪的功能,但-mno-cmovx86 处理器没有(尽管您可以禁用其他处理器目标的条件移动)。

作为一种解决方法,我可以直接告诉 llvm 组件不要在处理器功能列表中包含“cmov”。但是,也许这是一个错误或者我做错了什么,即使关闭此功能它仍然会生成 cmov 指令。

如何让 clang/llvm 不生成 cmov 指令?
(在我的特定用例中,将条件保留为分支对于自动覆盖跟踪分析很有用,并且-O0非常苛刻,如果代码使用三元运算符,可能仍不能保证防止这种情况发生。)


这是一个带有一些测试的代码示例

文件:ac

void report(char *);

int foo(int x)
{
    if (x==1) {
        report("x is one");
    }
    else {
        report("x is not one");
    }
    return 1;
}

显示正常编译的控制台片段

$ clang-10 --version
clang version 10.0.0-4ubuntu1~18.04.1 
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

$ clang-10 -O2 -c a.c
$ objdump -M intel -d a.o
...
0000000000000000 <foo>:
   0:   50                      push   rax
   1:   83 ff 01                cmp    edi,0x1
   4:   b8 00 00 00 00          mov    eax,0x0
   9:   bf 00 00 00 00          mov    edi,0x0
   e:   48 0f 44 f8             cmove  rdi,rax
  12:   e8 00 00 00 00          call   17 <foo+0x17>
  17:   b8 01 00 00 00          mov    eax,0x1
  1c:   59                      pop    rcx
  1d:   c3                      ret    

控制台片段显示作为 llvm 发出,并关闭 cmov 目标功能,
然后编译 llvm -> 机器指令

$ clang-10 -O2 -Xclang -target-feature -Xclang -cmov -S -emit-llvm a.c
$ cat a.ll
...
define dso_local i32 @foo(i32 %0) local_unnamed_addr #0 {
  %2 = icmp eq i32 %0, 1
  %3 = select i1 %2,
     i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0),
     i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i64 0, i64 0)
  call void @report(i8* %3) #2
  ret i32 1
}
...
attributes #0 = {
  ... 
  "target-cpu"="x86-64"
  "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87,-cmov"
  "unsafe-fp-math"="false"
  "use-soft-float"="false"
}
...
$ llc-10 --x86-asm-syntax=intel a.ll
$ cat a.s
...
foo:                                    # @foo
    .cfi_startproc
# %bb.0:
    push    rax
    .cfi_def_cfa_offset 16
    cmp edi, 1
    mov eax, offset .L.str
    mov edi, offset .L.str.1
    cmove   rdi, rax
    call    report
    mov eax, 1
    pop rcx
    .cfi_def_cfa_offset 8
    ret
...
4

0 回答 0