LLVM不一致编号方案

LLVM不一致编号方案,llvm,llvm-ir,Llvm,Llvm Ir,我一直在玩编译器,一直在做我自己的玩具C编译器。目前,我正试图以LLVM IR为目标,但在语法方面遇到了困难 我当前的问题:为什么这是有效的IR语法: define i32 @main() { %1 = alloca i32, align 4 %2 = add i32 0, 0 store i32 %2, i32* %1, align 4 %3 = alloca i32, align 4 %4 = add i32 0, 1 store i32 %4

我一直在玩编译器,一直在做我自己的玩具C编译器。目前,我正试图以LLVM IR为目标,但在语法方面遇到了困难

我当前的问题:为什么这是有效的IR语法:

define i32 @main() {
    %1 = alloca i32, align 4
    %2 = add i32 0, 0
    store i32 %2, i32* %1, align 4
    %3 = alloca i32, align 4
    %4 = add i32 0, 1
    store i32 %4, i32* %3, align 4
    %5 = load i32, i32* %1, align 4
    %6 = icmp ne i32 %5, 0
    br i1 %6, label %true0, label %else0
true0:                          ; preds %0
    %7 = add i32 0, 1
    store i32 %7, i32* %3, align 4
    br label %end0
else0:                          ; preds %0
    %8 = load i32, i32* %3, align 4
    %9 = icmp ne i32 %8, 0
    br i1 %9, label %true1, label %end1
true1:                      ; preds %else0
    %10 = add i32 0, 2
    store i32 %10, i32* %3, align 4
    br label %end1
end1:                       ; preds %true1, %else0
    br label %end0
end0:                           ; preds %true0, %else1
    %11 = load i32, i32* %3, align 4
    ret i32 %11
}
但这不是:

define i32 @main() {
    %1 = alloca i32, align 4
    %2 = add i32 0, 0
    store i32 %2, i32* %1, align 4 ; variable a
    %3 = load i32, i32* %1, align 4
    %4 = icmp ne i32 %3, 0
    br i1 %4, label %true0, label %else0
true0: ; preds %0
    %5 = add i32 0, 1
    ret i32 %5
    br label %end0
else0: ; preds %0
    %6 = add i32 0, 2
    ret i32 %6
    br label %end0
end0: ; % preds %true0, %else0
    ret i32 0
}
我得到一个错误:

llc-6.0: test2.ll:13:1: error: instruction expected to be numbered '%7'
%6 = add i32 0, 2
^
我不明白为什么块必须是%7,因为以前使用的数字是%6。比较第一个示例的%else0标签,它的语法非常相似,可以正常工作


是的,我的编译器需要很多优化,但我还没有完成:

您的代码无效,因为实际上还有一个基本块没有标记:

true0: ; preds %0
    %5 = add i32 0, 1
    ret i32 %5
hidden_bb: ; this will named as %6 by default
    br label %end0
else0: ; preds %0

如果有标签,则错误将消失。请注意,所有终止符指令(如br和ret)都将创建自己的基本块。

您的代码无效,因为实际上还有一个基本块未标记:

true0: ; preds %0
    %5 = add i32 0, 1
    ret i32 %5
hidden_bb: ; this will named as %6 by default
    br label %end0
else0: ; preds %0

如果有标签,则错误将消失。请注意,所有终止符指令,像br和ret一样,他们将创建自己的基本块。

谢谢@eraklon-为什么第一个例子没有这个问题?在第一个例子中,所有的基本块都被标记了,所以llvm没有尝试制作一个像这里一样的基本块。我想我已经解决了-因为ret语句,在第二个例子中有一个新的基本块。谢谢@eraklon-为什么没有第一个示例有问题吗?在第一个示例中,所有基本块都被标记,因此llvm没有尝试使一个像这里一样的块认为我已经解决了-由于ret语句,在第二个示例中有一个新的基本块。