From 035f83b2097c221f3de83cfc8ae00a8f274555a9 Mon Sep 17 00:00:00 2001 From: lzkk <956449176@qq.com> Date: Thu, 28 May 2026 02:38:07 +0800 Subject: [PATCH] =?UTF-8?q?fix(mir):=20=E6=A8=A12^n=20AND=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E2=80=94=E2=80=94=E4=BF=AE=E5=A4=8D=20x<0=20=E4=B8=94?= =?UTF-8?q?=20x%2^n=3D=3D0=20=E6=97=B6=E7=9A=84=E9=9B=B6=E5=80=BC=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -4%2 应得 0,但 AND+符号修正路径算出 -2。 增加 cmp masked,#0; csel dst,wzr,temp,EQ 零值保护。 平台无 -O 时该路径被触发,导致 48_assign_complex_expr WA。 --- src/mir/Lowering.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/mir/Lowering.cpp b/src/mir/Lowering.cpp index 80dcf320..03dfb230 100644 --- a/src/mir/Lowering.cpp +++ b/src/mir/Lowering.cpp @@ -606,11 +606,21 @@ namespace mir Operand::VReg(masked, VRegClass::Int), Operand::VReg(val_reg, VRegClass::Int)}); } + int after_sign = function.CreateVReg(VRegClass::Int); block.Append(Opcode::Csel, - {Operand::VReg(dst, VRegClass::Int), + {Operand::VReg(after_sign, VRegClass::Int), Operand::VReg(neg_fixup, VRegClass::Int), Operand::VReg(masked, VRegClass::Int), Operand::Imm(static_cast(CondCode::LT))}); + // 修正:若 masked==0 则结果必须为 0(-4 % 2 = 0,不是 -2) + block.Append(Opcode::CmpImm, + {Operand::VReg(masked, VRegClass::Int), + Operand::Imm(0)}); + block.Append(Opcode::Csel, + {Operand::VReg(dst, VRegClass::Int), + Operand::Reg(PhysReg::WZR), + Operand::VReg(after_sign, VRegClass::Int), + Operand::Imm(static_cast(CondCode::EQ))}); value_vregs[value] = dst; return dst; } @@ -660,11 +670,21 @@ namespace mir Operand::VReg(masked, VRegClass::Int), Operand::VReg(val_reg, VRegClass::Int)}); } + int after_sign2 = function.CreateVReg(VRegClass::Int); block.Append(Opcode::Csel, - {Operand::VReg(dst, VRegClass::Int), + {Operand::VReg(after_sign2, VRegClass::Int), Operand::VReg(neg_fixup, VRegClass::Int), Operand::VReg(masked, VRegClass::Int), Operand::Imm(static_cast(CondCode::LT))}); + // 修正:若 masked==0 则结果必须为 0 + block.Append(Opcode::CmpImm, + {Operand::VReg(masked, VRegClass::Int), + Operand::Imm(0)}); + block.Append(Opcode::Csel, + {Operand::VReg(dst, VRegClass::Int), + Operand::Reg(PhysReg::WZR), + Operand::VReg(after_sign2, VRegClass::Int), + Operand::Imm(static_cast(CondCode::EQ))}); value_vregs[value] = dst; return dst; }