cornell-zhang/hcl-dialect

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

zzzDavid opened this issue · 4 comments

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"?

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

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.

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

Fixed by fd5eabe