【问题标题】:LLVM Cast InstructionsLLVM 转换说明
【发布时间】:2013-11-18 22:12:34
【问题描述】:

我有想要使用fadd 添加的ConstantIntConstantFP 值。但是,我无法将 ConstantInt 转换为 fadd 可以接受的浮点数。

以下是代码的摘录:

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 比较陌生,所以如果这段代码没有意义,我会接受任何建议。

【问题讨论】:

    标签: c++ llvm llvm-c++-api


    【解决方案1】:

    我对这些东西的常用方法是查看 Clang 生成的内容 - LLVM IR 和 C++ API 调用(C++ 后端)。为简单起见,您可以使用online instance。所以,编译这段 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 时,这是最好/最快的方法。

    【讨论】:

    • 啊,这是一个非常好的工具。我能够使用它(和您的示例)来调试我的问题。谢谢!
    【解决方案2】:

    问题出在这里:

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

    你将left 转换为left->getType(),也就是说,你什么也没做。改为right->getType()

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2013-12-20
        • 2021-12-31
        • 2016-02-25
        • 1970-01-01
        • 2015-04-12
        • 2012-06-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多