fix unroll with phis with eval on the edge
MODIFY
ir/function.cpp
ir/function.cpp
@@ -161,12 +161,12 @@ const BasicBlock& Function::bbOf(const Instr &i) const {
UNREACHABLE();
}
-BasicBlock& Function::insertBBBefore(string_view name, const BasicBlock &bb) {
+BasicBlock& Function::insertBBAfter(string_view name, const BasicBlock &bb) {
auto p = BBs.try_emplace(string(name), name);
if (p.second) {
auto I = find(BB_order.begin(), BB_order.end(), &bb);
assert(I != BB_order.end());
- BB_order.insert(I, &p.first->second);
+ BB_order.insert(next(I), &p.first->second);
}
return p.first->second;
}

MODIFY
ir/function.h
ir/function.h
@@ -108,7 +108,7 @@ public:
const BasicBlock& getBB(std::string_view name) const;
const BasicBlock& bbOf(const Instr &i) const;
- BasicBlock& insertBBBefore(std::string_view name, const BasicBlock &bb);
+ BasicBlock& insertBBAfter(std::string_view name, const BasicBlock &bb);
void removeBB(BasicBlock &BB);

MODIFY
llvm_util/llvm2alive.cpp
llvm_util/llvm2alive.cpp
@@ -1534,10 +1534,12 @@ public:
// introduce a new BB even if not always needed.
auto val = i->getIncomingValue(idx);
if (has_constant_expr(val)) {
- auto &phi_bb = getBB(i->getParent());
auto bridge = predecessor(i, idx);
- BB = &Fn.insertBBBefore(bridge, phi_bb);
- getBB(i->getIncomingBlock(idx)).replaceTargetWith(&phi_bb, BB);
+ auto &pred = getBB(i->getIncomingBlock(idx));
+ BB = &Fn.insertBBAfter(bridge, pred);
+
+ auto &phi_bb = getBB(i->getParent());
+ pred.replaceTargetWith(&phi_bb, BB);
if (auto op = get_operand(val)) {
phi->addValue(*op, std::move(bridge));
BB->addInstr(make_unique<Branch>(phi_bb));

ADD
tests/alive-tv/loops/phi-eval.srctgt.ll
+; TEST-ARGS: -src-unroll=1
+
+@c = external global i16, align 1
+
+define void @src() {
+entry:
+ br label %for.cond
+
+for.cond:
+ %0 = phi i16 [ 0, %entry ], [ ptrtoint (i16* @c to i16), %if.end ], [ 0, %for.cond1 ]
+ br i1 0, label %for.cond1, label %for.end8
+
+for.cond1:
+ br i1 0, label %for.cond, label %if.end
+
+if.end:
+ br i1 0, label %for.cond, label %for.cond1
+
+for.end8:
+ ret void
+}
+
+define void @tgt() {
+ ret void
+}

fix #791: unroll with phis with eval on the edge