cornell-zhang / hcl-dialect

HeteroCL-MLIR dialect for accelerator design
https://cornell-zhang.github.io/heterocl/index.html
Other
40 stars 17 forks source link

[Cast] Int to Float Cast Assertion Failure: `Assertion `isSimple() && "Expected a SimpleValueType!` #88

Closed zzzDavid closed 2 years ago

zzzDavid commented 2 years ago

Not sure if anyone has bumped into this issue. This happens in mlir/test_dtype.py::test_dtype_cast when casting from int to float. A sample IR:

module {
  func @top(%arg0: memref<100xi1>, %arg1: memref<100xi10>) -> (memref<100xf32>, memref<100xf32>) attributes {itypes = "uu", otypes = "__"} {
    %0 = memref.alloc() {name = "compute_2"} : memref<100xf32>
    %1 = hcl.create_loop_handle "x" : !hcl.LoopHandle
    affine.for %arg2 = 0 to 100 {
      %6 = affine.load %arg0[%arg2] {from = "compute_0", unsigned} : memref<100xi1>
      %7 = arith.extui %6 {unsigned} : i1 to i10
      %8 = affine.load %arg1[%arg2] {from = "compute_1", unsigned} : memref<100xi10>
      %9 = arith.addi %7, %8 {unsigned} : i10
      %10 = arith.sitofp %9 : i10 to f32
      affine.store %10, %0[%arg2] {to = "compute_2"} : memref<100xf32>
    } {loop_name = "x", stage_name = "compute_2"}
    %2 = hcl.create_stage_handle "compute_2" : !hcl.StageHandle
    %3 = memref.alloc() {name = "compute_3"} : memref<100xf32>
    %4 = hcl.create_loop_handle "x" : !hcl.LoopHandle
    affine.for %arg2 = 0 to 100 {
      %6 = affine.load %arg0[%arg2] {from = "compute_0", unsigned} : memref<100xi1>
      %7 = arith.extui %6 {unsigned} : i1 to i10
      %8 = affine.load %arg1[%arg2] {from = "compute_1", unsigned} : memref<100xi10>
      %9 = arith.subi %7, %8 {unsigned} : i10
      %10 = arith.sitofp %9 : i10 to f32
      affine.store %10, %3[%arg2] {to = "compute_3"} : memref<100xf32>
    } {loop_name = "x", stage_name = "compute_3"}
    %5 = hcl.create_stage_handle "compute_3" : !hcl.StageHandle
    return %0, %3 : memref<100xf32>, memref<100xf32>
  }
}

The error message:

python: /home/nz264/shared/llvm-project-14.0.0/llvm/include/llvm/CodeGen/ValueTypes.h:290: llvm::MVT llvm::EVT::getSimpleVT() const: Assertion `isSimple() && "Expected a SimpleValueType!"' failed.
 #0 0x00007f8c78af594f PrintStackTraceSignalHandler(void*) Signals.cpp:0:0
 #1 0x00007f8c78af3379 SignalHandler(int) Signals.cpp:0:0
 #2 0x00007f8c83ee1630 __restore_rt sigaction.c:0:0

What is a "simple value"?

zzzDavid commented 2 years ago

First of all, what is "simple value":

This is related to the extended value type in LLVM:

Extended Value Type. Capable of holding value types which are not native for any processor (such as the i12345 type), as well as the types an MVT can represent.

Here, MVT means "machine value type":

Machine Value Type. Every type that is supported natively by some processor targeted by LLVM occurs here. This means that any legal value type can be represented by an MVT.

Simple value type is an enumerate defined here:

https://llvm.org/doxygen/classllvm_1_1MVT.html#a330aea6151cae3adaf5e179dcfe87346

zzzDavid commented 2 years ago

This issue is related to arithmetic dialect's SIToFP and UIToFP operations.

When source integer type is not in [1, 8, 16, 32, 64], it throws this error.

zzzDavid commented 2 years ago

Therefore, the solution is to extend/truncate the source integer to the same width as float first, and then cast to FP. This is done with a new pass LegalizeCast

zzzDavid commented 2 years ago

Fixed by fd5eabef2c185253971984045f335d13196a7841