From 9f4e55a8e7caf5c2127f1da366b36fdf6aa6df08 Mon Sep 17 00:00:00 2001 From: 0xsegf4ult Date: Wed, 28 Aug 2024 12:10:21 +0200 Subject: [PATCH] shader_recompiler: constant propagation bitwise operations + S_CMPK_EQ_U32 fix (#613) * rebase on main branch impl of V_LSHL_B64 * remove V_LSHR_B64 * fix S_CMPK_EQ_u32 * fix conflicts * fix broken merge * remove duplicate cases * remove duplicate declaration --- .../backend/spirv/emit_spirv_instructions.h | 1 + .../backend/spirv/emit_spirv_integer.cpp | 7 +++++++ .../frontend/translate/scalar_alu.cpp | 2 +- src/shader_recompiler/ir/ir_emitter.cpp | 14 ++++++++++++-- src/shader_recompiler/ir/ir_emitter.h | 2 +- src/shader_recompiler/ir/opcodes.inc | 1 + .../ir/passes/constant_propagation_pass.cpp | 6 ++++++ 7 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h index dd3d8fae..ce4d3f13 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h @@ -286,6 +286,7 @@ Id EmitShiftRightLogical64(EmitContext& ctx, Id base, Id shift); Id EmitShiftRightArithmetic32(EmitContext& ctx, Id base, Id shift); Id EmitShiftRightArithmetic64(EmitContext& ctx, Id base, Id shift); Id EmitBitwiseAnd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); +Id EmitBitwiseAnd64(EmitContext& ctx, IR::Inst* inst, Id a, Id b); Id EmitBitwiseOr32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); Id EmitBitwiseOr64(EmitContext& ctx, IR::Inst* inst, Id a, Id b); Id EmitBitwiseXor32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp index f20c4fac..a9becb1e 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp @@ -139,6 +139,13 @@ Id EmitBitwiseAnd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { return result; } +Id EmitBitwiseAnd64(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { + const Id result{ctx.OpBitwiseAnd(ctx.U64, a, b)}; + SetZeroFlag(ctx, inst, result); + SetSignFlag(ctx, inst, result); + return result; +} + Id EmitBitwiseOr32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { const Id result{ctx.OpBitwiseOr(ctx.U32[1], a, b)}; SetZeroFlag(ctx, inst, result); diff --git a/src/shader_recompiler/frontend/translate/scalar_alu.cpp b/src/shader_recompiler/frontend/translate/scalar_alu.cpp index 50a550d4..7914726f 100644 --- a/src/shader_recompiler/frontend/translate/scalar_alu.cpp +++ b/src/shader_recompiler/frontend/translate/scalar_alu.cpp @@ -472,7 +472,7 @@ void Translator::S_MIN_U32(const GcnInst& inst) { void Translator::S_CMPK_EQ_U32(const GcnInst& inst) { const s32 simm16 = inst.control.sopk.simm; - const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src0{GetSrc(inst.dst[0])}; const IR::U32 src1{ir.Imm32(simm16)}; ir.SetScc(ir.IEqual(src0, src1)); } diff --git a/src/shader_recompiler/ir/ir_emitter.cpp b/src/shader_recompiler/ir/ir_emitter.cpp index a65e538c..65de98b7 100644 --- a/src/shader_recompiler/ir/ir_emitter.cpp +++ b/src/shader_recompiler/ir/ir_emitter.cpp @@ -1115,8 +1115,18 @@ U32U64 IREmitter::ShiftRightArithmetic(const U32U64& base, const U32& shift) { } } -U32 IREmitter::BitwiseAnd(const U32& a, const U32& b) { - return Inst(Opcode::BitwiseAnd32, a, b); +U32U64 IREmitter::BitwiseAnd(const U32U64& a, const U32U64& b) { + if (a.Type() != b.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type()); + } + switch (a.Type()) { + case Type::U32: + return Inst(Opcode::BitwiseAnd32, a, b); + case Type::U64: + return Inst(Opcode::BitwiseAnd64, a, b); + default: + ThrowInvalidType(a.Type()); + } } U32U64 IREmitter::BitwiseOr(const U32U64& a, const U32U64& b) { diff --git a/src/shader_recompiler/ir/ir_emitter.h b/src/shader_recompiler/ir/ir_emitter.h index 8f806eb5..a60f4c28 100644 --- a/src/shader_recompiler/ir/ir_emitter.h +++ b/src/shader_recompiler/ir/ir_emitter.h @@ -195,7 +195,7 @@ public: [[nodiscard]] U32U64 ShiftLeftLogical(const U32U64& base, const U32& shift); [[nodiscard]] U32U64 ShiftRightLogical(const U32U64& base, const U32& shift); [[nodiscard]] U32U64 ShiftRightArithmetic(const U32U64& base, const U32& shift); - [[nodiscard]] U32 BitwiseAnd(const U32& a, const U32& b); + [[nodiscard]] U32U64 BitwiseAnd(const U32U64& a, const U32U64& b); [[nodiscard]] U32U64 BitwiseOr(const U32U64& a, const U32U64& b); [[nodiscard]] U32 BitwiseXor(const U32& a, const U32& b); [[nodiscard]] U32 BitFieldInsert(const U32& base, const U32& insert, const U32& offset, diff --git a/src/shader_recompiler/ir/opcodes.inc b/src/shader_recompiler/ir/opcodes.inc index 26da00bb..a49ea1c7 100644 --- a/src/shader_recompiler/ir/opcodes.inc +++ b/src/shader_recompiler/ir/opcodes.inc @@ -260,6 +260,7 @@ OPCODE(ShiftRightLogical64, U64, U64, OPCODE(ShiftRightArithmetic32, U32, U32, U32, ) OPCODE(ShiftRightArithmetic64, U64, U64, U32, ) OPCODE(BitwiseAnd32, U32, U32, U32, ) +OPCODE(BitwiseAnd64, U64, U64, U64, ) OPCODE(BitwiseOr32, U32, U32, U32, ) OPCODE(BitwiseOr64, U64, U64, U64, ) OPCODE(BitwiseXor32, U32, U32, U32, ) diff --git a/src/shader_recompiler/ir/passes/constant_propagation_pass.cpp b/src/shader_recompiler/ir/passes/constant_propagation_pass.cpp index b0d9dcc4..87a06933 100644 --- a/src/shader_recompiler/ir/passes/constant_propagation_pass.cpp +++ b/src/shader_recompiler/ir/passes/constant_propagation_pass.cpp @@ -352,9 +352,15 @@ void ConstantPropagation(IR::Block& block, IR::Inst& inst) { case IR::Opcode::BitwiseAnd32: FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a & b; }); return; + case IR::Opcode::BitwiseAnd64: + FoldWhenAllImmediates(inst, [](u64 a, u64 b) { return a & b; }); + return; case IR::Opcode::BitwiseOr32: FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a | b; }); return; + case IR::Opcode::BitwiseOr64: + FoldWhenAllImmediates(inst, [](u64 a, u64 b) { return a | b; }); + return; case IR::Opcode::BitwiseXor32: FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a ^ b; }); return;