-
Notifications
You must be signed in to change notification settings - Fork 449
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
Some for loops over range incorrectly use uninitialized values #5106
Comments
@ChrisDodd Food for thought on a subtle point involving for loops over ranges where the loop variable is modifed in the body. I wouldn't mind if we changed the compiler and/or language spec to restrict programs so that they cannot modify the loop variable in the loop body, at least not for the I also don't mind if p4c does allow modifying the loop variable in such loops, as long as p4c and the spec agree on what the behavior should be. 2025-Jan-28 update to this comment: My guess is that we could consider the compiler's output correct, if we removed the |
My take on this is:
BTW. I find the transformation with the extra action quite peculiar, what is the motivation for that? |
I am not able to quickly determine which pass does this, but it is reasonably common that assignment statements in a control can be replaced with a "dummy table", i.e. a table with no key fields at all (thus no entries can be added, thus all applies on it will always result in a miss, executing the default_action), one const default_action equal to a new synthesized action, and the assignment statements that were in the control apply body moved into the body of that action. Historically, I believe this is done for back ends that want everything in the control to look like either a conditional branch, or a table apply, and nothing else. And BMv2 back end is such a back end. Note that in my original comment, I did not include the "dummy table" for brevity. I said that the output of the compiler was equivalent to what I wrote, which it is. I just removed the dummy table and invoked the action directly in the body of the control. If you want to see the dummy table in its full glory, just run this command on the source file I provided in the attached zip file of the original comment:
then look in the |
I tried a test P4 program (attached) using the
for (typeRef var in min..max)
style of loop, and believe the output IR from the compiler midend is subtly wrong in some cases, depending upon one's interpretation of the desired behavior.Here is an example. A critical fact about the example is that the loop variable is modified within the body of the loop:
I believe that the behavior should be that the loop iterates exactly
n
times, wheren
is the original value ofn
when execution first reaches thefor
loop. The values ofi
during each successive iteration whenhdr.ethernet.dstAddr[7:0]
is equal to 3, for example, should be:In particular, it should not skip an iteration with
i
equal to 2 because of thei = i + 1
statement in the loop body.Note: It seems best to raise the question of the correct behavior in the LDWG if someone else's interpretation of the correct behavior for the oroginal program differs from mine above.
If my interpretation is correct, an equivalent way of writing the code above that I might hope to see in the output of midend is (see comments for special points of interest):
With p4c built from 2024-Dec-30 version of the source code, this command:
the output I see is equivalent to the following (see the in-line comments for the things that look like problems to me):
loop-var-in-range-modifiable-in-body4.p4.txt
The text was updated successfully, but these errors were encountered: