LLVM 使用指令不是指令

LLVM Use Of Instruction Is Not An Instruction

我在这里 post 看到一个关于“使用指令不是指令”的错误,我 运行 遇到了类似的问题,但没有充分的理由.

我正在使用 moe (https://llvm.moe/ocaml/Llvm.html) 编写 LLVM 来构建编译器,我的问题基本上归结为 3 行:

let pointer = L.build_alloca float_t ("reg") builder in      L.dump_value(pointer);
  let test = L.build_store (L.const_float float_t 32.3) pointer builder      in L.dump_value(test);
   let loaded = L.build_load pointer ("reg") builder  in L.     dump_value(loaded);

我在这里所做的基本上是使用 alloc 在内存中获取一些 space,然后将 32.3 的值存储到那个 space,并尝试 加载它回到我在内存中分配的地方.

LLVM 明智,它看起来很不错,因为在 dump_module 输出之后,我得到如下内容:

align 8  %reg = alloca double, align 8 
store double 3.230000e+01, double* %reg, align 8
%x13 = load double, double* %reg, align 8

这应该正是我想要的——我什至通过编写一个类似的 C 程序来测试它,它在 LLVM 中做的事情与此非常相似。

但是,当我 运行 我的程序出现以下错误时:

Use of instruction is not an instruction!
 %x13 = load double, double* %reg, align 8

这似乎真的没有意义。又查了一下错误,好像是LLVM源码中的几行造成的:

     if (Instruction *Used = dyn_cast<Instruction>(U.getUser()))
       Assert(Used->getParent() != nullptr,
              "Instruction referencing"
              " instruction not embedded in a basic block!",
              &I, Used);
     else {
       CheckFailed("Use of instruction is not an instruction!", U);
       return;
     }
   }

这似乎暗示如果说明没有父项,就会发生这种情况,但我不确定为什么会这样。

如有任何帮助,我们将不胜感激!

LLVM 有常量和指令。常量是诸如 12 之类的东西,还有函数和全局变量(具有常量地址)。说明是涉及某种动作的东西。

常量可以使用常量(例如,常量的初始化程序可以引用其他常量)。指令可以使用常量(例如,可以存储到全局变量)。指令可以使用指令(例如,您可以从作为指令结果的地址加载)。

但是常量不能使用指令

当断言代码查看 %x13 = load double, double* %reg 时,User 变量指向操作数 (%reg),并且操作数的父级是加载指令。我不知道它断言时指向什么,但是 ->getParent() returns 不是指令,使用的是指令。