Optimise case arguments in sys_core_fold

If the argument of a case expression is a let, a seq or a case with two clauses
where the second one is a failing clause; it can be moved outside the case and
further optimisations can be performed.

module 'foo' ['t'/4]
  attributes []
't'/4 =
  fun (_cor14,Sub0,_cor15,_cor16) ->
    let Ssa = call 'erlang':'get' ('foo') in
      case let Ssa = {'ssa',_cor14,Sub0,_cor15,_cor16} in
           let _rec11 = call 'erlang':'+' (_cor14, 1) in
           let _cor4 = call 'erlang':'setelement' (2, Ssa, _rec11) in
             {{'tmp',_cor14},_cor4} of
        {NewReg,Foo} when 'true' ->
          {NewReg,Foo,Ssa}
        _cor20 when 'true' ->
          primop 'match_failure' ({'case_clause',_cor20})
      end
end

  ==>

module 'foo' ['t'/4]
  attributes []
't'/4 =
  fun (_cor14,Sub0,_cor15,_cor16) ->
    let Ssa = call 'erlang':'get' ('foo') in
    let _fol0 = {'ssa',_cor14,Sub0,_cor15,_cor16} in
    let _rec11 = call 'erlang':'+' (_cor14, 1) in
    let _cor4 = call 'erlang':'setelement' (2, _fol0, _rec11) in
    let NewReg = {'tmp',_cor14} in
      {NewReg,_cor4,Ssa}
end