Skip to content

Fix unsigned integers in pointers #1894

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 32 additions & 9 deletions integration_tests/bindc_07.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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()
21 changes: 21 additions & 0 deletions src/libasr/codegen/asr_to_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,27 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
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<ASR::UnsignedInteger_t>(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<ASR::Real_t>(t2);
std::string type_name;
Expand Down
19 changes: 18 additions & 1 deletion src/libasr/codegen/asr_to_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,10 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
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;
Expand Down Expand Up @@ -6411,6 +6415,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
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:
Expand Down Expand Up @@ -6759,6 +6764,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
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 )
{
Expand All @@ -6771,7 +6777,18 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
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) : {
Expand Down