fix(mir):修复部分大数组的排序错误

develop
cy 3 days ago
parent 2660960674
commit 539e92d6bb

@ -202,21 +202,33 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct
case ir::Opcode::Store: {
auto& store = static_cast<const ir::StoreInst&>(inst);
if (dynamic_cast<const ir::GepInst*>(store.GetPtr())) {
// 如果指针是 GEP手动生成地址并 store避免额外计算
if (auto* gep = dynamic_cast<const ir::GepInst*>(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<const ir::GlobalVariable*>(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<const ir::LoadInst&>(inst);
if (auto* gep = dynamic_cast<const ir::GepInst*>(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<const ir::GepInst*>(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;
}

Loading…
Cancel
Save