【问题标题】:Clang producing executable with illegal instructionClang 产生带有非法指令的可执行文件
【发布时间】:2013-11-07 19:58:47
【问题描述】:

我将我看到的问题归结为一个小例子。这是我正在使用的 LLVM 汇编代码(在 foo.ll 中):

target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-pc-linux-gnu"

define fastcc i32 @foo(i32) {
entry:
    %x = add i32 %0, 1
    ret i32 %x
}

define i32 @main(i32, i8**) {
entry:
    %2 = call i32 @foo(i32 %0)
    ret i32 %2
}

然后我编译:

clang -O1 -o foo foo.ll

...当我运行它时,我得到:

Illegal instruction (core dumped)

...所以我启动了我的调试器,然后看到了这个:

Program received signal SIGILL, Illegal instruction.
0x00000000004004d0 in main ()
(gdb) bt
#0  0x00000000004004d0 in main ()
(gdb) disas
Dump of assembler code for function main:
=> 0x00000000004004d0 <+0>: ud2    
End of assembler dump.
(gdb) 

请注意,如果我更改以下任何一项,程序都会正常执行:

  • 从 clang 标志中删除 -O1
  • 从 foo.ll 中 @foo 的声明中删除 fastcc

作为参考,“clang -v”是:

clang version 3.3 (tags/RELEASE_33/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix

另外,如果有帮助的话here is the result of "objdump -d foo"

【问题讨论】:

  • 奇怪。我最近的 TOT 得到了完全相同的结果。

标签: clang llvm


【解决方案1】:

您的被呼叫者被标记为“fastcall”,但呼叫不是。调用约定需要匹配,否则它是未定义的行为,进而优化为“ud2”,或者根本没有。这是一个常见问题解答:http://llvm.org/docs/FAQ.html#why-does-instcombine-simplifycfg-turn-a-call-to-a-function-with-a-mismatched-calling-convention-into-unreachable-why-not-make-the-verifier-reject-it

【讨论】:

    【解决方案2】:

    有一个错误,在优化函数调用时,clang 会产生一个未定义的指令 ud2(这将引发无效的操作码错误)表明它无法处理某些事情。

    本质上,为了加快速度,它将返回值放在寄存器中。如果返回值不适合寄存器(因此将返回到堆栈中),那么它会发出 ud2 而不是 ret。

    这是一个已知的错误(至少在 3.2 中)。

    【讨论】:

    • 在某处的跟踪器中是否存在问题?
    • 另外,你说“如果返回值不适合寄存器”。在这种情况下确实如此,对吧?
    • --- 马歇尔写了一些令人困惑的东西,所以不会让他删除它,所以他用这个道歉代替了它。 ---
    猜你喜欢
    • 1970-01-01
    • 2019-04-29
    • 2011-11-18
    • 2019-11-06
    • 1970-01-01
    • 1970-01-01
    • 2016-06-30
    • 1970-01-01
    • 2013-01-20
    相关资源
    最近更新 更多