Skip to content
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

Avoid creating invalid PhiNodes in IR passes #50235

Merged
merged 1 commit into from
Jun 21, 2023
Merged

Avoid creating invalid PhiNodes in IR passes #50235

merged 1 commit into from
Jun 21, 2023

Conversation

Keno
Copy link
Member

@Keno Keno commented Jun 20, 2023

As of #50158, irverify catches cases where PhiNodes show up in the middle of a basic block (which is illegal). Unfortunately, it turns out there were two cases in Base, where we created just such code:

  1. When cfg_simplify! merged basic blocks, it didn't bother to delete (resp, replace by the one incoming edge) the PhiNodes in the basic block it was merging.

  2. In irinterp we try to delete instructions that result in constants. This is not legal if the instruction is a PhiNode.

The second of these is somewhat unfortunate, but any subsequent compaction will of course take care of it, so I don't think it's a huge issue to just disable the replacement.

As of #50158, irverify catches cases where PhiNodes show up in the
middle of a basic block (which is illegal). Unfortunately, it turns
out there were two cases in Base, where we created just such code:

1. When cfg_simplify! merged basic blocks, it didn't bother to delete
   (resp, replace by the one incoming edge) the PhiNodes in the basic
   block it was merging.

2. In irinterp we try to delete instructions that result in constants.
   This is not legal if the instruction is a PhiNode.

The second of these is somewhat unfortunate, but any subsequent compaction
will of course take care of it, so I don't think it's a huge issue
to just disable the replacement.
@oscardssmith oscardssmith added bugfix This change fixes an existing bug compiler:optimizer Optimization passes (mostly in base/compiler/ssair/) labels Jun 20, 2023
@Keno Keno merged commit 95749c3 into master Jun 21, 2023
@Keno Keno deleted the kf/invalidirphis branch June 21, 2023 00:52
Keno added a commit that referenced this pull request Jun 27, 2023
In #50158, I tought the verifier to reject code that has invalid
statements in the original PHI block. In #50235, this required
irinterp to stop folding PhiNodes to the respective constants.
I said at the time that a subsequent compact would fix it, but
it turns out that we don't actually have the logic for that.
I might still add that logic, but on the other hand it just
seems kinda silly that PhiNodes need to be a special case here.

This PR relaxes the semantics of the PHI block, to allow any
value-position constant to appear in the PHI block and undoes
the irinterp change from #50235. Only the interpreter really
cares about the semantics of the phi block, so the primary change
is there.

Of note, SSAValue forwards are not allowed in the phi block. This
is because of the following:

```
loop:
 %1 = %(...)
 %2 = %1
 %3 = %(top => %1)
```

The two phi values %1 and %2 have different semantics: %1 gets
the *current* iteration of the loop, while %3 gets the *previous*
value. As a result, any pass that wants to move SSAValues out of
PhiNode uses would have to be aware of these semantics anyway,
and there's no simplicitly benefits to allowing SSAValues in the
middle of a phi block.
Keno added a commit that referenced this pull request Jun 27, 2023
In #50158, I tought the verifier to reject code that has invalid
statements in the original PHI block. In #50235, this required
irinterp to stop folding PhiNodes to the respective constants.
I said at the time that a subsequent compact would fix it, but
it turns out that we don't actually have the logic for that.
I might still add that logic, but on the other hand it just
seems kinda silly that PhiNodes need to be a special case here.

This PR relaxes the semantics of the PHI block, to allow any
value-position constant to appear in the PHI block and undoes
the irinterp change from #50235. Only the interpreter really
cares about the semantics of the phi block, so the primary change
is there.

Of note, SSAValue forwards are not allowed in the phi block. This
is because of the following:

```
loop:
 %1 = %(...)
 %2 = %1
 %3 = %(top => %1)
```

The two phi values %1 and %2 have different semantics: %1 gets
the *current* iteration of the loop, while %3 gets the *previous*
value. As a result, any pass that wants to move SSAValues out of
PhiNode uses would have to be aware of these semantics anyway,
and there's no simplicitly benefits to allowing SSAValues in the
middle of a phi block.
Keno added a commit that referenced this pull request Jun 27, 2023
In #50158, I tought the verifier to reject code that has invalid
statements in the original PHI block. In #50235, this required
irinterp to stop folding PhiNodes to the respective constants.
I said at the time that a subsequent compact would fix it, but
it turns out that we don't actually have the logic for that.
I might still add that logic, but on the other hand it just
seems kinda silly that PhiNodes need to be a special case here.

This PR relaxes the semantics of the PHI block, to allow any
value-position constant to appear in the PHI block and undoes
the irinterp change from #50235. Only the interpreter really
cares about the semantics of the phi block, so the primary change
is there.

Of note, SSAValue forwards are not allowed in the phi block. This
is because of the following:

```
loop:
 %1 = %(...)
 %2 = %1
 %3 = %(top => %1)
```

The two phi values %1 and %2 have different semantics: %1 gets
the *current* iteration of the loop, while %3 gets the *previous*
value. As a result, any pass that wants to move SSAValues out of
PhiNode uses would have to be aware of these semantics anyway,
and there's no simplicitly benefits to allowing SSAValues in the
middle of a phi block.
Keno added a commit that referenced this pull request Jun 28, 2023
In #50158, I tought the verifier to reject code that has invalid
statements in the original PHI block. In #50235, this required
irinterp to stop folding PhiNodes to the respective constants.
I said at the time that a subsequent compact would fix it, but
it turns out that we don't actually have the logic for that.
I might still add that logic, but on the other hand it just
seems kinda silly that PhiNodes need to be a special case here.

This PR relaxes the semantics of the PHI block, to allow any
value-position constant to appear in the PHI block and undoes
the irinterp change from #50235. Only the interpreter really
cares about the semantics of the phi block, so the primary change
is there.

Of note, SSAValue forwards are not allowed in the phi block. This
is because of the following:

```
loop:
 %1 = %(...)
 %2 = %1
 %3 = %(top => %1)
```

The two phi values %1 and %2 have different semantics: %1 gets
the *current* iteration of the loop, while %3 gets the *previous*
value. As a result, any pass that wants to move SSAValues out of
PhiNode uses would have to be aware of these semantics anyway,
and there's no simplicitly benefits to allowing SSAValues in the
middle of a phi block.
Keno added a commit that referenced this pull request Jun 29, 2023
In #50158, I tought the verifier to reject code that has invalid
statements in the original PHI block. In #50235, this required
irinterp to stop folding PhiNodes to the respective constants.
I said at the time that a subsequent compact would fix it, but
it turns out that we don't actually have the logic for that.
I might still add that logic, but on the other hand it just
seems kinda silly that PhiNodes need to be a special case here.

This PR relaxes the semantics of the PHI block, to allow any
value-position constant to appear in the PHI block and undoes
the irinterp change from #50235. Only the interpreter really
cares about the semantics of the phi block, so the primary change
is there.

Of note, SSAValue forwards are not allowed in the phi block. This
is because of the following:

```
loop:
 %1 = %(...)
 %2 = %1
 %3 = %(top => %1)
```

The two phi values %1 and %2 have different semantics: %1 gets
the *current* iteration of the loop, while %3 gets the *previous*
value. As a result, any pass that wants to move SSAValues out of
PhiNode uses would have to be aware of these semantics anyway,
and there's no simplicitly benefits to allowing SSAValues in the
middle of a phi block.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugfix This change fixes an existing bug compiler:optimizer Optimization passes (mostly in base/compiler/ssair/)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants