Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/HansKristian-Work/dxil-spirv.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Kristian Arntzen <post@arntzen-software.no>2022-04-27 16:12:58 +0300
committerHans-Kristian Arntzen <post@arntzen-software.no>2022-04-28 13:49:33 +0300
commit0ab26a342fd1316b4e3559827a6ddeaee17c1457 (patch)
treeb0cdfca1c8da07930bf539ea7f59111604149911
parent2e413b15fb58fe3472ac24cd01c9539175c51e92 (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.cpp47
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;
}