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