Fix unreachable BrOn branch analysis - #8970
Conversation
| ;; We can monomorphize the call to $target, pushing the ref.is_null into | ||
| ;; $target_2. The parameter we send there is now nullref, so everything there | ||
| ;; gets optimized away. In this function, after refinalizing we end up with | ||
| ;; an unreachable br_on, and while doing so, we should not hit an internal |
There was a problem hiding this comment.
The br_on is not actually unreachable, right? It just unconditionally traps because of the null descriptor.
There was a problem hiding this comment.
Right, I meant to say it is not reached/taken 😄
There was a problem hiding this comment.
No, wait, the comment is already right. It does become unreachable after refinalizing, see the output.
There was a problem hiding this comment.
How can that be right? This is the output:
;; CHECK-NEXT: (block ;; (replaces unreachable BrOn we can't emit)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
Neither child of the BrOn is unreachable, so the BrOn should not be unreachable.
There was a problem hiding this comment.
The BrOn is not actually unreachable, but it is unPrintable, here is the Printing logic:
Lines 2918 to 2921 in a0463cb
When we lack a defined type to write out the br_on* line, we emit this. So it happens for unwritable type immediates, not just for unreachable BrOns.
There was a problem hiding this comment.
Right. Let's update the comment to describe it as unconditionally trapping rather than unreachable.
We skipped the branch if we were unreachable, but that is not correct, see
visitBreakabove - we need to note all the branches, taken or not, or elsewe can hit an assertion. (We rely on optimization passes to remove
unreachable branch instructions.)