试图了解llvm-IR中的phi指令语义
(https://llvm.org/docs/LangRef.html#phi-instruction)
让我们考虑以下示例:
; Function Attrs: norecurse nounwind
define i32 @main( i32 %argc, i8** %argv) {
entry:
switch i32 %argc, label %L1 [ i32 0, label %L0
i32 1, label %L1 ]
L0:
%x = add i32 %argc, 1
br label %L1
L1:
%y = phi i32 [ %argc, %entry ], [ %x, %L0 ]
%z = sub i32 %y, 1
%w = udiv i32 100, %z
ret i32 %w
}
使用clang-7.0.1进行编译
$ clang-7.0.1 -O0 test.ll -o a.out
PHINode should have one entry for each predecessor of its parent basic
block!
%y = phi i32 [ %argc, %entry ], [ %x, %L0 ]
fatal error: error in backend: Broken function found, compilation
流产!
当我用“%y = add i32 2、1”替换“%y = phi ...”时,测试已成功编译。
这里的问题是关于错误消息的: 为什么在测试中不是所有的前辈都在phi中列出?从LangRef.html#phi-instruction中phi指令的描述中我无法 了解它。
答案 0 :(得分:0)
当从块A到块B有多个边时,则B中的PHI节点必须列出A的次数与边的次数相同,每次具有相同的值。在您的情况下,从entry
到L1
有两条边(一条是开关的默认情况,一条是1情况),因此entry
需要在PHI中列出两次。节点。
但是,在这种情况下,更清洁的解决方案可能是从交换机中删除[i32 1, label %L1]
情况,因为这仍然很多余。这样一来,entry
就只需要一条边。