From fcf5366b112eade0b4458233eaca13e235570755 Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 14 Apr 2026 01:49:28 +0200 Subject: [PATCH 1/5] feat: added mod operator --- compiler/astoir_mir/src/builder.rs | 19 +++++++++++++++++++ compiler/astoir_mir/src/insts/mod.rs | 2 ++ compiler/astoir_mir_lowering/src/math.rs | 6 ++++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/compiler/astoir_mir/src/builder.rs b/compiler/astoir_mir/src/builder.rs index 2b8322b5..22ed2017 100644 --- a/compiler/astoir_mir/src/builder.rs +++ b/compiler/astoir_mir/src/builder.rs @@ -121,6 +121,16 @@ pub fn build_int_div(ctx: &mut MIRContext, left: MIRIntValue, right: MIRIntValue return res.as_int(); } +pub fn build_int_mod(ctx: &mut MIRContext, left: MIRIntValue, right: MIRIntValue, signed: bool) -> DiagnosticResult { + if left.size != right.size { + unsure_panic!("Tried using imod on different sized integers"); + } + + let res = ctx.append_inst(MIRInstruction::IntegerMod { signed, left, right }).get()?; + + return res.as_int(); +} + pub fn build_int_shift_left(ctx: &mut MIRContext, left: MIRIntValue, shift: MIRIntValue) -> DiagnosticResult { let res = ctx.append_inst(MIRInstruction::ShiftLeft { a: left, shift }).get()?; @@ -181,6 +191,15 @@ pub fn build_float_div(ctx: &mut MIRContext, left: MIRFloatValue, right: MIRFloa return res.as_float(); } +pub fn build_float_mod(ctx: &mut MIRContext, left: MIRFloatValue, right: MIRFloatValue, signed: bool) -> DiagnosticResult { + if left.size != right.size { + unsure_panic!("Tried using fmod on different sized integers"); + } + + let res = ctx.append_inst(MIRInstruction::FloatMod { signed, left, right }).get()?; + + return res.as_float(); +} pub fn build_float_neg(ctx: &mut MIRContext, val: MIRFloatValue) -> DiagnosticResult { let res = ctx.append_inst(MIRInstruction::FloatNeg { val }).get()?; diff --git a/compiler/astoir_mir/src/insts/mod.rs b/compiler/astoir_mir/src/insts/mod.rs index dbb271a3..d3ec5c2b 100644 --- a/compiler/astoir_mir/src/insts/mod.rs +++ b/compiler/astoir_mir/src/insts/mod.rs @@ -34,6 +34,7 @@ pub enum MIRInstruction { FloatSub { signed: bool, left: MIRFloatValue, right: MIRFloatValue }, FloatMul { signed: bool, left: MIRFloatValue, right: MIRFloatValue }, FloatDiv { signed: bool, left: MIRFloatValue, right: MIRFloatValue }, + FloatMod { signed: bool, left: MIRFloatValue, right: MIRFloatValue }, FloatNeg { val: MIRFloatValue }, // Bitwise (int typed) @@ -230,6 +231,7 @@ impl Display for MIRInstruction { Self::FloatSub { signed, left, right } => writeln!(f, "fsub s{} {} {}", signed, left, right)?, Self::FloatMul { signed, left, right } => writeln!(f, "fmul s{} {} {}", signed, left, right)?, Self::FloatDiv { signed, left, right } => writeln!(f, "fdiv s{} {} {}", signed, left, right)?, + Self::FloatMod { signed, left, right } => writeln!(f, "fmod s{} {} {}", signed, left, right)?, Self::FloatNeg { val } => writeln!(f, "fneg {}", val)?, Self::BitwiseAnd { a, b } => writeln!(f, "and {} {}", a, b)?, diff --git a/compiler/astoir_mir_lowering/src/math.rs b/compiler/astoir_mir_lowering/src/math.rs index 181e9cd0..3c625ef2 100644 --- a/compiler/astoir_mir_lowering/src/math.rs +++ b/compiler/astoir_mir_lowering/src/math.rs @@ -1,5 +1,5 @@ use astoir_hir::nodes::{HIRNode, HIRNodeKind}; -use astoir_mir::{blocks::refer::MIRBlockReference, builder::{build_float_add, build_float_div, build_float_mul, build_float_sub, build_int_add, build_int_div, build_int_mul, build_int_sub, build_shift_left, build_shift_right}, vals::base::BaseMIRValue}; +use astoir_mir::{blocks::refer::MIRBlockReference, builder::{build_float_add, build_float_div, build_float_mod, build_float_mul, build_float_sub, build_int_add, build_int_div, build_int_mod, build_int_mul, build_int_sub, build_shift_left, build_shift_right}, vals::base::BaseMIRValue}; use compiler_typing::raw::RawType; use compiler_utils::operators::{MathOperator, MathOperatorType}; use diagnostics::{DiagnosticResult, builders::{make_math_operation_req_assign, make_req_type_kind}, unsure_panic}; @@ -55,7 +55,8 @@ pub fn lower_hir_math_operation_int(left: BaseMIRValue, right: BaseMIRValue, ope MathOperatorType::Multiply => build_int_mul(&mut ctx.mir_ctx, left, right, signed)?, MathOperatorType::Divide => build_int_div(&mut ctx.mir_ctx, left, right, signed)?, MathOperatorType::ShiftLeft => build_shift_left(&mut ctx.mir_ctx, left, right)?, - MathOperatorType::ShiftRight => build_shift_right(&mut ctx.mir_ctx, left, right)? + MathOperatorType::ShiftRight => build_shift_right(&mut ctx.mir_ctx, left, right)?, + MathOperatorType::Modulo => build_int_mod(&mut ctx.mir_ctx, left, right, signed)? }; return Ok(res.into()); @@ -72,6 +73,7 @@ pub fn lower_hir_math_operation_float(left: BaseMIRValue, right: BaseMIRValue, o MathOperatorType::Subtract => build_float_sub(&mut ctx.mir_ctx, left, right, signed)?, MathOperatorType::Multiply => build_float_mul(&mut ctx.mir_ctx, left, right, signed)?, MathOperatorType::Divide => build_float_div(&mut ctx.mir_ctx, left, right, signed)?, + MathOperatorType::Modulo => build_float_mod(&mut ctx.mir_ctx, left, right, signed)?, _ => return Err(make_req_type_kind(node, &"integer".to_string()).into()) }; From 2370907ffa610500f27ca661689b64734a1a38fd Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 14 Apr 2026 01:53:17 +0200 Subject: [PATCH 2/5] feat: added mod operator in LLVM bridge --- compiler/llvm_ir_bridge/src/insts.rs | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/compiler/llvm_ir_bridge/src/insts.rs b/compiler/llvm_ir_bridge/src/insts.rs index b9fb59ed..3cb6af0e 100644 --- a/compiler/llvm_ir_bridge/src/insts.rs +++ b/compiler/llvm_ir_bridge/src/insts.rs @@ -86,6 +86,24 @@ pub fn bridge_llvm_instruction(instruction: MIRBlockHeldInstruction, func: usize Some(res.into()) }, + MIRInstruction::IntegerMod { signed, left, right } => { + let left: BaseMIRValue = MIRIntValue::into(left); + let right: BaseMIRValue = MIRIntValue::into(right); + + let l = bridge.values[&left.get_ssa_index()].clone(); + let r = bridge.values[&right.get_ssa_index()].clone(); + + let res: IntValue<'static>; + + if signed { + res = llvm_to_base!(bridge.builder.build_int_signed_rem(l.into_int_value(), r.into_int_value(), "")) + } else { + res = llvm_to_base!(bridge.builder.build_int_unsigned_rem(l.into_int_value(), r.into_int_value(), "")) + } + + Some(res.into()) + } + MIRInstruction::FloatAdd { signed: _, left, right } => { let left: BaseMIRValue = MIRFloatValue::into(left); let right: BaseMIRValue = MIRFloatValue::into(right); @@ -134,6 +152,18 @@ pub fn bridge_llvm_instruction(instruction: MIRBlockHeldInstruction, func: usize Some(res.into()) }, + MIRInstruction::FloatMod { signed: _, left, right } => { + let left: BaseMIRValue = MIRFloatValue::into(left); + let right: BaseMIRValue = MIRFloatValue::into(right); + + let l = bridge.values[&left.get_ssa_index()].clone(); + let r = bridge.values[&right.get_ssa_index()].clone(); + + let res: FloatValue<'static> = llvm_to_base!(bridge.builder.build_float_rem(l.into_float_value(), r.into_float_value(), "")); + + Some(res.into()) + } + MIRInstruction::BitwiseAnd { a, b } => { let left: BaseMIRValue = MIRIntValue::into(a); let right: BaseMIRValue = MIRIntValue::into(b); From a820db905459c9d500aab05113ba3a9d04585363 Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 14 Apr 2026 11:48:17 +0200 Subject: [PATCH 3/5] feat: added fast math flags on MIR instructions --- compiler/astoir_mir/src/builder.rs | 40 ++++++++-------- compiler/astoir_mir/src/insts/mod.rs | 58 ++++++++++++------------ compiler/astoir_mir_lowering/src/math.rs | 20 ++++---- 3 files changed, 59 insertions(+), 59 deletions(-) diff --git a/compiler/astoir_mir/src/builder.rs b/compiler/astoir_mir/src/builder.rs index 22ed2017..7dad1422 100644 --- a/compiler/astoir_mir/src/builder.rs +++ b/compiler/astoir_mir/src/builder.rs @@ -81,52 +81,52 @@ pub fn build_upcast_float(ctx: &mut MIRContext, val: MIRFloatValue, size: usize) return res.as_float(); } -pub fn build_int_add(ctx: &mut MIRContext, left: MIRIntValue, right: MIRIntValue, signed: bool) -> DiagnosticResult { +pub fn build_int_add(ctx: &mut MIRContext, left: MIRIntValue, right: MIRIntValue, signed: bool, fast: bool) -> DiagnosticResult { if left.size != right.size { unsure_panic!("Tried using iadd on different sized integers"); } - let res = ctx.append_inst(MIRInstruction::IntegerAdd { signed, left, right }).get()?; + let res = ctx.append_inst(MIRInstruction::IntegerAdd { signed, fast, left, right }).get()?; return res.as_int(); } -pub fn build_int_sub(ctx: &mut MIRContext, left: MIRIntValue, right: MIRIntValue, signed: bool) -> DiagnosticResult { +pub fn build_int_sub(ctx: &mut MIRContext, left: MIRIntValue, right: MIRIntValue, signed: bool, fast: bool) -> DiagnosticResult { if left.size != right.size { unsure_panic!("Tried using isub on different sized integers"); } - let res = ctx.append_inst(MIRInstruction::IntegerSub { signed, left, right }).get()?; + let res = ctx.append_inst(MIRInstruction::IntegerSub { signed, fast, left, right }).get()?; return res.as_int(); } -pub fn build_int_mul(ctx: &mut MIRContext, left: MIRIntValue, right: MIRIntValue, signed: bool) -> DiagnosticResult { +pub fn build_int_mul(ctx: &mut MIRContext, left: MIRIntValue, right: MIRIntValue, signed: bool, fast: bool) -> DiagnosticResult { if left.size != right.size { unsure_panic!("Tried using imul on different sized integers"); } - let res = ctx.append_inst(MIRInstruction::IntegerMul { signed, left, right }).get()?; + let res = ctx.append_inst(MIRInstruction::IntegerMul { signed, fast, left, right }).get()?; return res.as_int(); } -pub fn build_int_div(ctx: &mut MIRContext, left: MIRIntValue, right: MIRIntValue, signed: bool) -> DiagnosticResult { +pub fn build_int_div(ctx: &mut MIRContext, left: MIRIntValue, right: MIRIntValue, signed: bool, fast: bool) -> DiagnosticResult { if left.size != right.size { unsure_panic!("Tried using idiv on different sized integers"); } - let res = ctx.append_inst(MIRInstruction::IntegerDiv { signed, left, right }).get()?; + let res = ctx.append_inst(MIRInstruction::IntegerDiv { signed, fast, left, right }).get()?; return res.as_int(); } -pub fn build_int_mod(ctx: &mut MIRContext, left: MIRIntValue, right: MIRIntValue, signed: bool) -> DiagnosticResult { +pub fn build_int_mod(ctx: &mut MIRContext, left: MIRIntValue, right: MIRIntValue, signed: bool, fast: bool) -> DiagnosticResult { if left.size != right.size { unsure_panic!("Tried using imod on different sized integers"); } - let res = ctx.append_inst(MIRInstruction::IntegerMod { signed, left, right }).get()?; + let res = ctx.append_inst(MIRInstruction::IntegerMod { signed, fast, left, right }).get()?; return res.as_int(); } @@ -149,54 +149,54 @@ pub fn build_int_neg(ctx: &mut MIRContext, val: MIRIntValue) -> DiagnosticResult return res.as_int(); } -pub fn build_float_add(ctx: &mut MIRContext, left: MIRFloatValue, right: MIRFloatValue, signed: bool) -> DiagnosticResult { +pub fn build_float_add(ctx: &mut MIRContext, left: MIRFloatValue, right: MIRFloatValue, signed: bool, fast: bool) -> DiagnosticResult { if left.size != right.size { unsure_panic!("Tried using fadd on different sized integers"); } - let res = ctx.append_inst(MIRInstruction::FloatAdd { signed, left, right }).get()?; + let res = ctx.append_inst(MIRInstruction::FloatAdd { signed, fast, left, right }).get()?; return res.as_float(); } -pub fn build_float_sub(ctx: &mut MIRContext, left: MIRFloatValue, right: MIRFloatValue, signed: bool) -> DiagnosticResult { +pub fn build_float_sub(ctx: &mut MIRContext, left: MIRFloatValue, right: MIRFloatValue, signed: bool, fast: bool) -> DiagnosticResult { if left.size != right.size { unsure_panic!("Tried using fsub on different sized integers"); } - let res = ctx.append_inst(MIRInstruction::FloatSub { signed, left, right }).get()?; + let res = ctx.append_inst(MIRInstruction::FloatSub { signed, fast, left, right }).get()?; return res.as_float(); } -pub fn build_float_mul(ctx: &mut MIRContext, left: MIRFloatValue, right: MIRFloatValue, signed: bool) -> DiagnosticResult { +pub fn build_float_mul(ctx: &mut MIRContext, left: MIRFloatValue, right: MIRFloatValue, signed: bool, fast: bool) -> DiagnosticResult { if left.size != right.size { unsure_panic!("Tried using fmul on different sized integers"); } - let res = ctx.append_inst(MIRInstruction::FloatMul { signed, left, right }).get()?; + let res = ctx.append_inst(MIRInstruction::FloatMul { signed, fast, left, right }).get()?; return res.as_float(); } -pub fn build_float_div(ctx: &mut MIRContext, left: MIRFloatValue, right: MIRFloatValue, signed: bool) -> DiagnosticResult { +pub fn build_float_div(ctx: &mut MIRContext, left: MIRFloatValue, right: MIRFloatValue, signed: bool, fast: bool) -> DiagnosticResult { if left.size != right.size { unsure_panic!("Tried using fdiv on different sized integers"); } - let res = ctx.append_inst(MIRInstruction::FloatDiv { signed, left, right }).get()?; + let res = ctx.append_inst(MIRInstruction::FloatDiv { signed, fast, left, right }).get()?; return res.as_float(); } -pub fn build_float_mod(ctx: &mut MIRContext, left: MIRFloatValue, right: MIRFloatValue, signed: bool) -> DiagnosticResult { +pub fn build_float_mod(ctx: &mut MIRContext, left: MIRFloatValue, right: MIRFloatValue, signed: bool, fast: bool) -> DiagnosticResult { if left.size != right.size { unsure_panic!("Tried using fmod on different sized integers"); } - let res = ctx.append_inst(MIRInstruction::FloatMod { signed, left, right }).get()?; + let res = ctx.append_inst(MIRInstruction::FloatMod { signed, fast, left, right }).get()?; return res.as_float(); } diff --git a/compiler/astoir_mir/src/insts/mod.rs b/compiler/astoir_mir/src/insts/mod.rs index d3ec5c2b..066b776b 100644 --- a/compiler/astoir_mir/src/insts/mod.rs +++ b/compiler/astoir_mir/src/insts/mod.rs @@ -23,18 +23,18 @@ pub enum MIRInstruction { UpcastFloat { val: MIRFloatValue, size: usize }, // Arithmetrics - IntegerAdd { signed: bool, left: MIRIntValue, right: MIRIntValue }, - IntegerSub { signed: bool, left: MIRIntValue, right: MIRIntValue }, - IntegerMul { signed: bool, left: MIRIntValue, right: MIRIntValue }, - IntegerDiv { signed: bool, left: MIRIntValue, right: MIRIntValue }, - IntegerMod { signed: bool, left: MIRIntValue, right: MIRIntValue }, + IntegerAdd { signed: bool, fast: bool, left: MIRIntValue, right: MIRIntValue }, + IntegerSub { signed: bool, fast: bool, left: MIRIntValue, right: MIRIntValue }, + IntegerMul { signed: bool, fast: bool, left: MIRIntValue, right: MIRIntValue }, + IntegerDiv { signed: bool, fast: bool, left: MIRIntValue, right: MIRIntValue }, + IntegerMod { signed: bool, fast: bool, left: MIRIntValue, right: MIRIntValue }, IntegerNeg { val: MIRIntValue }, - FloatAdd { signed: bool, left: MIRFloatValue, right: MIRFloatValue }, - FloatSub { signed: bool, left: MIRFloatValue, right: MIRFloatValue }, - FloatMul { signed: bool, left: MIRFloatValue, right: MIRFloatValue }, - FloatDiv { signed: bool, left: MIRFloatValue, right: MIRFloatValue }, - FloatMod { signed: bool, left: MIRFloatValue, right: MIRFloatValue }, + FloatAdd { signed: bool, fast: bool, left: MIRFloatValue, right: MIRFloatValue }, + FloatSub { signed: bool, fast: bool, left: MIRFloatValue, right: MIRFloatValue }, + FloatMul { signed: bool, fast: bool, left: MIRFloatValue, right: MIRFloatValue }, + FloatDiv { signed: bool, fast: bool, left: MIRFloatValue, right: MIRFloatValue }, + FloatMod { signed: bool, fast: bool, left: MIRFloatValue, right: MIRFloatValue }, FloatNeg { val: MIRFloatValue }, // Bitwise (int typed) @@ -139,17 +139,17 @@ impl MIRInstruction { Self::DowncastFloat { val, size } => return Type::GenericLowered(RawType::Floating(*size, val.signed)), Self::UpcastFloat { val, size } => return Type::GenericLowered(RawType::Floating(*size, val.signed)), - Self::IntegerAdd { signed, left, right: _ } => return Type::GenericLowered(RawType::Integer(left.size, *signed)), - Self::IntegerSub { signed, left, right: _ } => return Type::GenericLowered(RawType::Integer(left.size, *signed)), - Self::IntegerMul { signed, left, right: _ } => return Type::GenericLowered(RawType::Integer(left.size, *signed)), - Self::IntegerDiv { signed, left, right: _ } => return Type::GenericLowered(RawType::Integer(left.size, *signed)), - Self::IntegerMod { signed, left, right: _ } => return Type::GenericLowered(RawType::Integer(left.size, *signed)), + Self::IntegerAdd { signed, fast: _, left, right: _ } => return Type::GenericLowered(RawType::Integer(left.size, *signed)), + Self::IntegerSub { signed, fast: _, left, right: _ } => return Type::GenericLowered(RawType::Integer(left.size, *signed)), + Self::IntegerMul { signed, fast: _, left, right: _ } => return Type::GenericLowered(RawType::Integer(left.size, *signed)), + Self::IntegerDiv { signed, fast: _, left, right: _ } => return Type::GenericLowered(RawType::Integer(left.size, *signed)), + Self::IntegerMod { signed, fast: _, left, right: _ } => return Type::GenericLowered(RawType::Integer(left.size, *signed)), Self::IntegerNeg { val } => return Type::GenericLowered(RawType::Integer(val.size, true)), - Self::FloatAdd { signed, left, right: _ } => return Type::GenericLowered(RawType::Floating(left.size, *signed)), - Self::FloatSub { signed, left, right: _ } => return Type::GenericLowered(RawType::Floating(left.size, *signed)), - Self::FloatMul { signed, left, right: _ } => return Type::GenericLowered(RawType::Floating(left.size, *signed)), - Self::FloatDiv { signed, left, right: _ } => return Type::GenericLowered(RawType::Floating(left.size, *signed)), + Self::FloatAdd { signed, fast: _, left, right: _ } => return Type::GenericLowered(RawType::Floating(left.size, *signed)), + Self::FloatSub { signed, fast: _, left, right: _ } => return Type::GenericLowered(RawType::Floating(left.size, *signed)), + Self::FloatMul { signed, fast: _, left, right: _ } => return Type::GenericLowered(RawType::Floating(left.size, *signed)), + Self::FloatDiv { signed, fast: _, left, right: _ } => return Type::GenericLowered(RawType::Floating(left.size, *signed)), Self::FloatNeg { val } => return Type::GenericLowered(RawType::Floating(val.size, true)), Self::BitwiseAnd { a, b: _ } => return Type::GenericLowered(RawType::Integer(a.size, a.signed)), @@ -220,18 +220,18 @@ impl Display for MIRInstruction { Self::UpcastInteger { val, size } => writeln!(f, "uintcast {} {}", val, size)?, Self::UpcastFloat { val, size } => writeln!(f, "ufcast {} {}", val, size)?, - Self::IntegerAdd { signed, left, right } => writeln!(f, "iadd s{} {} {}", signed, left, right)?, - Self::IntegerSub { signed, left, right } => writeln!(f, "isub s{} {} {}", signed, left, right)?, - Self::IntegerMul { signed, left, right } => writeln!(f, "imul s{} {} {}", signed, left, right)?, - Self::IntegerDiv { signed, left, right } => writeln!(f, "idiv s{} {} {}", signed, left, right)?, - Self::IntegerMod { signed, left, right } => writeln!(f, "imod s{} {} {}", signed, left, right)?, + Self::IntegerAdd { signed, fast, left, right } => writeln!(f, "iadd s{} f{} {} {}", signed, fast, left, right)?, + Self::IntegerSub { signed, fast, left, right } => writeln!(f, "isub s{} f{} {} {}", signed, fast, left, right)?, + Self::IntegerMul { signed, fast, left, right } => writeln!(f, "imul s{} f{} {} {}", signed, fast, left, right)?, + Self::IntegerDiv { signed, fast, left, right } => writeln!(f, "idiv s{} f{} {} {}", signed, fast, left, right)?, + Self::IntegerMod { signed, fast, left, right } => writeln!(f, "imod s{} f{} {} {}", signed, fast, left, right)?, Self::IntegerNeg { val } => writeln!(f, "ineg {}", val)?, - Self::FloatAdd { signed, left, right } => writeln!(f, "fadd s{} {} {}", signed, left, right)?, - Self::FloatSub { signed, left, right } => writeln!(f, "fsub s{} {} {}", signed, left, right)?, - Self::FloatMul { signed, left, right } => writeln!(f, "fmul s{} {} {}", signed, left, right)?, - Self::FloatDiv { signed, left, right } => writeln!(f, "fdiv s{} {} {}", signed, left, right)?, - Self::FloatMod { signed, left, right } => writeln!(f, "fmod s{} {} {}", signed, left, right)?, + Self::FloatAdd { signed, fast, left, right } => writeln!(f, "fadd s{} f{} {} {}", signed, fast, left, right)?, + Self::FloatSub { signed, fast, left, right } => writeln!(f, "fsub s{} f{} {} {}", signed, fast, left, right)?, + Self::FloatMul { signed, fast, left, right } => writeln!(f, "fmul s{} f{} {} {}", signed, fast, left, right)?, + Self::FloatDiv { signed, fast, left, right } => writeln!(f, "fdiv s{} f{} {} {}", signed, fast, left, right)?, + Self::FloatMod { signed, fast, left, right } => writeln!(f, "fmod s{} f{} {} {}", signed, fast, left, right)?, Self::FloatNeg { val } => writeln!(f, "fneg {}", val)?, Self::BitwiseAnd { a, b } => writeln!(f, "and {} {}", a, b)?, diff --git a/compiler/astoir_mir_lowering/src/math.rs b/compiler/astoir_mir_lowering/src/math.rs index 3c625ef2..de846e21 100644 --- a/compiler/astoir_mir_lowering/src/math.rs +++ b/compiler/astoir_mir_lowering/src/math.rs @@ -50,13 +50,13 @@ pub fn lower_hir_math_operation_int(left: BaseMIRValue, right: BaseMIRValue, ope let signed = left.signed; let res = match operator.operator { - MathOperatorType::Add => build_int_add(&mut ctx.mir_ctx, left, right, signed)?, - MathOperatorType::Subtract => build_int_sub(&mut ctx.mir_ctx, left, right, signed)?, - MathOperatorType::Multiply => build_int_mul(&mut ctx.mir_ctx, left, right, signed)?, - MathOperatorType::Divide => build_int_div(&mut ctx.mir_ctx, left, right, signed)?, + MathOperatorType::Add => build_int_add(&mut ctx.mir_ctx, left, right, signed, operator.fast)?, + MathOperatorType::Subtract => build_int_sub(&mut ctx.mir_ctx, left, right, signed, operator.fast)?, + MathOperatorType::Multiply => build_int_mul(&mut ctx.mir_ctx, left, right, signed, operator.fast)?, + MathOperatorType::Divide => build_int_div(&mut ctx.mir_ctx, left, right, signed, operator.fast)?, MathOperatorType::ShiftLeft => build_shift_left(&mut ctx.mir_ctx, left, right)?, MathOperatorType::ShiftRight => build_shift_right(&mut ctx.mir_ctx, left, right)?, - MathOperatorType::Modulo => build_int_mod(&mut ctx.mir_ctx, left, right, signed)? + MathOperatorType::Modulo => build_int_mod(&mut ctx.mir_ctx, left, right, signed, operator.fast)? }; return Ok(res.into()); @@ -69,11 +69,11 @@ pub fn lower_hir_math_operation_float(left: BaseMIRValue, right: BaseMIRValue, o let signed = left.signed; let res = match operator.operator { - MathOperatorType::Add => build_float_add(&mut ctx.mir_ctx, left, right, signed)?, - MathOperatorType::Subtract => build_float_sub(&mut ctx.mir_ctx, left, right, signed)?, - MathOperatorType::Multiply => build_float_mul(&mut ctx.mir_ctx, left, right, signed)?, - MathOperatorType::Divide => build_float_div(&mut ctx.mir_ctx, left, right, signed)?, - MathOperatorType::Modulo => build_float_mod(&mut ctx.mir_ctx, left, right, signed)?, + MathOperatorType::Add => build_float_add(&mut ctx.mir_ctx, left, right, signed, operator.fast)?, + MathOperatorType::Subtract => build_float_sub(&mut ctx.mir_ctx, left, right, signed, operator.fast)?, + MathOperatorType::Multiply => build_float_mul(&mut ctx.mir_ctx, left, right, signed, operator.fast)?, + MathOperatorType::Divide => build_float_div(&mut ctx.mir_ctx, left, right, signed, operator.fast)?, + MathOperatorType::Modulo => build_float_mod(&mut ctx.mir_ctx, left, right, signed, operator.fast)?, _ => return Err(make_req_type_kind(node, &"integer".to_string()).into()) }; From 434c1bd7874ac5261a731e0e2244b4e725153563 Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 14 Apr 2026 12:10:02 +0200 Subject: [PATCH 4/5] feat: added fast math to llvm bridge --- compiler/ast/src/operators.rs | 8 +++- compiler/ast_parser/src/math.rs | 4 +- compiler/llvm_ir_bridge/src/insts.rs | 66 ++++++++++++++++++++++------ 3 files changed, 61 insertions(+), 17 deletions(-) diff --git a/compiler/ast/src/operators.rs b/compiler/ast/src/operators.rs index 3a33dfc8..6faf3123 100644 --- a/compiler/ast/src/operators.rs +++ b/compiler/ast/src/operators.rs @@ -38,14 +38,18 @@ pub fn parse_math_operator(tokens: &Vec, ind: &mut usize) -> Diagnos _ => false }; - *ind += 1; + if assigns { + *ind += 1; + } let fast = match tokens[*ind].tok_type { LexerTokenType::Tidle => true, _ => false }; - *ind += 1; + if fast { + *ind += 1; + } return Ok(MathOperator { operator: op, assigns, fast }); } diff --git a/compiler/ast_parser/src/math.rs b/compiler/ast_parser/src/math.rs index bb7469d9..ad6664d3 100644 --- a/compiler/ast_parser/src/math.rs +++ b/compiler/ast_parser/src/math.rs @@ -10,8 +10,8 @@ pub fn parse_math_operation(tokens: &Vec, ind: &mut usize, original: if !oper.assigns && restricts_to_assigns { return Err(tokens[*ind].make_simple_diagnostic(MATH_OPERATION_ASSIGNS.0, Level::Error, MATH_OPERATION_ASSIGNS.1.to_string(), None, vec![], vec!["consider assigning this to variable".to_string()], vec!["add = at the end of the operator".to_string()]).into()) } - - *ind += 1; + + println!("{:#?}", tokens[*ind].tok_type); let right_member = parse_ast_value(tokens, ind)?; diff --git a/compiler/llvm_ir_bridge/src/insts.rs b/compiler/llvm_ir_bridge/src/insts.rs index 3cb6af0e..cb41af95 100644 --- a/compiler/llvm_ir_bridge/src/insts.rs +++ b/compiler/llvm_ir_bridge/src/insts.rs @@ -1,6 +1,6 @@ -use astoir_mir::{blocks::MIRBlockHeldInstruction, ctx::MIRContext, insts::MIRInstruction, vals::{base::BaseMIRValue, float::{MIRFloatValue}, int::MIRIntValue, ptr::MIRPointerValue}}; +use astoir_mir::{blocks::MIRBlockHeldInstruction, ctx::MIRContext, insts::{MIRInstruction}, vals::{base::BaseMIRValue, float::MIRFloatValue, int::MIRIntValue, ptr::MIRPointerValue}}; use compiler_typing::{raw::RawType}; -use inkwell::{IntPredicate, module::Linkage, types::{BasicType, BasicTypeEnum, StringRadix}, values::{BasicValue, BasicValueEnum, FloatValue, IntValue}}; +use inkwell::{IntPredicate, module::Linkage, types::{BasicType, BasicTypeEnum, StringRadix}, values::{BasicValue, BasicValueEnum, FastMathFlags, FloatValue, IntValue}}; use crate::{ctx::LLVMBridgeContext, llvm_to_base, llvm_to_base_returnless, utils::LLVMBasicValue}; @@ -32,19 +32,23 @@ pub fn bridge_llvm_instruction(instruction: MIRBlockHeldInstruction, func: usize None } - MIRInstruction::IntegerAdd { signed: _, left, right } => { + MIRInstruction::IntegerAdd { signed: _, fast, left, right } => { let left: BaseMIRValue = MIRIntValue::into(left); let right: BaseMIRValue = MIRIntValue::into(right); let l = bridge.values[&left.get_ssa_index()].clone(); let r = bridge.values[&right.get_ssa_index()].clone(); - let res: IntValue<'static> = llvm_to_base!(bridge.builder.build_int_add(l.into_int_value(), r.into_int_value(), "")); + let res = llvm_to_base!(bridge.builder.build_int_add(l.into_int_value(), r.into_int_value(), "")); + + if fast { + llvm_to_base_returnless!(res.as_instruction_value().unwrap().set_fast_math_flags(FastMathFlags::all())) + } Some(res.into()) }, - MIRInstruction::IntegerSub { signed: _, left, right } => { + MIRInstruction::IntegerSub { signed: _, fast, left, right } => { let left: BaseMIRValue = MIRIntValue::into(left); let right: BaseMIRValue = MIRIntValue::into(right); @@ -53,10 +57,14 @@ pub fn bridge_llvm_instruction(instruction: MIRBlockHeldInstruction, func: usize let res: IntValue<'static> = llvm_to_base!(bridge.builder.build_int_sub(l.into_int_value(), r.into_int_value(), "")); + if fast { + llvm_to_base_returnless!(res.as_instruction_value().unwrap().set_fast_math_flags(FastMathFlags::all())) + } + Some(res.into()) }, - MIRInstruction::IntegerMul { signed: _, left, right } => { + MIRInstruction::IntegerMul { signed: _, fast, left, right } => { let left: BaseMIRValue = MIRIntValue::into(left); let right: BaseMIRValue = MIRIntValue::into(right); @@ -65,10 +73,14 @@ pub fn bridge_llvm_instruction(instruction: MIRBlockHeldInstruction, func: usize let res: IntValue<'static> = llvm_to_base!(bridge.builder.build_int_mul(l.into_int_value(), r.into_int_value(), "")); + if fast { + llvm_to_base_returnless!(res.as_instruction_value().unwrap().set_fast_math_flags(FastMathFlags::all())) + } + Some(res.into()) }, - MIRInstruction::IntegerDiv { signed, left, right } => { + MIRInstruction::IntegerDiv { signed, fast, left, right } => { let left: BaseMIRValue = MIRIntValue::into(left); let right: BaseMIRValue = MIRIntValue::into(right); @@ -83,10 +95,14 @@ pub fn bridge_llvm_instruction(instruction: MIRBlockHeldInstruction, func: usize res = llvm_to_base!(bridge.builder.build_int_unsigned_div(l.into_int_value(), r.into_int_value(), "")) } + if fast { + llvm_to_base_returnless!(res.as_instruction_value().unwrap().set_fast_math_flags(FastMathFlags::all())) + } + Some(res.into()) }, - MIRInstruction::IntegerMod { signed, left, right } => { + MIRInstruction::IntegerMod { signed, fast, left, right } => { let left: BaseMIRValue = MIRIntValue::into(left); let right: BaseMIRValue = MIRIntValue::into(right); @@ -101,10 +117,14 @@ pub fn bridge_llvm_instruction(instruction: MIRBlockHeldInstruction, func: usize res = llvm_to_base!(bridge.builder.build_int_unsigned_rem(l.into_int_value(), r.into_int_value(), "")) } + if fast { + llvm_to_base_returnless!(res.as_instruction_value().unwrap().set_fast_math_flags(FastMathFlags::all())) + } + Some(res.into()) } - MIRInstruction::FloatAdd { signed: _, left, right } => { + MIRInstruction::FloatAdd { signed: _, fast, left, right } => { let left: BaseMIRValue = MIRFloatValue::into(left); let right: BaseMIRValue = MIRFloatValue::into(right); @@ -113,10 +133,14 @@ pub fn bridge_llvm_instruction(instruction: MIRBlockHeldInstruction, func: usize let res: FloatValue<'static> = llvm_to_base!(bridge.builder.build_float_add(l.into_float_value(), r.into_float_value(), "")); + if fast { + llvm_to_base_returnless!(res.as_instruction_value().unwrap().set_fast_math_flags(FastMathFlags::all())) + } + Some(res.into()) }, - MIRInstruction::FloatSub { signed: _, left, right } => { + MIRInstruction::FloatSub { signed: _, fast, left, right } => { let left: BaseMIRValue = MIRFloatValue::into(left); let right: BaseMIRValue = MIRFloatValue::into(right); @@ -125,10 +149,14 @@ pub fn bridge_llvm_instruction(instruction: MIRBlockHeldInstruction, func: usize let res: FloatValue<'static> = llvm_to_base!(bridge.builder.build_float_sub(l.into_float_value(), r.into_float_value(), "")); + if fast { + llvm_to_base_returnless!(res.as_instruction_value().unwrap().set_fast_math_flags(FastMathFlags::all())) + } + Some(res.into()) }, - MIRInstruction::FloatMul { signed: _, left, right } => { + MIRInstruction::FloatMul { signed: _, fast, left, right } => { let left: BaseMIRValue = MIRFloatValue::into(left); let right: BaseMIRValue = MIRFloatValue::into(right); @@ -137,10 +165,14 @@ pub fn bridge_llvm_instruction(instruction: MIRBlockHeldInstruction, func: usize let res: FloatValue<'static> = llvm_to_base!(bridge.builder.build_float_mul(l.into_float_value(), r.into_float_value(), "")); + if fast { + llvm_to_base_returnless!(res.as_instruction_value().unwrap().set_fast_math_flags(FastMathFlags::all())) + } + Some(res.into()) }, - MIRInstruction::FloatDiv { signed: _, left, right } => { + MIRInstruction::FloatDiv { signed: _, fast, left, right } => { let left: BaseMIRValue = MIRFloatValue::into(left); let right: BaseMIRValue = MIRFloatValue::into(right); @@ -149,10 +181,14 @@ pub fn bridge_llvm_instruction(instruction: MIRBlockHeldInstruction, func: usize let res: FloatValue<'static> = llvm_to_base!(bridge.builder.build_float_div(l.into_float_value(), r.into_float_value(), "")); + if fast { + llvm_to_base_returnless!(res.as_instruction_value().unwrap().set_fast_math_flags(FastMathFlags::all())) + } + Some(res.into()) }, - MIRInstruction::FloatMod { signed: _, left, right } => { + MIRInstruction::FloatMod { signed: _, fast, left, right } => { let left: BaseMIRValue = MIRFloatValue::into(left); let right: BaseMIRValue = MIRFloatValue::into(right); @@ -161,6 +197,10 @@ pub fn bridge_llvm_instruction(instruction: MIRBlockHeldInstruction, func: usize let res: FloatValue<'static> = llvm_to_base!(bridge.builder.build_float_rem(l.into_float_value(), r.into_float_value(), "")); + if fast { + llvm_to_base_returnless!(res.as_instruction_value().unwrap().set_fast_math_flags(FastMathFlags::all())) + } + Some(res.into()) } From a19bfd6f26a76ce3ff09615d2893825280183b8e Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 14 Apr 2026 12:16:07 +0200 Subject: [PATCH 5/5] feat: added int fastmath --- compiler/llvm_ir_bridge/src/insts.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/compiler/llvm_ir_bridge/src/insts.rs b/compiler/llvm_ir_bridge/src/insts.rs index cb41af95..4776f669 100644 --- a/compiler/llvm_ir_bridge/src/insts.rs +++ b/compiler/llvm_ir_bridge/src/insts.rs @@ -42,7 +42,10 @@ pub fn bridge_llvm_instruction(instruction: MIRBlockHeldInstruction, func: usize let res = llvm_to_base!(bridge.builder.build_int_add(l.into_int_value(), r.into_int_value(), "")); if fast { - llvm_to_base_returnless!(res.as_instruction_value().unwrap().set_fast_math_flags(FastMathFlags::all())) + let res2 = res.as_instruction_value().unwrap(); + + llvm_to_base_returnless!(res2.set_no_signed_wrap_flag(true)); + llvm_to_base_returnless!(res2.set_no_unsigned_wrap_flag(true)); } Some(res.into()) @@ -58,7 +61,10 @@ pub fn bridge_llvm_instruction(instruction: MIRBlockHeldInstruction, func: usize let res: IntValue<'static> = llvm_to_base!(bridge.builder.build_int_sub(l.into_int_value(), r.into_int_value(), "")); if fast { - llvm_to_base_returnless!(res.as_instruction_value().unwrap().set_fast_math_flags(FastMathFlags::all())) + let res2 = res.as_instruction_value().unwrap(); + + llvm_to_base_returnless!(res2.set_no_signed_wrap_flag(true)); + llvm_to_base_returnless!(res2.set_no_unsigned_wrap_flag(true)); } Some(res.into()) @@ -74,7 +80,10 @@ pub fn bridge_llvm_instruction(instruction: MIRBlockHeldInstruction, func: usize let res: IntValue<'static> = llvm_to_base!(bridge.builder.build_int_mul(l.into_int_value(), r.into_int_value(), "")); if fast { - llvm_to_base_returnless!(res.as_instruction_value().unwrap().set_fast_math_flags(FastMathFlags::all())) + let res2 = res.as_instruction_value().unwrap(); + + llvm_to_base_returnless!(res2.set_no_signed_wrap_flag(true)); + llvm_to_base_returnless!(res2.set_no_unsigned_wrap_flag(true)); } Some(res.into()) @@ -96,9 +105,12 @@ pub fn bridge_llvm_instruction(instruction: MIRBlockHeldInstruction, func: usize } if fast { - llvm_to_base_returnless!(res.as_instruction_value().unwrap().set_fast_math_flags(FastMathFlags::all())) - } + let res2 = res.as_instruction_value().unwrap(); + llvm_to_base_returnless!(res2.set_no_signed_wrap_flag(true)); + llvm_to_base_returnless!(res2.set_no_unsigned_wrap_flag(true)); + llvm_to_base_returnless!(res2.set_exact_flag(true)); + } Some(res.into()) },