[MLIR][Math] Miscompilation: `--math-expand-ops` loses the sign of zero when expanding `math.ceil`
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
## Reproducer
### small.mlir
```mlir
memref.global "private" @v : memref<2xf32> = dense<[-2.5e-01, -0.0]>
memref.global "private" @w : memref<2xf64> = dense<[-2.5e-01, -0.0]>
func.func @main() {
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
%g = memref.get_global @v : memref<2xf32>
%a = memref.load %g[%c0] : memref<2xf32>
%b = memref.load %g[%c1] : memref<2xf32>
%ca = math.ceil %a : f32
%cb = math.ceil %b : f32
vector.print %ca : f32
vector.print %cb : f32
%h = memref.get_global @w : memref<2xf64>
%d = memref.load %h[%c0] : memref<2xf64>
%e = memref.load %h[%c1] : memref<2xf64>
%cd = math.ceil %d : f64
%ce = math.ceil %e : f64
vector.print %cd : f64
vector.print %ce : f64
return
}
```
The values come out of a mutable global so that nothing folds them; with literals the program folds and the two routes agree on the folded constant.
### To reproduce
`$LLVM_LIB` is the `lib` directory of an `mlir-opt`/`mlir-runner` build; no other library is needed. The two commands differ in one pass and nothing else.
**Correct:**
```
mlir-opt small.mlir \
--convert-math-to-llvm --finalize-memref-to-llvm --convert-func-to-llvm \
--convert-arith-to-llvm --convert-vector-to-llvm --reconcile-unrealized-casts \
| mlir-runner -e main --entry-point-result=void \
--shared-libs=$LLVM_LIB/libmlir_c_runner_utils.so,$LLVM_LIB/libmlir_runner_utils.so
```
Output:
```
-0
-0
-0
-0
```
**Wrong:**
```
mlir-opt small.mlir --math-expand-ops
--convert-math-to-llvm --finalize-memref-to-llvm --convert-func-to-llvm \
--convert-arith-to-llvm --convert-vector-to-llvm --reconcile-unrealized-casts \
| mlir-runner -e main --entry-point-result=void \
--shared-libs=$LLVM_LIB/libmlir_c_runner_utils.so,$LLVM_LIB/libmlir_runner_utils.so
```
Output:
```
0
0
0
0
```
Contributor guide
Research direction
Start by running the supplied small.mlir reproducer through mlir-opt and mlir-runner, comparing the pipelines with and without --math-expand-ops. Trace the expansion of math.ceil and add coverage for f32 and f64 negative zero. Done means the expanded path prints -0 for all four values, matching the unexpanded path.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100