-
Notifications
You must be signed in to change notification settings - Fork 119
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
Fix bad logical-and implementation #131
Conversation
Can you add some test cases in |
Hi, @nosba0957 , I use the following code to test the logical-and operation: /* test.c */
#include <stdio.h>
int func(int x)
{
if (x >= 0) {
printf("x >= 0\n");
}
return x;
}
int main()
{
int ret = 0;
ret = 1 && func(5);
if (ret)
printf("%d\n", ret);
printf("============\n");
ret = 0 && func(5);
if (ret)
printf("%d\n", ret);
return 0;
} If we use GCC or Clang to compile and execute the code, both yield the same output:
In the However, if we use shecc with the modified implementation to generate an executable with Arm32, the result is unexpected:
For the second Therefore, I think we can ensure the correctness of the logical-and behavior's result, but we still need to have more effort to implement the left-to-right evaluation rule for logical-and and logical-or operations. |
Sure, I'll add test cases to @DrXiao, Thank you for your feedback. I've decided to first ensure the correctness of the logical-and operation. Currently, left-to-right evaluation cannot be achieved. I will revise the commit messages. |
Per the C99 standard, left-to-right evaluation should be guaranteed. You should investigate the root cause preventing the proposed changes from being compliant with the C standard. |
@vacantron, I'm currently modifying the parser to achieve left-to-right evaluation. But if I start modifying the implementation from the parser, the changes to the codegen might not be necessary. |
That's okay. You can close this pull request since then. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use git rebase
instead of git merge
.
In
When we execute This problem can be reproduced by removing the modification in |
The property |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a snapshot test under the tests/
directory to watch the consistence of the work of lever/parser. Since they have been changed, the corresponding snapshots need to be updated together.
You can run tests/update-snapshots.sh
under the ARM config.
So should I keep the modifications in
Thanks for your friendly reminder. |
You can add a comment like |
src/ssa.c
Outdated
* the newly added phi instruction. Once this error is fixed, we | ||
* can remove the first if statement. | ||
*/ | ||
while (head->next->opcode != OP_branch) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you avoid traversing the whole elements since we just want to figure out the branch operation at first glance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nosba0957 , I have found the reason of this error. I will open another pull request for it later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I still modify this part of the code, or should I keep the current commit as is and wait for @vacantron 's fix?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can cherry-pick the commit at vacantron@5fd2fbe and update your change.
@nosba0957,I have opened the #137. You can redirect this pull request to that issue. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rebase the latest master
branch.
The previous implementation of the logical-and operation produced incorrect result. This implementation ensures the correctness of the logical-and behavior and guarantees left-to-right evaluation as mentioned in the C99 standard. Add new function, `read_log_and_operation` and `finalize_log_and`. `read_log_and_operation` is used when `read_expr` encounters `OP_log_and`. This function creates a new branch instruction to test the operand before `OP_log_and`, and then creates a new basic block for next expression. `finalize_log_and` is used when all operands are consumed or when an operator with lower priority than logical-and is encountered. This function create new basic blocks and new branchs to derive the final value (0 or 1) for the result of the logical-and operation, and then creates a new basic block for other new instructions. In `read_expr`, we provide data for the false branch of logical-and operation, including `else_bb` and `land_else_label`. All operands of logical-and operator are designed to branch to the same "else" basic block for the false branch. This commit adjusts the order of connecting the basic block during parsing `T_for` and `T_while`. This change ensures that basic blocks are connected correctly when the condition expression includes a logical-and operation. Resolve sysprog21#137
The current "prev" pointer of instruction doesn't be updated after inserting/removing the phi node. This causes the unexpected result of phi node unwinding.
Thank @nosba0957 for contributing! |
The previous implementation of the logical-and operation produced incorrect result. This error also affected the funtionality of if statements using logical-and.
This implementation follows the C99 standard for logical-and, ensuring left-to-right evaluation. If the first operand is zero, the second operand is not evaluated.
Close #137