llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.75k stars 11.89k forks source link

invalid code generation using --test-math-algebraic-simplification #82622

Open wangyongj1a opened 8 months ago

wangyongj1a commented 8 months ago

I have the following MLIR program: test.mlir:

module {
  func.func @func1() {
    %0 = arith.constant false
    %1 = arith.constant true
    %2 = math.ipowi %0, %1 : i1
    vector.print %2 : i1
    return
  }
}

When I tried mlir-opt --test-math-algebraic-simplification test.mlir, then the math.ipowi operation was optimized to :

module {
  func.func @func1() {
    %false = arith.constant false
    %true = arith.constant true
    %0 = arith.divsi %true, %false : i1  // division by zero
    vector.print %0 : i1
    return
  }
}

which seems would get a poison value for the returning value.

By the way, I found that --canonicalize can not optimize this case. However, when I change %0 and %1 to other values of i1, or just change the bitwidth, the--test-math-algebraic-simplification won't get a division by zero result, and --canonicalize can also optimize it. I'm not sure if the value in the test.mlir is illegal, or if I didn't find the correct way to optimize math.ipowi operation? My git version is 4a602d9250e1eb3c729d0421d11be2be8693cbf2.

llvmbot commented 8 months ago

@llvm/issue-subscribers-mlir

Author: None (wangyongj1a)

I have the following MLIR program: test.mlir: ``` module { func.func @func1() { %0 = arith.constant false %1 = arith.constant true %2 = math.ipowi %0, %1 : i1 vector.print %2 : i1 return } } ``` When I tried ```mlir-opt --test-math-algebraic-simplification test.mlir```, then the math.ipowi operation was optimized to : ``` module { func.func @func1() { %false = arith.constant false %true = arith.constant true %0 = arith.divsi %true, %false : i1 // division by zero vector.print %0 : i1 return } } ``` which seems would get a poison value for the returning value. By the way, I found that ```--canonicalize``` can not optimize this case. However, when I change %0 and %1 to other values of i1, or just change the bitwidth, the```--test-math-algebraic-simplification``` won't get a division by zero result, and ```--canonicalize``` can also optimize it. I'm not sure if the value in the ```test.mlir``` is illegal, or if I didn't find the correct way to optimize math.ipowi operation? My git version is 4a602d9250e1eb3c729d0421d11be2be8693cbf2.
wangyongj1a commented 23 hours ago

I made a small change where I cast the result of math.ipowi to f32 type, and made the function return the casted value to satisfy mlir-cpu-runner. test.mlir:

module {
  func.func @func1() -> f32 {
    %0 = arith.constant false
    %1 = arith.constant true
    %2 = math.ipowi %0, %1 : i1
    vector.print %2 : i1
    %3 = arith.sitofp %2 : i1 to f32
    return %3 : f32
  }
}

When I ran /data/tmp/v1029/llvm-project/build/bin/mlir-opt --test-math-algebraic-simplification --convert-arith-to-llvm --convert-vector-to-llvm --convert-func-to-llvm test.mlir | /data/tmp/v1029/llvm-project/build/bin/mlir-cpu-runner -e func1 --shared-libs=/data/tmp/v1029/llvm-project/build/lib/libmlir_runner_utils.so,/data/tmp/v1029/llvm-project/build/lib/libmlir_c_runner_utils.so on the program, I got inconsistent results over multiple runs.

However, when I ran /data/tmp/v1029/llvm-project/build/bin/mlir-opt --convert-math-to-funcs --convert-arith-to-llvm --convert-vector-to-llvm --convert-func-to-llvm test.mlir | /data/tmp/v1029/llvm-project/build/bin/mlir-cpu-runner -e func1 --shared-libs=/data/tmp/v1029/llvm-project/build/lib/libmlir_runner_utils.so,/data/tmp/v1029/llvm-project/build/lib/libmlir_c_runner_utils.so on the program, I got the result of:

1
-1.000000e+00

This problem seems to still exist. I'm not sure if there is any bug in my program or if the wrong usage of the above passes caused these results. My git version is e19a5fc6d306a81d181a9597a8b25c444c08d722.