Details

LoopSafetyInfo, which is used in LICM was very conservative - whenever
there was an instruction that could have throw it assumed that
none of the instructions in the header is guaranteed to execute.
With this patch we are able to hoist instructions based on the stronger
execution guarantee, and preserve metadata.

Wouldn't checking isGuaranteedToTransferExecutionToSuccessor(&HeaderInstr) be somewhat less error-prone wrt. deletions, RAUWs etc., especially since the header is already being scanned from the beginning?

Specifically NOT okay to land as is. The quadratic complexity concern is a real one and the window chosen here is very likely too large.

And if you're concern is purely LICM, this patch is no longer needed at all. I introduced a surgical fix for LICM which solves this without the need for O(n^2) work. Unfortunately, that approach only works for LICM (not, store promotion or other users of MustExecute). Unfortunately, as you've found there don't appear to be any good cheap ways to ask ordering questions around instructions within a basic block. If there were, we could just keep track of the first throwing instruction.

You could consider trying to wire in the caching needed for OrderedBasicBlock, but again, that's only needed if you're concern is different consumer than LICM

We created an abstraction for the ordered basic block caching that works and is used in a few passes.
Transforms/Utils/OrderedInstructions.h

I suspect it's in a bad place for people to find it, and should be next to OrderedBasicBlock (or just make OrderedBasicBlock a hidden implementation detail, since all uses i can find really are doing it for multiple BB's anyway)

We created an abstraction for the ordered basic block caching that works and is used in a few passes.
Transforms/Utils/OrderedInstructions.h

I suspect it's in a bad place for people to find it, and should be next to OrderedBasicBlock (or just make OrderedBasicBlock a hidden implementation detail, since all uses i can find really are doing it for multiple BB's anyway)

Specifically NOT okay to land as is. The quadratic complexity concern is a real one and the window chosen here is very likely too large.

And if you're concern is purely LICM, this patch is no longer needed at all. I introduced a surgical fix for LICM which solves this without the need for O(n^2) work. Unfortunately, that approach only works for LICM (not, store promotion or other users of MustExecute). Unfortunately, as you've found there don't appear to be any good cheap ways to ask ordering questions around instructions within a basic block. If there were, we could just keep track of the first throwing instruction.

You could consider trying to wire in the caching needed for OrderedBasicBlock, but again, that's only needed if you're concern is different consumer than LICM

OK, so it seems that at least the tests in the second patch passes without this patch, so I am fine with committing it without this one for one (also Philip if you could take a look at that patch I would be grateful)
I am worried about cases, where the first instruction does not throw, but it we can't hoist it (e.g. it depends on the loop phi) and after that, there is an instruction that can be hoisted.

Right now we bail out if we reach more than 66 instructions. Is there a lower number that is greater than 1 that you think would be small enough to slow down the compilation imperceptibly, like 10?