diku-dk / futhark

:boom::computer::boom: A data-parallel functional programming language
http://futhark-lang.org
ISC License
2.4k stars 167 forks source link

"A unique tuple element of return value of function ... is aliased to some other tuple component" ICE #1949

Closed Programmerino closed 1 year ago

Programmerino commented 1 year ago

This bug occurs on 0.24.3 and 889eeb9 (latest commit):

def fn (arr: *[](i32,i32)) =
    if true then opaque arr else opaque arr

entry test = (fn [(0, 0)])[0]

Error:

[  +0.000027] Reading and type-checking source program
[  +0.201637] Defunctorising
[  +0.000658] Full Normalising
[  +0.005616] Monomorphising
[  +0.051983] Lifting lambdas
[  +0.000278] Defunctionalising
[  +0.000249] Converting to core IR
[  +0.000709] Type-checking internalised program
Internal compiler error.  Please report this:
  https://github.com/diku-dk/futhark/issues
After internalisation:
In function fn_6585
When checking the body aliases: [[arr_6634, arr_6635], [arr_6634, arr_6635]]
A unique tuple element of return value of function fn_6585 is aliased to some other tuple component.
types {

}

let {fn_arg_6615 : ({}, [1i64]i32)} =
  [0i32] : []i32
let {fn_arg_6616 : ({}, [1i64]i32)} =
  [0i32] : []i32
let {tmp_6617 : ({}, [1i64]i32),
     tmp_6618 : ({}, [1i64]i32)} =
  -- Consumes fn_arg_6615, fn_arg_6616
  apply fn_6585(1i64, *fn_arg_6615, *fn_arg_6616)
  : {*[1i64]i32, *[1i64]i32}
let {tmp_6619 : ({tmp_6617}, [1i64]i32)} =
  tmp_6617
let {tmp_6620 : ({tmp_6618}, [1i64]i32)} =
  tmp_6618
let {to_i64_6621 : ({}, i64)} =
  sext i32 0i32 to i64
let {x_6622 : ({}, bool)} =
  sle64(0i64, to_i64_6621)
let {y_6623 : ({}, bool)} =
  slt64(to_i64_6621, 1i64)
let {bounds_check_6624 : ({}, bool)} =
  logand(x_6622, y_6623)
let {index_certs_6625 : ({}, unit)} =
  assert(bounds_check_6624, {"Index [", to_i64_6621 : i64, "] out of bounds for array of shape [", 1i64 : i64, "]."}, "bad_2.fut:4:14-29")
let {test_res_6626 : ({}, i32)} =
  #{index_certs_6625}
  tmp_6619[to_i64_6621]
let {test_res_6627 : ({}, i32)} =
  #{index_certs_6625}
  tmp_6620[to_i64_6621]

fun
  opaque_6584 (d_6628 : i64,
               x_6629 : [d_6628]i32,
               x_6630 : [d_6628]i32)
  : {[d_6628]i32,
     [d_6628]i32} = {
  let {opaque_res_6631 : ({x_6629}, [d_6628]i32)} =
    opaque(x_6629)
  let {opaque_res_6632 : ({x_6630}, [d_6628]i32)} =
    opaque(x_6630)
  in {opaque_res_6631, opaque_res_6632}
}

fun
  fn_6585 (d₀_6633 : i64,
           arr_6634 : *[d₀_6633]i32,
           arr_6635 : *[d₀_6633]i32)
  : {*[d₀_6633]i32,
     *[d₀_6633]i32} = {
  let {fn_res_6636 : ({arr_6634, arr_6635, fn_res_6637}, [d₀_6633]i32),
       fn_res_6637 : ({arr_6634, arr_6635, fn_res_6636}, [d₀_6633]i32)} =
    if true
    then {
      let {fn_res_t_res_6638 : ({arr_6634, arr_6635}, [d₀_6633]i32),
           fn_res_t_res_6639 : ({arr_6634, arr_6635}, [d₀_6633]i32)} =
        apply opaque_6584(d₀_6633, arr_6634, arr_6635)
        : {[d₀_6633]i32, [d₀_6633]i32}
      in {fn_res_t_res_6638, fn_res_t_res_6639}
    } else {
      let {fn_res_f_res_6640 : ({arr_6634, arr_6635}, [d₀_6633]i32),
           fn_res_f_res_6641 : ({arr_6634, arr_6635}, [d₀_6633]i32)} =
        apply opaque_6584(d₀_6633, arr_6634, arr_6635)
        : {[d₀_6633]i32, [d₀_6633]i32}
      in {fn_res_f_res_6640, fn_res_f_res_6641}
    }
    : {[d₀_6633]i32,
       [d₀_6633]i32}
  in {fn_res_6636, fn_res_6637}
}

entry("test",
      {},
      {i32,
       i32})
  entry_test ()
  : {i32,
     i32} = {
  {test_res_6626, test_res_6627}
}
athas commented 1 year ago

This is the other end of #803. We can either relax internal type checking a bit more or actually solve it properly this time.