Skip to content

LLVM: Support logical binop for strings, int, real #1506

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
Feb 13, 2023

Conversation

Smit-create
Copy link
Collaborator

Fixes #1487

@Smit-create Smit-create marked this pull request as ready for review February 13, 2023 07:59
@Smit-create Smit-create added the ready for review PRs that are ready for review label Feb 13, 2023
Copy link
Contributor

@certik certik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Comment on lines +14 to +15
or_op1 = a or b
or_op2 = x or y
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should explicitly be casting the operands tobool() (when are not already of bool type). For example:

res: bool
res = bool(a) or bool(b)

For or_op1 = a or b, since or_op1 is of type i32, I think it should be

or_op1 = i32(bool(a) or bool(b))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems the result of x or y is an integer, I think we are fine in this case.

Copy link
Collaborator

@ubaidsk ubaidsk Mar 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems the result of x or y is an integer, I think we are fine in this case.

It looks like or here is not a logical operation, but instead a selective operation. I think we should have a separate ASR node for this selective or operation.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can name it as SelectiveOr which takes two arguments both of any type (but equal types). The return value of this SelectiveOr is the same as that of the type of one of the operands.

Comment on lines +4654 to +4683
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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this operation should not be done at the backend level. A backend should exactly follow what the ASR says. In this case, it should always return a logical result. This logical result can/should later be casted to the desired type.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened an issue here lfortran/lfortran#3620.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this should be explicitly done in ASR, not in the backend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready for review PRs that are ready for review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Logical operation of two integers gives wrong answers.
4 participants