diff --git a/src/ir/passes/Inline.cpp b/src/ir/passes/Inline.cpp index 373fa652..dc5a346b 100644 --- a/src/ir/passes/Inline.cpp +++ b/src/ir/passes/Inline.cpp @@ -192,6 +192,40 @@ static bool TryConvertIfElseToSelect(Function* func, Context& ctx) { Value* cmp_val = br->GetCond(); + // 穿透冗余链 icmp ne (zext(X), 0) → X + // IR 生成器将 condbr 条件包裹为 icmp ne (zext(原始比较), 0),消除它 + if (auto* outer_cmp = dynamic_cast(cmp_val)) + { + if (outer_cmp->GetOpcode() == Opcode::Ne) + { + auto* rhs_c = dynamic_cast(outer_cmp->GetRhs()); + if (rhs_c && rhs_c->GetValue() == 0) + { + if (auto* zext = dynamic_cast(outer_cmp->GetLhs())) + { + if (zext->GetOpcode() == Opcode::ZExt) + cmp_val = zext->GetOperandValue(); + } + } + } + } + // 二次穿透(部分 IR 结构有两层包裹) + if (auto* outer_cmp = dynamic_cast(cmp_val)) + { + if (outer_cmp->GetOpcode() == Opcode::Ne) + { + auto* rhs_c = dynamic_cast(outer_cmp->GetRhs()); + if (rhs_c && rhs_c->GetValue() == 0) + { + if (auto* zext = dynamic_cast(outer_cmp->GetLhs())) + { + if (zext->GetOpcode() == Opcode::ZExt) + cmp_val = zext->GetOperandValue(); + } + } + } + } + // 移除 CondBr entry->TakeInstruction(br); diff --git a/src/mir/Lowering.cpp b/src/mir/Lowering.cpp index 13b8aea4..28d65cb4 100644 --- a/src/mir/Lowering.cpp +++ b/src/mir/Lowering.cpp @@ -659,6 +659,69 @@ namespace mir } } + // Div/Mod/And/Or 常量提前处理——避免先 emit rhs 再发现不需要的死 MovImm + if (opcode == Opcode::DivRR || opcode == Opcode::ModRR || + opcode == Opcode::AndRR || opcode == Opcode::OrRR) + { + if (auto *rhs_const = dynamic_cast(bin->GetRhs())) + { + int val = rhs_const->GetValue(); + // 提前处理 Div/Mod 的 1/-1 和 %2 情况,不 emit rhs + if (opcode == Opcode::DivRR && val == 1) + { + value_vregs[value] = lhs; + return lhs; + } + if (opcode == Opcode::DivRR && val == -1) + { + block.Append(Opcode::NegRR, + {Operand::VReg(dst, VRegClass::Int), + Operand::VReg(lhs, VRegClass::Int)}); + value_vregs[value] = dst; + return dst; + } + // Mod by 2(含正负):and+cmp+csneg,不 emit rhs + if (opcode == Opcode::ModRR && (val == 2 || val == -2)) + { + int pos = function.CreateVReg(VRegClass::Int); + block.Append(Opcode::AndRR, + {Operand::VReg(pos, VRegClass::Int), + Operand::VReg(lhs, VRegClass::Int), + Operand::Imm(1)}); + block.Append(Opcode::CmpImm, + {Operand::VReg(lhs, VRegClass::Int), + Operand::Imm(0)}); + block.Append(Opcode::Csneg, + {Operand::VReg(dst, VRegClass::Int), + Operand::VReg(pos, VRegClass::Int), + Operand::VReg(pos, VRegClass::Int), + Operand::Imm(static_cast(CondCode::GE))}); + value_vregs[value] = dst; + return dst; + } + // And with constant → 直接嵌入立即数,不 emit rhs + if (opcode == Opcode::AndRR && val >= 0 && static_cast(val) <= 4095) + { + block.Append(Opcode::AndRR, + {Operand::VReg(dst, VRegClass::Int), + Operand::VReg(lhs, VRegClass::Int), + Operand::Imm(val)}); + value_vregs[value] = dst; + return dst; + } + // Or with constant → 直接嵌入立即数,不 emit rhs + if (opcode == Opcode::OrRR && val >= 0 && static_cast(val) <= 4095) + { + block.Append(Opcode::OrRR, + {Operand::VReg(dst, VRegClass::Int), + Operand::VReg(lhs, VRegClass::Int), + Operand::Imm(val)}); + value_vregs[value] = dst; + return dst; + } + } + } + int rhs = EmitIntValue(bin->GetRhs(), function, value_vregs, scalar_slots, array_slots, block); @@ -806,8 +869,30 @@ namespace mir int val = rhs_const->GetValue(); if (val > 0 && (val & (val - 1)) == 0) { - // x % 2^n -> negs+and+and+csneg(4 指令,含零值正确语义) int mask = val - 1; + + // x % 2 快速路径:and+cmp+csneg ge(3 指令) + // bit 0 在取反下不变,无需第二个 and + if (mask == 1) + { + int pos = function.CreateVReg(VRegClass::Int); + block.Append(Opcode::AndRR, + {Operand::VReg(pos, VRegClass::Int), + Operand::VReg(lhs, VRegClass::Int), + Operand::Imm(1)}); + block.Append(Opcode::CmpImm, + {Operand::VReg(lhs, VRegClass::Int), + Operand::Imm(0)}); + block.Append(Opcode::Csneg, + {Operand::VReg(dst, VRegClass::Int), + Operand::VReg(pos, VRegClass::Int), + Operand::VReg(pos, VRegClass::Int), + Operand::Imm(static_cast(CondCode::GE))}); + value_vregs[value] = dst; + return dst; + } + + // x % 2^n (n>1) -> negs+and+and+csneg(4 指令,含零值正确语义) int neg = function.CreateVReg(VRegClass::Int); int pos = function.CreateVReg(VRegClass::Int); int neg_masked = function.CreateVReg(VRegClass::Int); @@ -847,8 +932,29 @@ namespace mir } if (val < 0 && (-val & (-val - 1)) == 0 && val != -1) { - // x % -2^n -> 同 x % 2^n,negs+and+and+csneg int mask = (-val) - 1; + + // x % -2 快速路径:and+cmp+csneg ge(3 指令) + if (mask == 1) + { + int pos = function.CreateVReg(VRegClass::Int); + block.Append(Opcode::AndRR, + {Operand::VReg(pos, VRegClass::Int), + Operand::VReg(lhs, VRegClass::Int), + Operand::Imm(1)}); + block.Append(Opcode::CmpImm, + {Operand::VReg(lhs, VRegClass::Int), + Operand::Imm(0)}); + block.Append(Opcode::Csneg, + {Operand::VReg(dst, VRegClass::Int), + Operand::VReg(pos, VRegClass::Int), + Operand::VReg(pos, VRegClass::Int), + Operand::Imm(static_cast(CondCode::GE))}); + value_vregs[value] = dst; + return dst; + } + + // x % -2^n (n>1) -> 同 x % 2^n,negs+and+and+csneg int neg = function.CreateVReg(VRegClass::Int); int pos = function.CreateVReg(VRegClass::Int); int neg_masked = function.CreateVReg(VRegClass::Int); @@ -1839,9 +1945,27 @@ namespace mir case ir::Opcode::GEP: return; + case ir::Opcode::Mul: + { + auto &bin = static_cast(inst); + if (IsFloatType(bin.GetType())) + { + EmitFloatValue(&bin, function, value_vregs, block); + return; + } + // 若 Mul 的唯一用户是 Add,推迟到 Add 的 Madd 折叠处理 + if (bin.GetUses().size() == 1) + { + auto *user = dynamic_cast(bin.GetUses().begin()->GetUser()); + if (user && user->GetOpcode() == ir::Opcode::Add) + return; + } + EmitIntValue(&bin, function, value_vregs, scalar_slots, array_slots, block); + return; + } + case ir::Opcode::Add: case ir::Opcode::Sub: - case ir::Opcode::Mul: case ir::Opcode::Div: case ir::Opcode::Mod: case ir::Opcode::And: