EnzymeAD / EnzymeAD/Enzyme-JAX
NonNegativeResultAnalysis wrongly proves mul(x, y) non-negative
- Dominant language
- MLIR
- Stars
- 131
- Forks
- 53
- Avg merge
- 1d 10h
- Merged PRs (30d)
- 193
Description
HUMAN: while I was working on PR #2576, Codex found an adjacent bug.
---
`guaranteedNonNegativeResult` proves a multiply non-negative by comparing the operands' *defining ops* rather than the operands themselves ([`Utils.cpp:989-995`](https://github.com/EnzymeAD/Enzyme-JAX/blob/main/src/enzyme_ad/jax/Utils.cpp#L989)):
```cpp
auto lhsOp = mulOp.getLhs().getDefiningOp();
auto rhsOp = mulOp.getRhs().getDefiningOp();
if (lhsOp == rhsOp) return State::GUARANTEED; // both null for two block args
```
When both operands are block arguments, `getDefiningOp()` is `nullptr` for each, so `null == null` incorrectly proves `mul(%arg0, %arg1) >= 0` -- even though the product is negative whenever the args have opposite signs. The rule intends "same value squared," but defining-op identity is both **unsound** (distinct block args) and, separately, too weak for multi-result ops.
**Fix:** compare Values directly --
```cpp
if (mulOp.getLhs() == mulOp.getRhs()) return State::GUARANTEED;
```
**Impact:** any consumer of `guaranteedNonNegativeResult` can mis-fire on a product of two distinct block args -- e.g. a `log((a*b)^2) -> 2*log(a*b)` peephole would produce NaN for `a*b < 0`. Found while implementing the non-negativity gate in #2576.
Contributor guide
No contributing guide indexed for this repository
Research direction
Open src/enzyme_ad/jax/Utils.cpp around lines 989-995 and read guaranteedNonNegativeResult, focusing on how the multiply operands are compared. Reproduce the two-block-argument case and verify that distinct values are not marked guaranteed non-negative, while multiplying a value by itself still is.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 1/5
- Estimated time
- Under an hour
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100