Issue 185253
Summary [ConstantFold] Folding loads of vector denormal FP constants ignores denormal-fp-math mode
Labels new issue
Assignees
Reporter cardigan1008
    Here is a miscompilation case when reviewing https://github.com/llvm/llvm-project/pull/182530:

```llvm
@constant_splat_vector_fp = constant <4 x float> <float 0x36A0000000000000, float 0x36A0000000000000, float 0x36A0000000000000, float 0x36A0000000000000>, align 16

define i1 @test() #0 {
  %v = load <4 x float>, ptr @constant_splat_vector_fp, align 16
  %cmp = fcmp oeq <4 x float> %v, zeroinitializer
  %r = extractelement <4 x i1> %cmp, i32 0
  ret i1 %r
}

define i1 @tgt_test() #0 {
  ret i1 false
}

attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
```

With opt built on this patch, it is transformed into:

```llvm
@constant_splat_vector_fp = constant <4 x float> splat (float 0x36A0000000000000), align 16

define i1 @test() #0 {
  ret i1 false
}

attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
```

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

Alive2 proof: https://alive2.llvm.org/ce/z/usWj8c

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

**Bug Triggering Analysis:**
The provided test case triggers the bug because it loads a vector of denormal floating-point values from a global constant and performs a comparison with zero. The function has the `denormal-fp-math` attribute set to `preserve-sign,preserve-sign`, which means denormal values should be flushed to zero. However, the constant folding logic in `ReadDataFromGlobal` and `FoldReinterpretLoadFromConst` does not check the instruction context or function attributes for denormal handling modes when folding vector constants. As a result, the compiler evaluates the comparison using strict IEEE semantics at compile-time, preserving the denormal values and folding the comparison to `false`. At runtime, the denormal values would be flushed to zero, making the comparison `true`.

**Fix Weakness Analysis:**
The fix added support for vector `ConstantInt` and `ConstantFP` in `ReadDataFromGlobal`, allowing `ConstantFoldLoadFromConst` to fold loads from global variables initialized with vector constants. However, it failed to consider that floating-point operations (including loads that might be used in FP ops) are sensitive to the execution environment, specifically denormal handling modes. By enabling constant folding for vector FP constants without checking the instruction context or function attributes, the fix introduced a mismatch between compile-time and runtime behavior for denormal values. This weakness is exposed by the provided test case, which demonstrates that the compiler incorrectly folds a comparison involving a vector of denormal values when flush-to-zero is enabled.

cc @paulwalker-arm 

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

Reply via email to