From 3d37a9a82324b35fcf1e27c4a20e929346513cbd Mon Sep 17 00:00:00 2001 From: Kishan-Ved Date: Mon, 26 Feb 2024 20:59:10 +0530 Subject: [PATCH 1/3] implemented lshift --- src/libasr/pass/intrinsic_function_registry.h | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/src/libasr/pass/intrinsic_function_registry.h b/src/libasr/pass/intrinsic_function_registry.h index 2fca01651d..9cd04a3da5 100644 --- a/src/libasr/pass/intrinsic_function_registry.h +++ b/src/libasr/pass/intrinsic_function_registry.h @@ -48,6 +48,7 @@ enum class IntrinsicScalarFunctions : int64_t { FMA, FlipSign, Mod, + LShift, Trailz, FloorDiv, ListIndex, @@ -122,6 +123,7 @@ inline std::string get_intrinsic_name(int x) { INTRINSIC_NAME_CASE(FlipSign) INTRINSIC_NAME_CASE(FloorDiv) INTRINSIC_NAME_CASE(Mod) + INTRINSIC_NAME_CASE(LShift) INTRINSIC_NAME_CASE(Trailz) INTRINSIC_NAME_CASE(ListIndex) INTRINSIC_NAME_CASE(Partition) @@ -2382,6 +2384,81 @@ namespace Mod { } // namespace Mod +#define i_BitRshift(n, bits, t) EXPR(ASR::make_IntegerBinOp_t(al, loc, \ + n, ASR::binopType::BitRShift, bits, t, nullptr)) +#define i_BitLshift(n, bits, t) EXPR(ASR::make_IntegerBinOp_t(al, loc, \ + n, ASR::binopType::BitLShift, bits, t, nullptr)) + +namespace LShift { + + static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { + ASRUtils::require_impl(x.n_args == 2, + "ASR Verify: Call to LShift must have exactly 2 arguments", + x.base.base.loc, diagnostics); + ASR::ttype_t *type1 = ASRUtils::expr_type(x.m_args[0]); + ASR::ttype_t *type2 = ASRUtils::expr_type(x.m_args[1]); + ASRUtils::require_impl((is_integer(*type1) && is_integer(*type2)), + "ASR Verify: Arguments to LShift must be of integer type", + x.base.base.loc, diagnostics); + } + + static ASR::expr_t *eval_LShift(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args) { + int64_t a = ASR::down_cast(args[0])->m_n; + int64_t b = ASR::down_cast(args[1])->m_n; + int64_t val = a << b; + return make_ConstantWithType(make_IntegerConstant_t, val, t1, loc); + } + + static inline ASR::asr_t* create_LShift(Allocator& al, const Location& loc, + Vec& args, + const std::function err) { + if (args.size() != 2) { + err("Intrinsic LShift function accepts exactly 2 arguments", loc); + } + ASR::ttype_t *type1 = ASRUtils::expr_type(args[0]); + ASR::ttype_t *type2 = ASRUtils::expr_type(args[1]); + if (!((ASRUtils::is_integer(*type1) && ASRUtils::is_integer(*type2)))) { + err("Argument of the LShift function must be Integer", + args[0]->base.loc); + } + ASR::expr_t *m_value = nullptr; + if (all_args_evaluated(args)) { + Vec arg_values; arg_values.reserve(al, 2); + arg_values.push_back(al, expr_value(args[0])); + arg_values.push_back(al, expr_value(args[1])); + m_value = eval_LShift(al, loc, expr_type(args[1]), arg_values); + } + return ASR::make_IntrinsicScalarFunction_t(al, loc, + static_cast(IntrinsicScalarFunctions::LShift), + args.p, args.n, 0, ASRUtils::expr_type(args[0]), m_value); + } + + static inline ASR::expr_t* instantiate_LShift(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_lshift_" + type_to_str_python(arg_types[1])); + fill_func_arg("a", arg_types[0]); + fill_func_arg("p", arg_types[1]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + function LShifti32i32(a, p) result(d) + integer(int32) :: a + integer(int32) :: b + result = a << b + return result + end function + */ + body.push_back(al, b.Assignment(result, i_BitLshift(args[0], args[1], arg_types[0]))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace LShift + namespace Trailz { static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { @@ -3665,6 +3742,8 @@ namespace IntrinsicScalarFunctionRegistry { {&FloorDiv::instantiate_FloorDiv, &FloorDiv::verify_args}}, {static_cast(IntrinsicScalarFunctions::Mod), {&Mod::instantiate_Mod, &Mod::verify_args}}, + {static_cast(IntrinsicScalarFunctions::LShift), + {&LShift::instantiate_LShift, &LShift::verify_args}}, {static_cast(IntrinsicScalarFunctions::Trailz), {&Trailz::instantiate_Trailz, &Trailz::verify_args}}, {static_cast(IntrinsicScalarFunctions::Abs), @@ -3793,6 +3872,8 @@ namespace IntrinsicScalarFunctionRegistry { "floordiv"}, {static_cast(IntrinsicScalarFunctions::Mod), "mod"}, + {static_cast(IntrinsicScalarFunctions::LShift), + "lshift"}, {static_cast(IntrinsicScalarFunctions::Trailz), "trailz"}, {static_cast(IntrinsicScalarFunctions::Expm1), @@ -3901,6 +3982,7 @@ namespace IntrinsicScalarFunctionRegistry { {"fma", {&FMA::create_FMA, &FMA::eval_FMA}}, {"floordiv", {&FloorDiv::create_FloorDiv, &FloorDiv::eval_FloorDiv}}, {"mod", {&Mod::create_Mod, &Mod::eval_Mod}}, + {"lshift", {&LShift::create_LShift, &LShift::eval_LShift}}, {"trailz", {&Trailz::create_Trailz, &Trailz::eval_Trailz}}, {"list.index", {&ListIndex::create_ListIndex, &ListIndex::eval_list_index}}, {"list.reverse", {&ListReverse::create_ListReverse, &ListReverse::eval_list_reverse}}, From 9a90e0c457cd0c0b02b547e24f8466b082d6a58b Mon Sep 17 00:00:00 2001 From: Kishan-Ved Date: Tue, 27 Feb 2024 18:33:36 +0530 Subject: [PATCH 2/3] integration test added --- integration_tests/CMakeLists.txt | 1 + integration_tests/intrinsics_03.py | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 integration_tests/intrinsics_03.py diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index 1177bb5266..19f8c7a014 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -816,6 +816,7 @@ RUN(NAME callback_04 IMPORT_PATH .. LABELS cpython) # Intrinsic Functions RUN(NAME intrinsics_01 LABELS cpython llvm NOFAST) # any RUN(NAME intrinsics_02 LABELS cpython llvm c) # floordiv +RUN(NAME intrinsics_03 LABELS llvm) # lshift # lpython decorator RUN(NAME lpython_decorator_01 LABELS cpython) diff --git a/integration_tests/intrinsics_03.py b/integration_tests/intrinsics_03.py new file mode 100644 index 0000000000..8d89909843 --- /dev/null +++ b/integration_tests/intrinsics_03.py @@ -0,0 +1,12 @@ +from lpython import i32 + +a : i32 +b : i32 + +a = 5 +b = 2 +print(lshift(a,b)) +assert(lshift(a,b) == a< Date: Thu, 7 Mar 2024 15:37:31 +0530 Subject: [PATCH 3/3] updated --- integration_tests/CMakeLists.txt | 2 +- src/libasr/codegen/asr_to_c_cpp.h | 1 + src/libasr/pass/intrinsic_function_registry.h | 21 ++++++++++--------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index 19f8c7a014..73d7757fed 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -816,7 +816,7 @@ RUN(NAME callback_04 IMPORT_PATH .. LABELS cpython) # Intrinsic Functions RUN(NAME intrinsics_01 LABELS cpython llvm NOFAST) # any RUN(NAME intrinsics_02 LABELS cpython llvm c) # floordiv -RUN(NAME intrinsics_03 LABELS llvm) # lshift +RUN(NAME intrinsics_03 LABELS cpython llvm) # lshift # lpython decorator RUN(NAME lpython_decorator_01 LABELS cpython) diff --git a/src/libasr/codegen/asr_to_c_cpp.h b/src/libasr/codegen/asr_to_c_cpp.h index c81ed357f5..b5f6e2c72a 100644 --- a/src/libasr/codegen/asr_to_c_cpp.h +++ b/src/libasr/codegen/asr_to_c_cpp.h @@ -3056,6 +3056,7 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) { SET_INTRINSIC_NAME(Trunc, "trunc"); SET_INTRINSIC_NAME(Fix, "fix"); SET_INTRINSIC_NAME(FloorDiv, "floordiv"); + SET_INTRINSIC_NAME(LShift, "lshift"); default : { throw LCompilersException("IntrinsicScalarFunction: `" + ASRUtils::get_intrinsic_name(x.m_intrinsic_id) diff --git a/src/libasr/pass/intrinsic_function_registry.h b/src/libasr/pass/intrinsic_function_registry.h index 9cd04a3da5..33fc68e282 100644 --- a/src/libasr/pass/intrinsic_function_registry.h +++ b/src/libasr/pass/intrinsic_function_registry.h @@ -371,6 +371,12 @@ class ASRBuilder { ASR::logicalbinopType::And, y, logical, nullptr)) #define Not(x) EXPR(ASR::make_LogicalNot_t(al, loc, x, logical, nullptr)) + + #define i_BitRshift(n, bits, t) EXPR(ASR::make_IntegerBinOp_t(al, loc, \ + n, ASR::binopType::BitRShift, bits, t, nullptr)) + #define i_BitLshift(n, bits, t) EXPR(ASR::make_IntegerBinOp_t(al, loc, \ + n, ASR::binopType::BitLShift, bits, t, nullptr)) + ASR::expr_t *Add(ASR::expr_t *left, ASR::expr_t *right) { LCOMPILERS_ASSERT(check_equal_type(expr_type(left), expr_type(right))); ASR::ttype_t *type = expr_type(left); @@ -2384,11 +2390,6 @@ namespace Mod { } // namespace Mod -#define i_BitRshift(n, bits, t) EXPR(ASR::make_IntegerBinOp_t(al, loc, \ - n, ASR::binopType::BitRShift, bits, t, nullptr)) -#define i_BitLshift(n, bits, t) EXPR(ASR::make_IntegerBinOp_t(al, loc, \ - n, ASR::binopType::BitLShift, bits, t, nullptr)) - namespace LShift { static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { @@ -2403,11 +2404,11 @@ namespace LShift { } static ASR::expr_t *eval_LShift(Allocator &al, const Location &loc, - ASR::ttype_t* t1, Vec &args) { - int64_t a = ASR::down_cast(args[0])->m_n; - int64_t b = ASR::down_cast(args[1])->m_n; - int64_t val = a << b; - return make_ConstantWithType(make_IntegerConstant_t, val, t1, loc); + ASR::ttype_t* t1, Vec &args) { + int64_t a = ASR::down_cast(args[0])->m_n; + int64_t b = ASR::down_cast(args[1])->m_n; + int64_t val = a << b; + return make_ConstantWithType(make_IntegerConstant_t, val, t1, loc); } static inline ASR::asr_t* create_LShift(Allocator& al, const Location& loc,