[backend]解决了非零数组初始化不正确的问题
This commit is contained in:
@ -238,7 +238,52 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
||||
auto bin = dynamic_cast<BinaryInst*>(node->value);
|
||||
Value* lhs = bin->getLhs();
|
||||
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节点内部按需加载常量操作数。
|
||||
auto load_val_if_const = [&](Value* val) {
|
||||
if (auto c = dynamic_cast<ConstantValue*>(val)) {
|
||||
|
||||
Reference in New Issue
Block a user