mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-29 06:16:55 +01:00
shader: recognize unconditional predicates in implication proofs
This commit is contained in:
@@ -1187,7 +1187,7 @@ private:
|
|||||||
bool Implies(Value guard, Value required) const {
|
bool Implies(Value guard, Value required) const {
|
||||||
guard = SimplifyGuard(guard);
|
guard = SimplifyGuard(guard);
|
||||||
required = required.Resolve();
|
required = required.Resolve();
|
||||||
if (EquivalentValue(m_program, guard, required)) return true;
|
if (required == Value(true) || EquivalentValue(m_program, guard, required)) return true;
|
||||||
const auto* test = required.TryInstruction();
|
const auto* test = required.TryInstruction();
|
||||||
if (test != nullptr && test->GetOpcode() == ValueOpcode::INotEqual32) {
|
if (test != nullptr && test->GetOpcode() == ValueOpcode::INotEqual32) {
|
||||||
for (uint32_t arg = 0; arg < 2u; ++arg)
|
for (uint32_t arg = 0; arg < 2u; ++arg)
|
||||||
|
|||||||
@@ -2411,8 +2411,8 @@ void TestScalarBufferSelectorDomain() {
|
|||||||
|
|
||||||
void TestPrivateLdsForwarding() {
|
void TestPrivateLdsForwarding() {
|
||||||
namespace CFG = Libs::Graphics::ShaderRecompiler::CFG;
|
namespace CFG = Libs::Graphics::ShaderRecompiler::CFG;
|
||||||
enum class Variant { Valid, Overlap, Duplicate, CrossLane, Truncated, OutOfBounds, Mask, Bypass };
|
enum class Variant { Valid, MaskedLoad, Overlap, Duplicate, CrossLane, Truncated, OutOfBounds, Mask, Bypass };
|
||||||
for (const auto variant : {Variant::Valid, Variant::Overlap, Variant::Duplicate,
|
for (const auto variant : {Variant::Valid, Variant::MaskedLoad, Variant::Overlap, Variant::Duplicate,
|
||||||
Variant::CrossLane, Variant::Truncated, Variant::OutOfBounds,
|
Variant::CrossLane, Variant::Truncated, Variant::OutOfBounds,
|
||||||
Variant::Mask, Variant::Bypass}) {
|
Variant::Mask, Variant::Bypass}) {
|
||||||
Fixture fixture;
|
Fixture fixture;
|
||||||
@@ -2454,7 +2454,8 @@ void TestPrivateLdsForwarding() {
|
|||||||
body->terminator = {.kind = CFG::TerminatorKind::Branch, .true_block = exit};
|
body->terminator = {.kind = CFG::TerminatorKind::Branch, .true_block = exit};
|
||||||
const auto load = fixture.Emit(ValueOpcode::LoadSharedU32,
|
const auto load = fixture.Emit(ValueOpcode::LoadSharedU32,
|
||||||
{variant == Variant::CrossLane
|
{variant == Variant::CrossLane
|
||||||
? fixture.Emit(ValueOpcode::IAdd32, {address, Value(4u)}) : address, Value(true)},
|
? fixture.Emit(ValueOpcode::IAdd32, {address, Value(4u)}) : address,
|
||||||
|
variant == Variant::MaskedLoad ? active : Value(true)},
|
||||||
fixture.AddMemory(memory, 0x20), exit);
|
fixture.AddMemory(memory, 0x20), exit);
|
||||||
const auto use = fixture.Emit(ValueOpcode::ReferenceU32, {load}, 0, exit);
|
const auto use = fixture.Emit(ValueOpcode::ReferenceU32, {load}, 0, exit);
|
||||||
ShaderComputeInputInfo compute;
|
ShaderComputeInputInfo compute;
|
||||||
@@ -2464,8 +2465,13 @@ void TestPrivateLdsForwarding() {
|
|||||||
fixture.PlanAndTrack({.compute = &compute});
|
fixture.PlanAndTrack({.compute = &compute});
|
||||||
const auto result = use.Instruction()->Arg(0).ResolveInstruction();
|
const auto result = use.Instruction()->Arg(0).ResolveInstruction();
|
||||||
Check(result != nullptr &&
|
Check(result != nullptr &&
|
||||||
(result->GetOpcode() == ValueOpcode::SelectU32) == (variant == Variant::Valid),
|
(result->GetOpcode() == ValueOpcode::SelectU32) ==
|
||||||
|
(variant == Variant::Valid || variant == Variant::MaskedLoad),
|
||||||
"private LDS forwarding lost its value or crossed an alias, mask, bound or dominance hazard");
|
"private LDS forwarding lost its value or crossed an alias, mask, bound or dominance hazard");
|
||||||
|
if (variant == Variant::MaskedLoad)
|
||||||
|
Check(result->Arg(0) == active && result->Arg(1) == Value(0x12345678u) &&
|
||||||
|
result->Arg(2) == Value(0u),
|
||||||
|
"forwarding an unconditional store lost the load's inactive-lane zero value");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user