What does left arrow <- mean outside a do block?

That's a pattern guard:

guard       →   pat <- infixexp      (pattern guard)

[...]

A guard has one of the following forms:

  • pattern guards are of the form p <- e, where p is a pattern (see Section 3.17) of type t and e is an expression type t. They succeed if the expression e matches the pattern p, and introduce the bindings of the pattern to the environment.

Where normal guards are limited to a boolean check, pattern guards can match against an arbitrary pattern and define local variables. (In your case entry, middle, and the contents of CmmForeignCall will be directly available in the function body.)

You can think of boolean guards as equivalent to pattern guards with a pattern of True:

| expr

works like

| True <- expr

This is a pattern guard [Haskell-wiki]. Since Haskell'10 a guard is a list of qualifiers. A qualifier can be a condition (like in the old guards), and pattern guards.

Haskell will thus (lazily) evaluate the expression on the right side of the arrow <- and aim to match it with the pattern on the left of the arrow. If that succeeds, than the guard (well that part of the guard) is successful. If all the parts of the guard are successful, then the rule "fires".

In this specific case the only part of the pattern that might fail is the fact that the third item of the 3-tuple is not a CmmForeignCall data constructor. Furthermore by using this pattern guard, we can of course use entry, middle in the body of the expression.