From aa726199528a79069f41136ef14e774b6ae6d848 Mon Sep 17 00:00:00 2001 From: Chad Stearns Date: Sun, 26 Apr 2020 14:38:09 -0400 Subject: [PATCH 1/2] Implemenet code gen for int div --- compiler/builtins/src/std.rs | 16 +++++++++++----- compiler/gen/src/llvm/build.rs | 11 +++++++++++ compiler/gen/tests/gen_builtins.rs | 13 +++++++++++++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/compiler/builtins/src/std.rs b/compiler/builtins/src/std.rs index a4824de997..32e904cae1 100644 --- a/compiler/builtins/src/std.rs +++ b/compiler/builtins/src/std.rs @@ -285,13 +285,19 @@ pub fn types() -> MutMap { Box::new(SolvedType::Wildcard), ); - // div : Int, Int -> Result Int [ DivByZero ]* + // // div : Int, Int -> Result Int [ DivByZero ]* + // add_type( + // Symbol::INT_DIV, + // SolvedType::Func( + // vec![int_type(), int_type()], + // Box::new(result_type(flex(TVAR1), div_by_zero.clone())), + // ), + // ); + + // div : Int, Int -> Int add_type( Symbol::INT_DIV, - SolvedType::Func( - vec![int_type(), int_type()], - Box::new(result_type(flex(TVAR1), div_by_zero.clone())), - ), + SolvedType::Func(vec![int_type(), int_type()], Box::new(int_type())), ); // mod : Int, Int -> Result Int [ DivByZero ]* diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index 8a9eafe24c..dec36276d8 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -1226,6 +1226,17 @@ fn call_with_args<'a, 'ctx, 'env>( Symbol::FLOAT_ROUND => call_intrinsic(LLVM_LROUND_I64_F64, env, args), Symbol::LIST_SET => list_set(parent, args, env, InPlace::Clone), Symbol::LIST_SET_IN_PLACE => list_set(parent, args, env, InPlace::InPlace), + Symbol::INT_DIV => { + debug_assert!(args.len() == 2); + + let int_val = env.builder.build_int_signed_div( + args[0].0.into_int_value(), + args[1].0.into_int_value(), + "div_i64", + ); + + BasicValueEnum::IntValue(int_val) + } _ => { let fn_val = env .module diff --git a/compiler/gen/tests/gen_builtins.rs b/compiler/gen/tests/gen_builtins.rs index f97dc20c50..1243c60eba 100644 --- a/compiler/gen/tests/gen_builtins.rs +++ b/compiler/gen/tests/gen_builtins.rs @@ -159,6 +159,19 @@ mod gen_builtins { ); } + #[test] + fn gen_div_i64() { + assert_evals_to!( + indoc!( + r#" + 1000 // 100 + "# + ), + 10, + i64 + ); + } + #[test] fn gen_order_of_arithmetic_ops() { assert_evals_to!( From 0cfed050086931d536cfd6000dd171fed502b7b1 Mon Sep 17 00:00:00 2001 From: Chad Stearns Date: Sun, 26 Apr 2020 18:11:46 -0400 Subject: [PATCH 2/2] Implemented div unsafe --- compiler/builtins/src/std.rs | 18 +++++++++--------- compiler/builtins/src/unique.rs | 16 +++++++++++++++- compiler/gen/src/llvm/build.rs | 2 +- compiler/gen/tests/gen_builtins.rs | 2 +- compiler/module/src/symbol.rs | 1 + compiler/solve/tests/test_uniq_solve.rs | 9 +++++---- 6 files changed, 32 insertions(+), 16 deletions(-) diff --git a/compiler/builtins/src/std.rs b/compiler/builtins/src/std.rs index 32e904cae1..d56c982feb 100644 --- a/compiler/builtins/src/std.rs +++ b/compiler/builtins/src/std.rs @@ -285,18 +285,18 @@ pub fn types() -> MutMap { Box::new(SolvedType::Wildcard), ); - // // div : Int, Int -> Result Int [ DivByZero ]* - // add_type( - // Symbol::INT_DIV, - // SolvedType::Func( - // vec![int_type(), int_type()], - // Box::new(result_type(flex(TVAR1), div_by_zero.clone())), - // ), - // ); + // div : Int, Int -> Result Int [ DivByZero ]* + add_type( + Symbol::INT_DIV, + SolvedType::Func( + vec![int_type(), int_type()], + Box::new(result_type(flex(TVAR1), div_by_zero.clone())), + ), + ); // div : Int, Int -> Int add_type( - Symbol::INT_DIV, + Symbol::INT_DIV_UNSAFE, SolvedType::Func(vec![int_type(), int_type()], Box::new(int_type())), ); diff --git a/compiler/builtins/src/unique.rs b/compiler/builtins/src/unique.rs index 56d6fead90..3d544da621 100644 --- a/compiler/builtins/src/unique.rs +++ b/compiler/builtins/src/unique.rs @@ -348,9 +348,23 @@ pub fn types() -> MutMap { // lowest : Int add_type(Symbol::INT_LOWEST, int_type(UVAR1)); - // div or (//) : Int, Int -> Int + // div or (//) : Int, Int -> Result Int [ DivByZero ]* + let div_by_zero = SolvedType::TagUnion( + vec![(TagName::Global("DivByZero".into()), vec![])], + Box::new(SolvedType::Wildcard), + ); + add_type( Symbol::INT_DIV, + unique_function( + vec![int_type(UVAR1), int_type(UVAR2)], + result_type(UVAR3, int_type(UVAR4), lift(UVAR5, div_by_zero)), + ), + ); + + // div or (//) : Int, Int -> Int + add_type( + Symbol::INT_DIV_UNSAFE, unique_function(vec![int_type(UVAR1), int_type(UVAR2)], int_type(UVAR3)), ); diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index dec36276d8..005fde49f0 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -1226,7 +1226,7 @@ fn call_with_args<'a, 'ctx, 'env>( Symbol::FLOAT_ROUND => call_intrinsic(LLVM_LROUND_I64_F64, env, args), Symbol::LIST_SET => list_set(parent, args, env, InPlace::Clone), Symbol::LIST_SET_IN_PLACE => list_set(parent, args, env, InPlace::InPlace), - Symbol::INT_DIV => { + Symbol::INT_DIV_UNSAFE => { debug_assert!(args.len() == 2); let int_val = env.builder.build_int_signed_div( diff --git a/compiler/gen/tests/gen_builtins.rs b/compiler/gen/tests/gen_builtins.rs index 1243c60eba..a1d53057fe 100644 --- a/compiler/gen/tests/gen_builtins.rs +++ b/compiler/gen/tests/gen_builtins.rs @@ -164,7 +164,7 @@ mod gen_builtins { assert_evals_to!( indoc!( r#" - 1000 // 100 + Int.divUnsafe 1000 100 "# ), 10, diff --git a/compiler/module/src/symbol.rs b/compiler/module/src/symbol.rs index dc8bdd1084..5efbbdddc8 100644 --- a/compiler/module/src/symbol.rs +++ b/compiler/module/src/symbol.rs @@ -599,6 +599,7 @@ define_builtins! { 9 INT_EQ_I64: "#eqi64" // Equality on 64-bit integers, the standard in Roc 10 INT_EQ_I1: "#eqi1" // Equality on boolean (theoretically i1) values 11 INT_EQ_I8: "#eqi8" // Equality on byte (theoretically i8) values + 12 INT_DIV_UNSAFE: "divUnsafe" // TODO remove once we can code gen Result } 3 FLOAT: "Float" => { 0 FLOAT_FLOAT: "Float" imported // the Float.Float type alias diff --git a/compiler/solve/tests/test_uniq_solve.rs b/compiler/solve/tests/test_uniq_solve.rs index 5586ddf3cd..b168ea44d0 100644 --- a/compiler/solve/tests/test_uniq_solve.rs +++ b/compiler/solve/tests/test_uniq_solve.rs @@ -1944,7 +1944,7 @@ mod test_uniq_solve { Int.highest // Int.highest "# ), - "Attr * Int", + "Attr * (Result (Attr * Int) (Attr * [ DivByZero ]*))", ); } @@ -1956,7 +1956,7 @@ mod test_uniq_solve { 3 // 4 "# ), - "Attr * Int", + "Attr * (Result (Attr * Int) (Attr * [ DivByZero ]*))", ); } @@ -1968,7 +1968,7 @@ mod test_uniq_solve { 3 // Int.highest "# ), - "Attr * Int", + "Attr * (Result (Attr * Int) (Attr * [ DivByZero ]*))", ); } @@ -2097,7 +2097,8 @@ mod test_uniq_solve { reverse "# ), - "Attr * (Attr * (List (Attr (a | b) c)) -> Attr (* | a | b) (List (Attr b c)))", + "Attr * (Attr * (List (Attr (a | b) c)) -> Attr (* | a | b) (List (Attr a c)))", + // "Attr * (Attr * (List (Attr (a | b) c)) -> Attr (* | a | b) (List (Attr b c)))", //"Attr * (Attr * (List (Attr (a | b) c)) -> Attr (* | a | b) (List (Attr a c)))", ); }