Minimal failing test
Minimal failing test

This corresponds to the failing bit of LocVolCalib.

The outer map is necessary in order to get an outer segmap_group, the test
doesn't fail without. I'm not really sure why.

The issue seems to be that the source of the short-circuiting (the result of the
inner map) is not last-used in the short-circuiting point. Really, in the case
of map, it will _never_ be last-used, since the source is actually the result of
the map, which is going to be used somewhere else.

The failing IR looks like this:

```
  let {defunc_3_map_res_6369 : [n_6212][m_6213]i32 @ mem_6411 ->
                               {base: [n_6212, m_6213];
                                contiguous: true;
                                LMADs: [{offset: 0i64;
                                         strides: [m_6213, 1i64];
                                         shape: [n_6212, m_6213];
                                         permutation: [0, 1];
                                         monotonicity: [Inc, Inc]}]}} =
    #[incremental_flattening(only_intra)]
    segmap(group; ; groups=n_6212; groupsize=m_6213)
    (gtid_6370 < n_6212) (~phys_tid_6371) : {[m_6213]i32} {
      let {color_6412 : mem@local} =
        alloc(bytes_6402, @local)
      let {color_6413 : mem@local} =
        alloc(bytes_6402, @local)
      let {scan_6377 : [m_6213]i32 @ color_6413 ->
                       {base: [m_6213];
                        contiguous: true;
                        LMADs: [{offset: 0i64;
                                 strides: [1i64];
                                 shape: [m_6213];
                                 permutation: [0];
                                 monotonicity: [Inc]}]}} =
        segscan(thread; ; )
        (gtid_6378 < m_6213) (~phys_tid_6379)
        ({0i32},
        ,
        \ {x_6380 : i32, x_6381 : i32}
          : {i32} ->
          let {defunc_1_op_res_6382 : i32} = add32(x_6380, x_6381)
          in {defunc_1_op_res_6382})
        : {i32} {
          let {x_6383 : i32} =
            xs_6214[gtid_6370, gtid_6378]
          return {returns x_6383}
        }
      let {res_6388 : [m_6213]i32 @ color_6412 ->
                      {base: [m_6213];
                       contiguous: true;
                       LMADs: [{offset: 0i64;
                                strides: [1i64];
                                shape: [m_6213];
                                permutation: [0];
                                monotonicity: [Inc]}]}} =
        segmap(thread; ; )
        (gtid_6389 < m_6213) (~phys_tid_6390) : {i32} {
          let {x_6391 : i32} =
            scan_6377[gtid_6389]
          let {defunc_0_f_res_6393 : i32} = add32(1i32, x_6391)
          return {returns defunc_0_f_res_6393}
        }
      let {reverse_res_6397 : [m_6213]i32 @ color_6412 ->
                              {base: [m_6213];
                               contiguous: true;
                               LMADs: [{offset: w_minus_1_6278;
                                        strides: [-1i64];
                                        shape: [m_6213];
                                        permutation: [0];
                                        monotonicity: [Dec]}]}} =
        res_6388[w_minus_1_6278 :+ m_6213 * -1i64]
      return {returns reverse_res_6397}
    }
```

If res_6388 is put in color_6413, then reverse_res_6397 will not contain right
result.

The source of the problem is that the general rule that the source of
short-circuiting should be last used at the short-circuit point should not be
enforced when it comes to maps. This works fine if the result of the map is only
ever used directly. But if a later change-of-layout operation relies on the
result of the map it will not work.

If we want to keep maps as potential short-circuit points, I see two solutions:

 1. If the result of a map is short-circuited, we should detect that there are
 no later uses that relies on index-function transformations on the result of
 the map.

 2. If the result of a map is short-circuited, all arrays that alias that result
 should also have their memory block and index function changed.

@Athas: Do you agree with this assessment? Any suggestions?

diku-dk/futhark,diku-dk/futhark,diku-dk/futhark,diku-dk/futhark,diku-dk/futhark