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/astoir_mir/src/builder.rs b/compiler/astoir_mir/src/builder.rs index 2b8322b5..7dad1422 100644 --- a/compiler/astoir_mir/src/builder.rs +++ b/compiler/astoir_mir/src/builder.rs @@ -81,42 +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, 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, fast, left, right }).get()?; return res.as_int(); } @@ -139,48 +149,57 @@ 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, 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, fast, 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..066b776b 100644 --- a/compiler/astoir_mir/src/insts/mod.rs +++ b/compiler/astoir_mir/src/insts/mod.rs @@ -23,17 +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 }, + 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) @@ -138,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)), @@ -219,17 +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::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 181e9cd0..de846e21 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}; @@ -50,12 +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::ShiftRight => build_shift_right(&mut ctx.mir_ctx, left, right)?, + MathOperatorType::Modulo => build_int_mod(&mut ctx.mir_ctx, left, right, signed, operator.fast)? }; return Ok(res.into()); @@ -68,10 +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::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()) }; diff --git a/compiler/llvm_ir_bridge/src/insts.rs b/compiler/llvm_ir_bridge/src/insts.rs index b9fb59ed..4776f669 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,26 @@ 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 { + 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()) }, - 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 +60,17 @@ 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 { + 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()) }, - 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 +79,17 @@ 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 { + 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()) }, - 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 +104,39 @@ 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 { + 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()) }, - MIRInstruction::FloatAdd { signed: _, left, right } => { + MIRInstruction::IntegerMod { 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>; + + 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(), "")) + } + + if fast { + llvm_to_base_returnless!(res.as_instruction_value().unwrap().set_fast_math_flags(FastMathFlags::all())) + } + + Some(res.into()) + } + + MIRInstruction::FloatAdd { signed: _, fast, left, right } => { let left: BaseMIRValue = MIRFloatValue::into(left); let right: BaseMIRValue = MIRFloatValue::into(right); @@ -95,10 +145,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); @@ -107,10 +161,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); @@ -119,10 +177,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); @@ -131,9 +193,29 @@ 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: _, fast, 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(), "")); + + if fast { + llvm_to_base_returnless!(res.as_instruction_value().unwrap().set_fast_math_flags(FastMathFlags::all())) + } + + Some(res.into()) + } + MIRInstruction::BitwiseAnd { a, b } => { let left: BaseMIRValue = MIRIntValue::into(a); let right: BaseMIRValue = MIRIntValue::into(b);