使用 LLVM 捕获整数溢出?

Jos*_*ise 4 integer-overflow llvm undefined-behavior llvm-ir

我正在创建一种静态编译的编程语言,并使用 LLVM 作为其后端。我希望我的语言在发生整数溢出时捕获/崩溃。

我知道llvm.sadd.with.overflow之类的东西,但我认为这不是最佳/有效的解决方案。该函数返回一个包含两个值的结构,而不仅仅是让我直接访问 OF 寄存器标志。理想情况下,在每次算术运算之后,只要发生整数溢出,我就会有一个“JO”汇编指令来捕获。这正是 clang 的UndefinedBehaviorSanitizer所做的。但是,我正在编译为 LLVM IR,而不是 C 或 C++。

如何直接在 LLVM IR 中使用 UndefinedBehaviorSanitizer(或完成等效操作)来处理整数溢出?

sep*_*p2k 5

我知道 llvm.sadd.with.overflow 之类的东西,但我认为这不是最佳/有效的解决方案。[...] 理想情况下,在每次算术运算之后,只要发生整数溢出,我就会有一个“JO”汇编指令来捕获。这正是 clang 的 UndefinedBehaviorSanitizer 所做的。

UndefinedBehaviorSanitizer 的作用是生成对llvm.sadd.with.overflow. 您可以通过编译以下 C 程序-fsanitize=undefined并查看生成的 LLVM 代码轻松验证这一点:

黑色:

#include <stdio.h>

int main(void){
  int x;
  scanf("%d", &x);
  printf("%d\n", x+1);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

命令行:

clang -fsanitize=undefined -emit-llvm -O2 -S bla.c
Run Code Online (Sandbox Code Playgroud)

bla.ll(摘录):

clang -fsanitize=undefined -emit-llvm -O2 -S bla.c
Run Code Online (Sandbox Code Playgroud)

sadd.with.overflow最终将作为常规incl指令¹和br i1 %7作为jo生成的 x64 程序集中的a 结束,所以这正是您想要的。


¹ 当然,如果我在 C 代码中添加了 1 以外的内容,这将是一个正确的添加指令。