13

我有我想要添加的值ConstantInt和值。但是,我无法将其转换为可以接受的浮点数。ConstantFPfaddConstantIntfadd

这是代码的摘录:

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());

哪里currentBlock()返回一个BasicBlock。在尝试为此生成操作码后,LLVM 抱怨它无法添加这两个值,因为它们不一样。

我对 LLVM 比较陌生,所以如果这段代码没有意义,我会接受任何建议。

4

3 回答 3

17

我对这些事情的常用方法是查看 Clang 生成的内容 - LLVM IR 和 C++ API 调用(C++ 后端)。为简单起见,您可以使用在线实例。因此,编译此 C 代码:

float foo(int a, float b) {
  return a + b;
}

给我这个 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
}

这是重新创建它所需的 C++ API 调用:

 // 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);   
 }

您可以随意调整输入的 C 代码(即用常量替换 vars 等)并查看 Clang/LLVM 发出的内容。当您不太熟悉 IR 和 API 时,这是最好/最快的方法。

于 2013-11-18T22:56:27.450 回答
1

问题在这里:

Instruction* cast = CastInst::Create(Instruction::SIToFP, left, left->getType(), "", currentBlock());

你投到leftleft->getType()即你什么也没做。改为right->getType()

Instruction* cast = CastInst::Create(Instruction::SIToFP, left, right->getType(), "", currentBlock());
于 2018-02-04T05:49:29.120 回答
0

LLVM 12

    Value *cg_binary(BinaryAst *ast)
    {
      auto l = codegen(ast->left);
      auto r = codegen(ast->right);
      switch (ast->op)
      {
      case parser::token::PLUS:
      {
        if (l->getType()->getTypeID() == Type::TypeID::DoubleTyID || r->getType()->getTypeID() == Type::TypeID::DoubleTyID)
          return b->CreateFAdd(b->CreateSIToFP(l, b->getDoubleTy()), b->CreateSIToFP(r, b->getDoubleTy()));
        else
          return b->CreateAdd(l, r);
      }
      }
    }
于 2021-06-10T05:45:35.580 回答