9

I am writing a compiler for a self-made language which can handle only int values i.e. i32. Conditions and expressions are similar to C language. Thus, I am considering conditional statements as expressions i.e. they return an int value. They can also be used in expressions e.g (2 > 1) + (3 > 2) will return 2. But LLVM conditions output i1 value.

  • Now, I want that after each conditional statement, i1 should be converted into i32, so that I can carry out binary operations
  • Also, I want to use variables and expression results as condition e.g. if(variable) or if(a + b). For that I need to convert i32 to i1

At the end, I want a way to typecast from i1 to i32 and from i32 to i1. My code is giving these kinds of errors as of now :

For statement like if(variable) :

error: branch condition must have 'i1' type
br i32 %0, label %ifb, label %else
   ^

For statement like a = b > 3

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

Any suggestion on how to do that ?

Chaitanya Patel
  • 390
  • 1
  • 4
  • 15
  • There is [TruncInst](http://llvm.org/doxygen/classllvm_1_1TruncInst.html). I don't have immediate answer, but I would compile a simple program to LLVM IR and see how trunc instruction is used. This simple program must contain the truncation `i32 -> i1`, so that TruncInst is emitted. – Stanislav Pankevich Nov 13 '17 at 14:01
  • To get the opposite: `i1 -> i32` you most probably need a `CastInst`. – Stanislav Pankevich Nov 13 '17 at 14:03
  • 1
    [IRBuilder::CreateIntCast](http://llvm.org/doxygen/classllvm_1_1IRBuilder.html#a31a4dba1bcad1b45216ae48b8c124f20) will create a zext / trunc / bitcast as needed. – Ismail Badawi Nov 14 '17 at 00:31

1 Answers1

5

I figured it out. To convert from i1 to i32, as pointed out here by Ismail Badawi , I used IRBuilder::CreateIntCast. So if v is Value * pointer pointing to an expression resulting in i1, I did following to convert it to i32 :

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

But same can't be applied for converting i32 to i1. It will truncate the value to least significant bit. So i32 2 will result in i1 0. I needed i1 1 for non-zero i32. If v is Value * pointer pointing to an expression resulting in i32, I did following to convert it in i1 :

v = Builder.CreateICmpNE(v, ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0, true))
Chaitanya Patel
  • 390
  • 1
  • 4
  • 15