0

我试图在 LLVM 中运行简化 CFG Pass,并在运行我自己的一个 IR 转换后删除一个无法访问的基本块,但我不断收到错误消息 -

删除时:i8* %g

Def 被销毁后使用仍然卡住:store i8 0, i8* %g

我很清楚这意味着什么,但“simplifyCFGPass”的全部目的不是为我们删除无法访问的基本块吗?为什么它必须抛出这个错误?我认为它应该能够简单地管理所有 use-def 依赖项并删除下面无法访问的“继续”基本块中的指令。

以下是相关的 IR -

entry:
  %a3 = alloca i32
  store i32 %a, i32* %a3
  %a4 = load i32, i32* %a3 
  %ifcond = icmp ne i32 %a4, 0
  br i1 %ifcond, label %then, label %else



then:                                             ; preds = %entry
  %gclone1 = alloca i32
  store i32 0, i32* %gclone1
  ret i5 0

else:                                             ; preds = %entry
  %gclone4 = alloca i64
  store i64 0, i64* %gclone4
  ret i5 0

continuation:                                     ; No predecessors!
  %iftmp = phi i32 [ 32, %then ], [ 64, %else ], !range !0
  %datasize = alloca i32
  store i32 %iftmp, i32* %datasize

  %g = alloca i8 ---------------------> Issue
  store i8 0, i8* %g ---------------------> Issue
  ret i5 0
}

有人可以解释为什么会出现这个错误吗?API不应该处理这个吗?

4

1 回答 1

0

你的 IR 明显坏了。你有:

%iftmp = phi i32 [ 32, %then ], [ 64, %else ], !range !0

但是,根据 LLVM IR 规范(http://llvm.org/docs/LangRef.html#phi-instruction):

传入值的类型由第一个类型字段指定。此后,“phi”指令将一对列表作为参数,其中一对用于当前块的每个前导基本块。只有第一类类型的值可以用作 PHI 节点的值参数。只有标签可以用作标签参数。

这显然违反了您的情况,因此后续的 IR 转换传递可能很容易失败。我建议您在转换通过后运行 IR 验证通过(例如通过 opt -verify)。

于 2017-06-17T14:18:28.673 回答