Issue 185240
Summary [InstCombine] `fcmp (bitcast X), 0.0` fold may ignore legacy `"denormal-fp-math"` attribute
Labels new issue
Assignees
Reporter cardigan1008
    Here is a miscompilation case when reviewing https://github.com/llvm/llvm-project/pull/181899:

```llvm
define i1 @bitcast_eq0_denorm_preservesign_input(i32 %x) "denormal-fp-math"="preserve-sign" {
  %f = bitcast i32 %x to float
  %r = fcmp oeq float %f, 0.0
  ret i1 %r
}

define i1 @bitcast_une0_denorm_positivezero_input(i32 %x) "denormal-fp-math"="positive-zero" {
  %f = bitcast i32 %x to float
  %r = fcmp une float %f, 0.0
  ret i1 %r
}

define i1 @bitcast_eq0_denorm_dynamic_input(i32 %x) "denormal-fp-math"="dynamic" {
  %f = bitcast i32 %x to float
  %r = fcmp oeq float %f, 0.0
  ret i1 %r
}

define <2 x i1> @bitcast_eq0_denorm_preservesign_input_vec(<2 x i32> %x) "denormal-fp-math"="preserve-sign" {
  %f = bitcast <2 x i32> %x to <2 x float>
  %r = fcmp oeq <2 x float> %f, <float 0.0, float 0.0>
  ret <2 x i1> %r
}
```

Compiler Explorer: https://godbolt.org/z/xEzrbh69a

Alive2 proof: https://alive2.llvm.org/ce/z/8Yo-Qh

> Note: This is a review assisted with a self-built agent. The reproducer was validated manually. Please let me know if anything is wrong.

The test cases use the legacy `"denormal-fp-math"` function attribute to request denormal modes such as `preserve-sign`, `positive-zero`, and `dynamic`. Under these modes, denormal inputs may be treated as zero, so folding

`fcmp oeq/une (bitcast X), 0.0` into `(and X, SignMask) ==/!= 0`

is not generally valid: a denormal floating-point value may compare equal to `0.0`, while its integer bit pattern is still non-zero.

The issue appears to be tied to how the denormal mode is queried. In the current implementation, `Function::getDenormalMode()` only checks the first-class `Attribute::DenormalFPEnv` attribute and otherwise returns the default mode. If the function still carries the legacy `"denormal-fp-math"` string attribute, this query can miss the requested denormal behavior and incorrectly treat the function as using the default IEEE mode.

I checked the behavior of `"denormal-fp-math"` here: https://llvm.org/docs/ReleaseNotes.html#changes-to-the-llvm-ir, which says:

> “denormal-fp-math” and “denormal-fp-math-f32” string attributes were migrated to first-class denormal_fpenv attribute.

But the check still seems to fail on the latest version of llvm.

cc @jholewinski 
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to