From 539e92d6bb3fcc19872d406d755a9708fb393c02 Mon Sep 17 00:00:00 2001 From: cy <766079883@qq.com> Date: Wed, 6 May 2026 14:59:03 +0800 Subject: [PATCH] =?UTF-8?q?fix(mir):=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=A4=A7=E6=95=B0=E7=BB=84=E7=9A=84=E6=8E=92=E5=BA=8F=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mir/Lowering.cpp | 75 +++++++++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 21 deletions(-) diff --git a/src/mir/Lowering.cpp b/src/mir/Lowering.cpp index 01cefd6..f86a587 100644 --- a/src/mir/Lowering.cpp +++ b/src/mir/Lowering.cpp @@ -202,21 +202,33 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct case ir::Opcode::Store: { auto& store = static_cast(inst); - if (dynamic_cast(store.GetPtr())) { + // 如果指针是 GEP,手动生成地址并 store,避免额外计算 + if (auto* gep = dynamic_cast(store.GetPtr())) { + // 值 -> T2 EmitValueToReg(store.GetValue(), PhysReg::T2, slots, block); - EmitValueToReg(store.GetPtr(), PhysReg::T0, slots, block, true); - block.Append(Opcode::StoreIndirect, - {Operand::Reg(PhysReg::T2), Operand::Reg(PhysReg::T0)}); + // 基址 -> T0 (for_address=true) + EmitValueToReg(gep->GetBasePtr(), PhysReg::T0, slots, block, true); + // 索引直接从栈槽加载(避免递归产生副作用) + auto idx_it = slots.find(gep->GetIndex()); + if (idx_it != slots.end()) { + block.Append(Opcode::Load, {Operand::Reg(PhysReg::T1), Operand::FrameIndex(idx_it->second)}); + } else { + EmitValueToReg(gep->GetIndex(), PhysReg::T1, slots, block); + } + // 左移2位 -> 乘4 + block.Append(Opcode::Slli, {Operand::Reg(PhysReg::T1), Operand::Reg(PhysReg::T1), Operand::Imm(2)}); + // 地址相加 + block.Append(Opcode::Add, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T1)}); + // store + block.Append(Opcode::StoreIndirect, {Operand::Reg(PhysReg::T2), Operand::Reg(PhysReg::T0)}); return; } if (auto* global = dynamic_cast(store.GetPtr())) { EmitValueToReg(store.GetValue(), PhysReg::T0, slots, block); std::string global_name = global->GetName(); - block.Append(Opcode::StoreGlobal, - {Operand::Reg(PhysReg::T0), Operand::Global(global_name)}); + block.Append(Opcode::StoreGlobal, {Operand::Reg(PhysReg::T0), Operand::Global(global_name)}); return; } - auto dst = slots.find(store.GetPtr()); if (dst != slots.end()) { EmitValueToReg(store.GetValue(), PhysReg::T0, slots, block); @@ -228,7 +240,25 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct case ir::Opcode::Load: { auto& load = static_cast(inst); - + if (auto* gep = dynamic_cast(load.GetPtr())) { + // 基址 -> T0 + EmitValueToReg(gep->GetBasePtr(), PhysReg::T0, slots, block, true); + // 索引 -> T1 + auto idx_it = slots.find(gep->GetIndex()); + if (idx_it != slots.end()) { + block.Append(Opcode::Load, {Operand::Reg(PhysReg::T1), Operand::FrameIndex(idx_it->second)}); + } else { + EmitValueToReg(gep->GetIndex(), PhysReg::T1, slots, block); + } + block.Append(Opcode::Slli, {Operand::Reg(PhysReg::T1), Operand::Reg(PhysReg::T1), Operand::Imm(2)}); + block.Append(Opcode::Add, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T1)}); + // load 到 T0,然后存储到新槽 + block.Append(Opcode::LoadIndirect, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0)}); + int dst_slot = function.CreateFrameIndex(4); + StoreRegToSlot(PhysReg::T0, dst_slot, block, false); + slots.emplace(&inst, dst_slot); + return; + } if (dynamic_cast(load.GetPtr())) { EmitValueToReg(load.GetPtr(), PhysReg::T0, slots, block, true); block.Append(Opcode::LoadIndirect, @@ -401,26 +431,29 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T1)}); break; - case ir::ICmpPredicate::SLE: - block.Append(Opcode::Slt, {Operand::Reg(PhysReg::T1), - Operand::Reg(PhysReg::T1), - Operand::Reg(PhysReg::T0)}); - block.Append(Opcode::Xori, {Operand::Reg(PhysReg::T0), - Operand::Reg(PhysReg::T1), - Operand::Imm(1)}); - break; case ir::ICmpPredicate::SGT: block.Append(Opcode::Slt, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T1), Operand::Reg(PhysReg::T0)}); break; case ir::ICmpPredicate::SGE: - block.Append(Opcode::Slt, {Operand::Reg(PhysReg::T1), - Operand::Reg(PhysReg::T1), - Operand::Reg(PhysReg::T0)}); + // lhs >= rhs 等价于 !(lhs < rhs) + block.Append(Opcode::Slt, {Operand::Reg(PhysReg::T0), + Operand::Reg(PhysReg::T0), + Operand::Reg(PhysReg::T1)}); block.Append(Opcode::Xori, {Operand::Reg(PhysReg::T0), - Operand::Reg(PhysReg::T1), - Operand::Imm(1)}); + Operand::Reg(PhysReg::T0), + Operand::Imm(1)}); + break; + + case ir::ICmpPredicate::SLE: + // lhs <= rhs 等价于 !(rhs < lhs) + block.Append(Opcode::Slt, {Operand::Reg(PhysReg::T0), + Operand::Reg(PhysReg::T1), + Operand::Reg(PhysReg::T0)}); // 注意操作数顺序:rhs < lhs + block.Append(Opcode::Xori, {Operand::Reg(PhysReg::T0), + Operand::Reg(PhysReg::T0), + Operand::Imm(1)}); break; }