Skip to content

Commit de44dbf

Browse files
authored
Merge pull request #2108 from Shaikh-Ubaid/unsigned_ints_impr
Unsigned integers improvement and fixes
2 parents 800be6b + 836ac01 commit de44dbf

File tree

3 files changed

+60
-13
lines changed

3 files changed

+60
-13
lines changed

integration_tests/cast_02.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,46 @@ def test_02():
3434
print(w)
3535
assert w == u32(11)
3636

37+
def test_03():
38+
x : u32 = u32(-10)
39+
print(x)
40+
assert x == u32(4294967286)
41+
42+
y: u16 = u16(x)
43+
print(y)
44+
assert y == u16(65526)
45+
46+
z: u64 = u64(y)
47+
print(z)
48+
assert z == u64(65526)
49+
50+
w: u8 = u8(z)
51+
print(w)
52+
assert w == u8(246)
53+
54+
def test_04():
55+
x : u64 = u64(-11)
56+
print(x)
57+
# TODO: We are unable to store the following u64 in AST/R
58+
# assert x == u64(18446744073709551605)
59+
60+
y: u8 = u8(x)
61+
print(y)
62+
assert y == u8(245)
63+
64+
z: u16 = u16(y)
65+
print(z)
66+
assert z == u16(245)
67+
68+
w: u32 = u32(z)
69+
print(w)
70+
assert w == u32(245)
71+
3772

3873
def main0():
3974
test_01()
4075
test_02()
76+
test_03()
77+
test_04()
4178

4279
main0()

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5345,7 +5345,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
53455345
tmp = builder->CreateNot(tmp);
53465346
}
53475347

5348-
void visit_IntegerUnaryMinus(const ASR::IntegerUnaryMinus_t &x) {
5348+
template <typename T>
5349+
void handle_SU_IntegerUnaryMinus(const T& x) {
53495350
if (x.m_value) {
53505351
this->visit_expr_wrapper(x.m_value, true);
53515352
return;
@@ -5356,15 +5357,12 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
53565357
tmp = builder->CreateSub(zero, tmp);
53575358
}
53585359

5360+
void visit_IntegerUnaryMinus(const ASR::IntegerUnaryMinus_t &x) {
5361+
handle_SU_IntegerUnaryMinus(x);
5362+
}
5363+
53595364
void visit_UnsignedIntegerUnaryMinus(const ASR::UnsignedIntegerUnaryMinus_t &x) {
5360-
if (x.m_value) {
5361-
this->visit_expr_wrapper(x.m_value, true);
5362-
return;
5363-
}
5364-
this->visit_expr_wrapper(x.m_arg, true);
5365-
int kind = ASRUtils::extract_kind_from_ttype_t(ASRUtils::expr_type(x.m_arg));
5366-
llvm::Value *one = llvm::ConstantInt::get(context, llvm::APInt(kind * 8, 1, true));
5367-
tmp = builder->CreateAdd(builder->CreateNot(tmp), one); // compute 2's complement
5365+
handle_SU_IntegerUnaryMinus(x);
53685366
}
53695367

53705368
void visit_RealUnaryMinus(const ASR::RealUnaryMinus_t &x) {
@@ -6025,8 +6023,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
60256023
}
60266024
break;
60276025
}
6028-
case (ASR::cast_kindType::IntegerToInteger) :
6029-
case (ASR::cast_kindType::UnsignedIntegerToUnsignedInteger) : {
6026+
case (ASR::cast_kindType::IntegerToInteger) : {
60306027
int arg_kind = -1, dest_kind = -1;
60316028
extract_kinds(x, arg_kind, dest_kind);
60326029
if( arg_kind > 0 && dest_kind > 0 &&
@@ -6040,6 +6037,20 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
60406037
}
60416038
break;
60426039
}
6040+
case (ASR::cast_kindType::UnsignedIntegerToUnsignedInteger) : {
6041+
int arg_kind = -1, dest_kind = -1;
6042+
extract_kinds(x, arg_kind, dest_kind);
6043+
if( arg_kind > 0 && dest_kind > 0 &&
6044+
arg_kind != dest_kind )
6045+
{
6046+
if (dest_kind > arg_kind) {
6047+
tmp = builder->CreateZExt(tmp, llvm_utils->getIntType(dest_kind));
6048+
} else {
6049+
tmp = builder->CreateTrunc(tmp, llvm_utils->getIntType(dest_kind));
6050+
}
6051+
}
6052+
break;
6053+
}
60436054
case (ASR::cast_kindType::IntegerToUnsignedInteger) : {
60446055
int arg_kind = -1, dest_kind = -1;
60456056
extract_kinds(x, arg_kind, dest_kind);

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3602,9 +3602,8 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
36023602
if (ASRUtils::expr_value(operand) != nullptr) {
36033603
int64_t op_value = ASR::down_cast<ASR::UnsignedIntegerConstant_t>(
36043604
ASRUtils::expr_value(operand))->m_n;
3605-
op_value = (~op_value) + 1; // compute 2's complement
36063605
value = ASR::down_cast<ASR::expr_t>(ASR::make_UnsignedIntegerConstant_t(
3607-
al, x.base.base.loc, op_value, operand_type));
3606+
al, x.base.base.loc, -op_value, operand_type));
36083607
}
36093608
tmp = ASR::make_UnsignedIntegerUnaryMinus_t(al, x.base.base.loc, operand,
36103609
operand_type, value);

0 commit comments

Comments
 (0)