[backend]解决了非零数组初始化不正确的问题

This commit is contained in:
Lixuanwang
2025-07-22 00:07:54 +08:00
parent c45938d41d
commit 9c87cb397b

View File

@ -238,7 +238,52 @@ void RISCv64ISel::selectNode(DAGNode* node) {
auto bin = dynamic_cast<BinaryInst*>(node->value); auto bin = dynamic_cast<BinaryInst*>(node->value);
Value* lhs = bin->getLhs(); Value* lhs = bin->getLhs();
Value* rhs = bin->getRhs(); Value* rhs = bin->getRhs();
// 检查是否是“基地址+偏移量”的地址计算模式
if (bin->getKind() == BinaryInst::kAdd) {
Value* base = nullptr;
Value* offset = nullptr;
// 判断哪个是基地址AllocaInst哪个是偏移量
if (dynamic_cast<AllocaInst*>(lhs)) {
base = lhs;
offset = rhs;
} else if (dynamic_cast<AllocaInst*>(rhs)) {
base = rhs;
offset = lhs;
}
// 如果成功匹配到该模式
if (base) {
// [最终修复]
// 1. 先为偏移量加载常量(如果它是常量的话)
if (auto const_offset = dynamic_cast<ConstantValue*>(offset)) {
auto li = std::make_unique<MachineInstr>(RVOpcodes::LI);
li->addOperand(std::make_unique<RegOperand>(getVReg(const_offset)));
li->addOperand(std::make_unique<ImmOperand>(const_offset->getInt()));
CurMBB->addInstruction(std::move(li));
}
// 2. 使用FRAME_ADDR伪指令来获取基地址
auto base_addr_vreg = getNewVReg(); // 创建一个新的临时vreg来存放基地址
auto frame_addr_instr = std::make_unique<MachineInstr>(RVOpcodes::FRAME_ADDR);
frame_addr_instr->addOperand(std::make_unique<RegOperand>(base_addr_vreg));
frame_addr_instr->addOperand(std::make_unique<RegOperand>(getVReg(base)));
CurMBB->addInstruction(std::move(frame_addr_instr));
// 3. 生成真正的add指令计算最终地址
auto final_addr_vreg = getVReg(bin); // 这是整个二元运算的结果vreg
auto offset_vreg = getVReg(offset);
auto add_instr = std::make_unique<MachineInstr>(RVOpcodes::ADD); // 指针运算是64位
add_instr->addOperand(std::make_unique<RegOperand>(final_addr_vreg));
add_instr->addOperand(std::make_unique<RegOperand>(base_addr_vreg));
add_instr->addOperand(std::make_unique<RegOperand>(offset_vreg));
CurMBB->addInstruction(std::move(add_instr));
return; // 地址计算处理完毕,直接返回
}
}
// [V2优点] 在BINARY节点内部按需加载常量操作数。 // [V2优点] 在BINARY节点内部按需加载常量操作数。
auto load_val_if_const = [&](Value* val) { auto load_val_if_const = [&](Value* val) {
if (auto c = dynamic_cast<ConstantValue*>(val)) { if (auto c = dynamic_cast<ConstantValue*>(val)) {