0

在遵循 LLVM Kaleidoscope 教程并使用 LLVM-C API 复制它时,我遇到了以下断言失败:

断言失败:New->getType() == getType() && "replaceAllUses of value with new value of different type!",文件 C:\llvm-project\llvm\lib\IR\Value.cpp,第 494 行

我已经看到在两种情况下产生了这个错误:

  1. CFGSimplificationPass 被添加到 pass 管理器中,并且 LLVMRunFunctionPassManager 函数在一个像这样分支的函数上被调用(下面的完整示例):
   br i1 true, label %then, label %else
  1. 未添加 CFGSimplificationPass;LLVMRunFunctionPassManager 成功。但是,运行 LLVMRunFunction 时会产生相同的错误。

以下生成的代码很好:

  %cmptmp = fcmp ult double %x, 3.000000e+00
  br i1 %cmptmp, label %then, label %else

我为第一个实例创建了一个小型复制器:

#include "llvm-c\Core.h"
#include "llvm-c\Transforms\Utils.h"
#include "llvm-c\Transforms\Scalar.h"
#include "llvm-c\Analysis.h"

LLVMContextRef context;
LLVMModuleRef module;
LLVMBuilderRef builder;
LLVMPassManagerRef passManager;

void initializePassManager() {
    passManager = LLVMCreateFunctionPassManagerForModule(module);
    LLVMAddPromoteMemoryToRegisterPass(passManager);
    LLVMAddInstructionCombiningPass(passManager);
    LLVMAddReassociatePass(passManager);
    LLVMAddGVNPass(passManager);
    LLVMAddCFGSimplificationPass(passManager);
}

LLVMValueRef codegenProto() {
    LLVMTypeRef parameters[1];
    LLVMTypeRef functionType = LLVMFunctionType
    (LLVMDoubleTypeInContext(context),
        parameters,
        0,
        0);
    LLVMValueRef func = LLVMAddFunction(module, "__anon_expr", functionType);
    LLVMSetLinkage(func, LLVMExternalLinkage);
    return func;
}

LLVMValueRef codegenBody() {
    LLVMValueRef x = LLVMConstReal(LLVMDoubleTypeInContext(context), 1.0);
    LLVMValueRef y = LLVMConstReal(LLVMDoubleTypeInContext(context), 2.0);
    LLVMValueRef conditionValue = LLVMBuildFCmp(builder, LLVMRealULT, x, y, "cmptmp");
    LLVMBasicBlockRef currentBasicBlock = LLVMGetInsertBlock(builder);
    LLVMValueRef func = LLVMGetBasicBlockParent(currentBasicBlock);
    LLVMBasicBlockRef thenBasicBlock = LLVMAppendBasicBlockInContext(context, func, "then");
    LLVMBasicBlockRef elseBasicBlock = LLVMCreateBasicBlockInContext(context, "else");
    LLVMBasicBlockRef mergeBasicBlock = LLVMCreateBasicBlockInContext(context, "ifcont");
    LLVMValueRef condBr = LLVMBuildCondBr(builder, conditionValue, thenBasicBlock, elseBasicBlock);
    LLVMPositionBuilderAtEnd(builder, thenBasicBlock);
    LLVMValueRef thenValue = LLVMConstReal(LLVMDoubleTypeInContext(context), 37.0);
    LLVMBuildBr(builder, mergeBasicBlock);
    thenBasicBlock = LLVMGetInsertBlock(builder);
    LLVMAppendExistingBasicBlock(func, elseBasicBlock);
    LLVMPositionBuilderAtEnd(builder, elseBasicBlock);
    LLVMValueRef elseValue = LLVMConstReal(LLVMDoubleTypeInContext(context), 42.0);
    LLVMBuildBr(builder, mergeBasicBlock);
    elseBasicBlock = LLVMGetInsertBlock(builder);
    LLVMAppendExistingBasicBlock(func, mergeBasicBlock);
    LLVMPositionBuilderAtEnd(builder, mergeBasicBlock);
    LLVMValueRef phiNode = LLVMBuildPhi(builder, LLVMDoubleTypeInContext(context), "iftmp");
    LLVMValueRef values[2] = {thenValue, elseValue};
    LLVMBasicBlockRef blocks[2] = {thenBasicBlock, elseBasicBlock};
    LLVMAddIncoming(phiNode, values, blocks, 2);
    return phiNode;
}

LLVMValueRef codegenFunc() {
    LLVMValueRef proto = codegenProto();
    LLVMBasicBlockRef basicBlock = LLVMAppendBasicBlock(proto, "entry");
    LLVMPositionBuilderAtEnd(builder, basicBlock);
    LLVMValueRef body = codegenBody();
    LLVMBuildRet(builder, body);
    LLVMDumpModule(module);
    LLVMVerifyFunction(proto, LLVMPrintMessageAction);
    LLVMRunFunctionPassManager(passManager,proto);
    return proto;
}

int main() {
    LLVMLinkInMCJIT();
    LLVMInitializeX86Target();
    LLVMInitializeX86TargetMC();
    LLVMInitializeX86TargetInfo();
    LLVMInitializeX86AsmPrinter();
    LLVMInitializeX86AsmParser();

    context = LLVMContextCreate();
    module = LLVMModuleCreateWithNameInContext("JIT", context);
    builder = LLVMCreateBuilderInContext(context);
    initializePassManager();

    LLVMValueRef IR = codegenFunc();

    LLVMDisposeBuilder(builder);
    LLVMDisposeModule(module);
    LLVMContextDispose(context);
    LLVMDisposePassManager(passManager);
    return 0;
}

LLVMDumpModule 函数为我提供以下输出:

; ModuleID = 'JIT'
source_filename = "JIT"

define double @__anon_expr() {
entry:
  br i1 true, label %then, label %else

then:                                             ; preds = %entry
  br label %ifcont

else:                                             ; preds = %entry
  br label %ifcont

ifcont:                                           ; preds = %else, %then
  %iftmp = phi double [ 3.700000e+01, %then ], [ 4.200000e+01, %else ]
  ret double %iftmp
}

我已经看到 LLVM Kaleidoscope 示例项目生成的相同代码,运行没有问题。我的 MCJIT 设置是否存在固有问题,或者我是否遇到了 LLVM 错误?

4

0 回答 0