diff options
author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2021-04-23 13:17:53 +0200 |
---|---|---|
committer | ameerj <52414509+ameerj@users.noreply.github.com> | 2021-07-23 03:51:29 +0200 |
commit | 50eb03382e8ac8eb4aeb7cdc488a7ee097fec39d (patch) | |
tree | ff92fe55869e683ce0978621983b723d7095235e /src/shader_recompiler/ir_opt/constant_propagation_pass.cpp | |
parent | vulkan_device: Require shaderClipDistance and shaderCullDistance features (diff) | |
download | yuzu-50eb03382e8ac8eb4aeb7cdc488a7ee097fec39d.tar yuzu-50eb03382e8ac8eb4aeb7cdc488a7ee097fec39d.tar.gz yuzu-50eb03382e8ac8eb4aeb7cdc488a7ee097fec39d.tar.bz2 yuzu-50eb03382e8ac8eb4aeb7cdc488a7ee097fec39d.tar.lz yuzu-50eb03382e8ac8eb4aeb7cdc488a7ee097fec39d.tar.xz yuzu-50eb03382e8ac8eb4aeb7cdc488a7ee097fec39d.tar.zst yuzu-50eb03382e8ac8eb4aeb7cdc488a7ee097fec39d.zip |
Diffstat (limited to 'src/shader_recompiler/ir_opt/constant_propagation_pass.cpp')
-rw-r--r-- | src/shader_recompiler/ir_opt/constant_propagation_pass.cpp | 19 |
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) { return; case IR::Opcode::BitFieldUExtract: FoldWhenAllImmediates(inst, [](u32 base, u32 shift, u32 count) { - if (static_cast<size_t>(shift) + static_cast<size_t>(count) > Common::BitSize<u32>()) { + if (static_cast<size_t>(shift) + static_cast<size_t>(count) > 32) { throw LogicError("Undefined result in {}({}, {}, {})", IR::Opcode::BitFieldUExtract, base, shift, count); } @@ -563,13 +563,22 @@ void ConstantPropagation(IR::Block& block, IR::Inst& inst) { case IR::Opcode::BitFieldSExtract: FoldWhenAllImmediates(inst, [](s32 base, u32 shift, u32 count) { const size_t back_shift{static_cast<size_t>(shift) + static_cast<size_t>(count)}; - if (back_shift > Common::BitSize<s32>()) { + const size_t left_shift{32 - back_shift}; + const size_t right_shift{static_cast<size_t>(32 - count)}; + if (back_shift >= 32 || left_shift >= 32 || right_shift >= 32) { throw LogicError("Undefined result in {}({}, {}, {})", IR::Opcode::BitFieldSExtract, base, shift, count); } - const size_t left_shift{Common::BitSize<s32>() - back_shift}; - return static_cast<u32>(static_cast<s32>(base << left_shift) >> - static_cast<size_t>(Common::BitSize<s32>() - count)); + return static_cast<u32>((base << left_shift) >> right_shift); + }); + return; + case IR::Opcode::BitFieldInsert: + FoldWhenAllImmediates(inst, [](u32 base, u32 insert, u32 offset, u32 bits) { + if (bits >= 32 || offset >= 32) { + throw LogicError("Undefined result in {}({}, {}, {}, {})", + IR::Opcode::BitFieldInsert, base, insert, offset, bits); + } + return (base & ~(~(~0u << bits) << offset)) | (insert << offset); }); return; case IR::Opcode::BranchConditional: |