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; }