I have ConstantInt
and ConstantFP
values that I want to add using fadd
. However, I'm having trouble casting the ConstantInt
into a floating point number that fadd
will accept.
Here is an excerpt of the code:
Value* left = ConstantInt::get(Type::getInt64Ty(getGlobalContext()), 12, true);
Value* right = ConstantFP::get(Type::getFloatTy(getGlobalContext()), 11.6);
Instruction* cast = CastInst::Create(Instruction::SIToFP, left, left->getType(), "", currentBlock());
left = cast->getOperand(0);
BinaryOperator::Create(Instruction::FAdd, left, right, "", currentBlock());
where currentBlock()
returns a BasicBlock
. After trying to generate the opcode for this, LLVM complains that it can't add the two values because they are not the same.
I'm rather new to LLVM, so I'll take any advice if this code makes no sense.
My usual approach with these things is see what Clang generates - both the LLVM IR and the C++ API calls (C++ backend). You can use the online instance for simplicity. So, compiling this C code:
float foo(int a, float b) {
return a + b;
}
Gives me this LLVM IR:
define float @foo(i32 %a, float %b) #0 {
entry:
%conv = sitofp i32 %a to float
%add = fadd float %conv, %b
ret float %add
}
And this is the C++ API calls required to recreate that:
// Function: foo (func_foo)
{
Function::arg_iterator args = func_foo->arg_begin();
Value* int32_a = args++;
int32_a->setName("a");
Value* float_b = args++;
float_b->setName("b");
BasicBlock* label_entry = BasicBlock::Create(mod->getContext(), "entry",func_foo,0);
// Block entry (label_entry)
CastInst* float_conv = new SIToFPInst(int32_a, Type::getFloatTy(mod->getContext()), "conv", label_entry);
BinaryOperator* float_add = BinaryOperator::Create(Instruction::FAdd, float_conv, float_b, "add", label_entry);
ReturnInst::Create(mod->getContext(), float_add, label_entry);
}
You're free to tweak the input C code (i.e. replacing vars with constants, etc) and seeing what Clang/LLVM emit. This is the best/quickest way to find your way around the IR and API when you're not too familiar with it.
The problem is here:
Instruction* cast = CastInst::Create(Instruction::SIToFP, left, left->getType(), "", currentBlock());
You casted left
to left->getType()
, i.e., you did nothing. Cast to right->getType()
instead:
Instruction* cast = CastInst::Create(Instruction::SIToFP, left, right->getType(), "", currentBlock());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With