Skip to content

Commit

Permalink
Merge pull request lcompilers#1506 from Smit-create/i-1487
Browse files Browse the repository at this point in the history
LLVM: Support logical binop for strings, int, real
  • Loading branch information
certik committed Feb 13, 2023
2 parents c313afe + ae75622 commit fe33004
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 3 deletions.
1 change: 1 addition & 0 deletions integration_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ RUN(NAME test_str_to_int LABELS cpython llvm c)
RUN(NAME test_platform LABELS cpython llvm c)
RUN(NAME test_vars_01 LABELS cpython llvm)
RUN(NAME test_version LABELS cpython llvm)
RUN(NAME logical_binop1 LABELS cpython llvm)
RUN(NAME vec_01 LABELS cpython llvm c)
RUN(NAME test_str_comparison LABELS cpython llvm c)
RUN(NAME test_bit_length LABELS cpython llvm c)
Expand Down
50 changes: 50 additions & 0 deletions integration_tests/logical_binop1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from ltypes import i32

def test_issue_1487_1():
a : i32
b : i32
x : i32
y : i32
or_op1 : i32
or_op2 : i32
a = 1
b = 2
x = 0
y = 4
or_op1 = a or b
or_op2 = x or y
assert or_op1 == 1
assert or_op2 == 4
y = 0
or_op2 = x or y
assert or_op2 == 0


def test_issue_1487_2():
a : i32
b : i32
x : i32
y : i32
and_op1 : i32
and_op2 : i32
a = 100
b = 150
x = 175
y = 0
and_op1 = a and b
and_op2 = y and x
assert and_op1 == 150
assert and_op2 == 0
x = 0
and_op2 = y and x
and_op1 = b and a
assert and_op2 == 0
assert and_op1 == 100


def check():
test_issue_1487_1()
test_issue_1487_2()


check()
50 changes: 47 additions & 3 deletions src/libasr/codegen/asr_to_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4651,14 +4651,58 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
llvm::Value *left_val = tmp;
this->visit_expr_wrapper(x.m_right, true);
llvm::Value *right_val = tmp;
LCOMPILERS_ASSERT(ASRUtils::is_logical(*x.m_type))
llvm::Value *zero, *cond;
llvm::AllocaInst *result;
if (ASRUtils::is_integer(*x.m_type)) {
int a_kind = down_cast<ASR::Integer_t>(x.m_type)->m_kind;
int init_value_bits = 8*a_kind;
zero = llvm::ConstantInt::get(context,
llvm::APInt(init_value_bits, 0));
cond = builder->CreateICmpEQ(left_val, zero);
result = builder->CreateAlloca(getIntType(a_kind), nullptr);
} else if (ASRUtils::is_real(*x.m_type)) {
int a_kind = down_cast<ASR::Real_t>(x.m_type)->m_kind;
int init_value_bits = 8*a_kind;
if (init_value_bits == 32) {
zero = llvm::ConstantFP::get(context,
llvm::APFloat((float)0));
} else {
zero = llvm::ConstantFP::get(context,
llvm::APFloat((double)0));
}
result = builder->CreateAlloca(getFPType(a_kind), nullptr);
cond = builder->CreateFCmpUEQ(left_val, zero);
} else if (ASRUtils::is_character(*x.m_type)) {
zero = llvm::Constant::getNullValue(character_type);
cond = lfortran_str_cmp(left_val, zero, "_lpython_str_compare_eq");
result = builder->CreateAlloca(character_type, nullptr);
} else if (ASRUtils::is_logical(*x.m_type)) {
zero = llvm::ConstantInt::get(context,
llvm::APInt(1, 0));
cond = builder->CreateICmpEQ(left_val, zero);
result = builder->CreateAlloca(llvm::Type::getInt1Ty(context), nullptr);
} else {
throw CodeGenError("Only Integer, Real, Strings and Logical types are supported "
"in logical binary operation.", x.base.base.loc);
}
switch (x.m_op) {
case ASR::logicalbinopType::And: {
tmp = builder->CreateAnd(left_val, right_val);
create_if_else(cond, [&, result, left_val]() {
LLVM::CreateStore(*builder, left_val, result);
}, [&, result, right_val]() {
LLVM::CreateStore(*builder, right_val, result);
});
tmp = LLVM::CreateLoad(*builder, result);
break;
};
case ASR::logicalbinopType::Or: {
tmp = builder->CreateOr(left_val, right_val);
create_if_else(cond, [&, result, right_val]() {
LLVM::CreateStore(*builder, right_val, result);

}, [&, result, left_val]() {
LLVM::CreateStore(*builder, left_val, result);
});
tmp = LLVM::CreateLoad(*builder, result);
break;
};
case ASR::logicalbinopType::Xor: {
Expand Down

0 comments on commit fe33004

Please sign in to comment.