From 053781d0f53abda45c8b9f55b60e74d8afd2de8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Mon, 12 Jun 2023 09:25:30 -0600 Subject: [PATCH 1/4] Add a test for c_p_pointer with unsigned integers --- integration_tests/bindc_07.py | 41 +++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/integration_tests/bindc_07.py b/integration_tests/bindc_07.py index 333e8bad28..f03af3331b 100644 --- a/integration_tests/bindc_07.py +++ b/integration_tests/bindc_07.py @@ -1,22 +1,35 @@ -from lpython import CPtr, i64, sizeof, i32, i16, i8, ccall, c_p_pointer, empty_c_void_p, Pointer, pointer -from numpy import empty, int64, array +from lpython import (CPtr, sizeof, ccall, c_p_pointer, empty_c_void_p, + i64, i32, i16, i8, + u64, u32, u16, u8, + Pointer, pointer, u16) +from numpy import array @ccall def _lfortran_malloc(size: i32) -> CPtr: pass -def allocate_memory(size: i32) -> tuple[CPtr, CPtr, CPtr, CPtr]: +def allocate_memory(size: i32) -> tuple[CPtr, CPtr, CPtr, CPtr, \ + CPtr, CPtr, CPtr, CPtr]: array1: CPtr = _lfortran_malloc(size * i32(sizeof(i8))) array2: CPtr = _lfortran_malloc(size * i32(sizeof(i16))) array3: CPtr = _lfortran_malloc(size * i32(sizeof(i32))) array4: CPtr = _lfortran_malloc(size * i32(sizeof(i64))) - return array1, array2, array3, array4 + array5: CPtr = _lfortran_malloc(size * i32(sizeof(u8))) + array6: CPtr = _lfortran_malloc(size * i32(sizeof(u16))) + array7: CPtr = _lfortran_malloc(size * i32(sizeof(u32))) + array8: CPtr = _lfortran_malloc(size * i32(sizeof(u64))) + return array1, array2, array3, array4, array5, array6, array7, array8 -def sum_arrays(array1: CPtr, array2: CPtr, array3: CPtr, array4: CPtr, size: i32): +def sum_arrays(array1: CPtr, array2: CPtr, array3: CPtr, array4: CPtr, \ + array5: CPtr, array6: CPtr, array7: CPtr, array8: CPtr, size: i32): iarray1: Pointer[i8[:]] = c_p_pointer(array1, i8[:], array([size])) iarray2: Pointer[i16[:]] = c_p_pointer(array2, i16[:], array([size])) iarray3: Pointer[i32[:]] = c_p_pointer(array3, i32[:], array([size])) iarray4: Pointer[i64[:]] = c_p_pointer(array4, i64[:], array([size])) + iarray5: Pointer[u8[:]] = c_p_pointer(array5, u8[:], array([size])) + iarray6: Pointer[u16[:]] = c_p_pointer(array6, u16[:], array([size])) + iarray7: Pointer[u32[:]] = c_p_pointer(array7, u32[:], array([size])) + iarray8: Pointer[u64[:]] = c_p_pointer(array8, u64[:], array([size])) sum_array_cptr: CPtr = _lfortran_malloc(size * i32(sizeof(i64))) sum_array: Pointer[i64[:]] = c_p_pointer(sum_array_cptr, i64[:], array([size])) i: i32 @@ -26,20 +39,30 @@ def sum_arrays(array1: CPtr, array2: CPtr, array3: CPtr, array4: CPtr, size: i32 iarray2[i] = i16(2 * i) iarray3[i] = i32(3 * i) iarray4[i] = i64(4 * i) + iarray5[i] = u8(i) + iarray6[i] = u16(6 * i) + iarray7[i] = u32(7 * i) + iarray8[i] = u64(8 * i) for i in range(size): - sum_array[i] = i64(iarray1[i]) + i64(iarray2[i]) + i64(iarray3[i]) + iarray4[i] + sum_array[i] = i64(iarray1[i]) + i64(iarray2[i]) + i64(iarray3[i]) \ + + iarray4[i] + i64(iarray5[i]) + i64(iarray6[i]) \ + + i64(iarray7[i]) + i64(iarray8[i]) for i in range(size): print(i, sum_array[i]) - assert sum_array[i] == i64(10 * i) + assert sum_array[i] == i64(32 * i) def test_tuple_return(): a: CPtr = empty_c_void_p() b: CPtr = empty_c_void_p() c: CPtr = empty_c_void_p() d: CPtr = empty_c_void_p() - a, b, c, d = allocate_memory(50) - sum_arrays(a, b, c, d, 50) + e: CPtr = empty_c_void_p() + f: CPtr = empty_c_void_p() + g: CPtr = empty_c_void_p() + h: CPtr = empty_c_void_p() + a, b, c, d, e, f, g, h = allocate_memory(50) + sum_arrays(a, b, c, d, e, f, g, h, 50) test_tuple_return() From 7d532ac403deb842d8943e1eefdc1c2d1e68d258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Mon, 12 Jun 2023 09:25:42 -0600 Subject: [PATCH 2/4] LLVM: handle UnsignedInteger in Pointer --- src/libasr/codegen/asr_to_llvm.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp index df47c151db..478c2dc1a3 100644 --- a/src/libasr/codegen/asr_to_llvm.cpp +++ b/src/libasr/codegen/asr_to_llvm.cpp @@ -444,6 +444,10 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor el_type = getIntType(a_kind, true); break; } + case ASR::ttypeType::UnsignedInteger: { + el_type = getIntType(a_kind, true); + break; + } case ASR::ttypeType::Real: { el_type = getFPType(a_kind, true); break; @@ -6411,6 +6415,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor ASRUtils::type_get_past_pointer(x->m_type)); switch (t2->type) { case ASR::ttypeType::Integer: + case ASR::ttypeType::UnsignedInteger: case ASR::ttypeType::Real: case ASR::ttypeType::Complex: case ASR::ttypeType::Struct: From 768cb11afe57b1716e1e6ace45d400c0676a0626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Mon, 12 Jun 2023 14:34:48 -0600 Subject: [PATCH 3/4] LLVM: Implement UnsignedIntegerToInteger cast --- src/libasr/codegen/asr_to_llvm.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp index 478c2dc1a3..be8aa4b3a2 100644 --- a/src/libasr/codegen/asr_to_llvm.cpp +++ b/src/libasr/codegen/asr_to_llvm.cpp @@ -6764,6 +6764,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor case (ASR::cast_kindType::IntegerToUnsignedInteger) : { int arg_kind = -1, dest_kind = -1; extract_kinds(x, arg_kind, dest_kind); + LCOMPILERS_ASSERT(arg_kind != -1 && dest_kind != -1) if( arg_kind > 0 && dest_kind > 0 && arg_kind != dest_kind ) { @@ -6776,7 +6777,18 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor break; } case (ASR::cast_kindType::UnsignedIntegerToInteger) : { - // tmp = tmp + int arg_kind = -1, dest_kind = -1; + extract_kinds(x, arg_kind, dest_kind); + LCOMPILERS_ASSERT(arg_kind != -1 && dest_kind != -1) + if( arg_kind > 0 && dest_kind > 0 && + arg_kind != dest_kind ) + { + if (dest_kind > arg_kind) { + tmp = builder->CreateSExt(tmp, getIntType(dest_kind)); + } else { + tmp = builder->CreateTrunc(tmp, getIntType(dest_kind)); + } + } break; } case (ASR::cast_kindType::CPtrToUnsignedInteger) : { From 77aa0d0aaf8f5fa591d6fcc7daa9ad55f782d31a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Mon, 12 Jun 2023 14:41:29 -0600 Subject: [PATCH 4/4] C: support unsigned integers in pointers --- src/libasr/codegen/asr_to_c.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/libasr/codegen/asr_to_c.cpp b/src/libasr/codegen/asr_to_c.cpp index b6837ad9f3..da4edbabcc 100644 --- a/src/libasr/codegen/asr_to_c.cpp +++ b/src/libasr/codegen/asr_to_c.cpp @@ -250,6 +250,27 @@ class ASRToCVisitor : public BaseCCPPVisitor std::string dims = convert_dims_c(n_dims, m_dims, v_m_type, is_fixed_size); sub = format_type_c(dims, type_name, v.m_name, use_ref, dummy); } + } else if (ASRUtils::is_unsigned_integer(*t2)) { + ASR::UnsignedInteger_t *t = ASR::down_cast(ASRUtils::type_get_past_array(t2)); + std::string type_name = "uint" + std::to_string(t->m_kind * 8) + "_t"; + if( !ASRUtils::is_array(v_m_type) ) { + type_name.append(" *"); + } + if( is_array ) { + bool is_fixed_size = true; + std::string dims = convert_dims_c(n_dims, m_dims, v_m_type, is_fixed_size, true); + std::string encoded_type_name = "u" + std::to_string(t->m_kind * 8); + generate_array_decl(sub, std::string(v.m_name), type_name, dims, + encoded_type_name, m_dims, n_dims, + use_ref, dummy, + v.m_intent != ASRUtils::intent_in && + v.m_intent != ASRUtils::intent_inout && + v.m_intent != ASRUtils::intent_out, is_fixed_size, true); + } else { + bool is_fixed_size = true; + std::string dims = convert_dims_c(n_dims, m_dims, v_m_type, is_fixed_size); + sub = format_type_c(dims, type_name, v.m_name, use_ref, dummy); + } } else if (ASRUtils::is_real(*t2)) { ASR::Real_t *t = ASR::down_cast(t2); std::string type_name;