diff options
author | Hans-Kristian Arntzen <post@arntzen-software.no> | 2022-04-27 16:12:58 +0300 |
---|---|---|
committer | Hans-Kristian Arntzen <post@arntzen-software.no> | 2022-04-28 13:49:33 +0300 |
commit | 0ab26a342fd1316b4e3559827a6ddeaee17c1457 (patch) | |
tree | b0cdfca1c8da07930bf539ea7f59111604149911 | |
parent | 2e413b15fb58fe3472ac24cd01c9539175c51e92 (diff) |
Avoid degenerate PHIs.
Some LCSSA passes create PHIs with one incoming block.
Just forward the SSA value directly. For one pred, the incoming value
must dominate the consuming block, so it should be fine.
-rw-r--r-- | dxil_converter.cpp | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/dxil_converter.cpp b/dxil_converter.cpp index 4aa567e..3e9ad55 100644 --- a/dxil_converter.cpp +++ b/dxil_converter.cpp @@ -4679,21 +4679,46 @@ spv::Id Converter::Impl::fixup_store_type_typed(DXIL::ComponentType component_ty bool Converter::Impl::emit_phi_instruction(CFGNode *block, const llvm::PHINode &instruction) { - PHI phi; - phi.id = get_id_for_value(&instruction); - phi.type_id = get_type_id(instruction.getType()); - unsigned count = instruction.getNumIncomingValues(); - for (unsigned i = 0; i < count; i++) + + if (count == 1) { - IncomingValue incoming = {}; - incoming.block = bb_map[instruction.getIncomingBlock(i)]->node; - auto *value = instruction.getIncomingValue(i); - incoming.id = get_id_for_value(value); - phi.incoming.push_back(incoming); + // Degenerate PHI. Seems to happen in some bizarre cases with lcssa passes? + auto *value = instruction.getIncomingValue(0); + rewrite_value(&instruction, get_id_for_value(value)); + + // This PHI node can actually be pointer or descriptor for whatever reason, + // so inherit any such mappings. + { + auto itr = handle_to_storage_class.find(value); + if (itr != handle_to_storage_class.end()) + handle_to_storage_class[&instruction] = itr->second; + } + + { + auto itr = handle_to_root_member_offset.find(value); + if (itr != handle_to_root_member_offset.end()) + handle_to_root_member_offset[&instruction] = itr->second; + } + } + else + { + PHI phi; + phi.id = get_id_for_value(&instruction); + phi.type_id = get_type_id(instruction.getType()); + + for (unsigned i = 0; i < count; i++) + { + IncomingValue incoming = {}; + incoming.block = bb_map[instruction.getIncomingBlock(i)]->node; + auto *value = instruction.getIncomingValue(i); + incoming.id = get_id_for_value(value); + phi.incoming.push_back(incoming); + } + + block->ir.phi.push_back(std::move(phi)); } - block->ir.phi.push_back(std::move(phi)); return true; } |