summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-04-23 08:17:53 -0300
committerGravatar ameerj2021-07-22 21:51:29 -0400
commit50eb03382e8ac8eb4aeb7cdc488a7ee097fec39d (patch)
treeff92fe55869e683ce0978621983b723d7095235e /src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
parentvulkan_device: Require shaderClipDistance and shaderCullDistance features (diff)
downloadyuzu-50eb03382e8ac8eb4aeb7cdc488a7ee097fec39d.tar.gz
yuzu-50eb03382e8ac8eb4aeb7cdc488a7ee097fec39d.tar.xz
yuzu-50eb03382e8ac8eb4aeb7cdc488a7ee097fec39d.zip
shader: Fix error checking in bitfieldExtract and implement bitfieldInsert folding
Diffstat (limited to 'src/shader_recompiler/ir_opt/constant_propagation_pass.cpp')
-rw-r--r--src/shader_recompiler/ir_opt/constant_propagation_pass.cpp19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
index 770d3de61..f16c5e8f6 100644
--- a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
+++ b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
@@ -553,7 +553,7 @@ void ConstantPropagation(IR::Block& block, IR::Inst& inst) {
553 return; 553 return;
554 case IR::Opcode::BitFieldUExtract: 554 case IR::Opcode::BitFieldUExtract:
555 FoldWhenAllImmediates(inst, [](u32 base, u32 shift, u32 count) { 555 FoldWhenAllImmediates(inst, [](u32 base, u32 shift, u32 count) {
556 if (static_cast<size_t>(shift) + static_cast<size_t>(count) > Common::BitSize<u32>()) { 556 if (static_cast<size_t>(shift) + static_cast<size_t>(count) > 32) {
557 throw LogicError("Undefined result in {}({}, {}, {})", IR::Opcode::BitFieldUExtract, 557 throw LogicError("Undefined result in {}({}, {}, {})", IR::Opcode::BitFieldUExtract,
558 base, shift, count); 558 base, shift, count);
559 } 559 }
@@ -563,13 +563,22 @@ void ConstantPropagation(IR::Block& block, IR::Inst& inst) {
563 case IR::Opcode::BitFieldSExtract: 563 case IR::Opcode::BitFieldSExtract:
564 FoldWhenAllImmediates(inst, [](s32 base, u32 shift, u32 count) { 564 FoldWhenAllImmediates(inst, [](s32 base, u32 shift, u32 count) {
565 const size_t back_shift{static_cast<size_t>(shift) + static_cast<size_t>(count)}; 565 const size_t back_shift{static_cast<size_t>(shift) + static_cast<size_t>(count)};
566 if (back_shift > Common::BitSize<s32>()) { 566 const size_t left_shift{32 - back_shift};
567 const size_t right_shift{static_cast<size_t>(32 - count)};
568 if (back_shift >= 32 || left_shift >= 32 || right_shift >= 32) {
567 throw LogicError("Undefined result in {}({}, {}, {})", IR::Opcode::BitFieldSExtract, 569 throw LogicError("Undefined result in {}({}, {}, {})", IR::Opcode::BitFieldSExtract,
568 base, shift, count); 570 base, shift, count);
569 } 571 }
570 const size_t left_shift{Common::BitSize<s32>() - back_shift}; 572 return static_cast<u32>((base << left_shift) >> right_shift);
571 return static_cast<u32>(static_cast<s32>(base << left_shift) >> 573 });
572 static_cast<size_t>(Common::BitSize<s32>() - count)); 574 return;
575 case IR::Opcode::BitFieldInsert:
576 FoldWhenAllImmediates(inst, [](u32 base, u32 insert, u32 offset, u32 bits) {
577 if (bits >= 32 || offset >= 32) {
578 throw LogicError("Undefined result in {}({}, {}, {}, {})",
579 IR::Opcode::BitFieldInsert, base, insert, offset, bits);
580 }
581 return (base & ~(~(~0u << bits) << offset)) | (insert << offset);
573 }); 582 });
574 return; 583 return;
575 case IR::Opcode::BranchConditional: 584 case IR::Opcode::BranchConditional: