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

[SimplifyCFG] transform undef to unreachable #85510

Open
DianQK opened this issue Mar 16, 2024 · 2 comments
Open

[SimplifyCFG] transform undef to unreachable #85510

DianQK opened this issue Mar 16, 2024 · 2 comments

Comments

@DianQK
Copy link
Member

DianQK commented Mar 16, 2024

I tried the following code:

define noundef i32 @src(i32 noundef %arg) {
bb:
  switch i32 %arg, label %bb5 [
    i32 1, label %bb1
    i32 2, label %bb2
    i32 3, label %bb3
    i32 4, label %bb4
  ]

bb1:                                              ; preds = %bb
  br label %bb5

bb2:                                              ; preds = %bb
  br label %bb5

bb3:                                              ; preds = %bb
  br label %bb5

bb4:                                              ; preds = %bb
  br label %bb5

bb5:                                              ; preds = %bb4, %bb3, %bb2, %bb1, %bb
  %i = phi i32 [ undef, %bb ], [ 4, %bb4 ], [ 3, %bb3 ], [ 2, %bb2 ], [ 1, %bb1 ]
  ret i32 %i
}

define noundef i32 @tgt(i32 noundef %arg) {
bb:
  ret i32 %arg
}

src can be transformed into a return statement because bb through bb5 is undefined behavior.
Perhaps we will be blocked by #78578 if we fix this issue.

alive2: https://alive2.llvm.org/ce/z/Sz6r-e
godbolt: https://llvm.godbolt.org/z/sjrT7Ms6e

@DianQK DianQK changed the title [SimplifyCFG] transform `undef to unreachable [SimplifyCFG] transform undef to unreachable Mar 16, 2024
@XChy
Copy link
Member

XChy commented Mar 27, 2024

Specifically, in your example, if the return value isn't labelled noundef, it's illegal to transform undef to unreachable: https://alive2.llvm.org/ce/z/GGkF83

I guess what you want is to refine undef to %arg? SimplifyCFG kills bb1, threads over bb1 to bb5 and refines undef to 1, because undef in phi is always mergeable, see also:

!CanMergeValues(BBPN->getIncomingValueForBlock(IBB),

A more general question is how to make the refinement best, but it's hard(or even undecidable). I wonder where this example comes from, and are there more specific scenarios? That would be helpful for this issue.

Anyway, I think CanRedirectPredsOfEmptyBBToSucc is irrelevant here, because it doesn't allow redirecting common predecessor, like the switch in this example.

@DianQK
Copy link
Member Author

DianQK commented Mar 27, 2024

Specifically, in your example, if the return value isn't labelled noundef, it's illegal to transform undef to unreachable: https://alive2.llvm.org/ce/z/GGkF83

I guess what you want is to refine undef to %arg? SimplifyCFG kills bb1, threads over bb1 to bb5 and refines undef to 1, because undef in phi is always mergeable, see also:

!CanMergeValues(BBPN->getIncomingValueForBlock(IBB),

A more general question is how to make the refinement best, but it's hard(or even undecidable). I wonder where this example comes from, and are there more specific scenarios? That would be helpful for this issue.

See https://llvm.godbolt.org/z/zzv3jxYdc. Yes, I was simply hoping that the noundef attribute of the returned value would be more helpful, though it isn't essential.

Anyway, I think CanRedirectPredsOfEmptyBBToSucc is irrelevant here, because it doesn't allow redirecting common predecessor, like the switch in this example.

I apologize, I got some of my initial debugging results mixed up. You're right, the code you mentioned above is relevant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants