LLVM IR:C++ API:从i1到i32和从i32到i1的类型转换

10
我正在编写一个编译器,用于处理仅限于int值(即i32)的自制语言。条件和表达式类似于C语言。因此,我将条件语句视为表达式,即它们返回一个int值。它们也可以用于表达式中,例如(2>1)+(3>2)将返回2。但是LLVM条件输出i1值。
现在,我希望在每个条件语句之后,将i1转换为i32,以便进行二进制运算。
另外,我想要使用变量和表达式结果作为条件,例如if(variable)或if(a+b)。为此,我需要将i32转换为i1。
最后,我希望有一种方法可以从i1转换为i32,以及从i32转换为i1。目前我的代码会出现这些错误:
对于像if(variable)这样的语句:
error: branch condition must have 'i1' type
br i32 %0, label %ifb, label %else
   ^

对于像a = b > 3这样的语句

error: stored value and pointer type do not match
store i1 %gttmp, i32* @a
      ^

有没有关于如何做到这一点的建议?

有一个名为TruncInst的东西。我没有直接的答案,但我会编译一个简单的程序到LLVM IR并查看截断指令如何使用。这个简单的程序必须包含截断i32 -> i1,以便发出TruncInst。 - Stanislav Pankevich
为了得到相反的结果:i1 -> i32,你很可能需要使用CastInst - Stanislav Pankevich
1
IRBuilder::CreateIntCast 会根据需要创建 zext / trunc / bitcast。 - Ismail Badawi
1个回答

7

我发现了解决方法。要从 i1 转换为 i32,就像 Ismail Badawi 在这里指出的那样,我使用了IRBuilder::CreateIntCast。所以如果v是指向结果为i1的表达式的Value *指针,我会按照以下方式将其转换为i32

v = Builder.CreateIntCast(v, Type::getInt32Ty(getGlobalContext()), true);

但是将 i32 转换为 i1 时情况就不同了。它会将值截断为最低有效位。因此,i32 2 将导致 i1 0。我需要对于非零的 i32 得到 i1 1。如果 v 是指向生成 i32 的表达式的 Value * 指针,则可以执行以下操作将其转换为 i1

v = Builder.CreateICmpNE(v, ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0, true))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接