Issue 137196
Summary copysign not preserving sign bit of a NaN
Labels new issue
Assignees
Reporter regehr
    we're optimizing this:
```llvm
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare float @llvm.copysign.f32(float, float) #0

define nofpclass(ninf nzero nsub nnorm) float @f(float %0) {
  %2 = call float @llvm.copysign.f32(float 0x7FF8000000000000, float %0)
  ret float %2
}

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
```

to:
```llvm
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
define noundef nofpclass(ninf nzero nsub nnorm) float @f(float %0) local_unnamed_addr #0 {
  ret float 0x7FF8000000000000
}

attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
```

Alive complains that the optimized code will flip the sign bit of a NaN, while the unoptimized code preserved it as required by LangRef's specification of the copysign semantics:
> The returned value is completely identical to the first operand except for the sign bit; in particular, if the input is a NaN, then the quiet/signaling bit and payload are perfectly preserved.

If any of the individual flags in `nofpclass(ninf nzero nsub nnorm)` are removed, then we don't do this transformation. Am I missing something here where these flags, together, mean that it's legal to flip the sign of a NaN? Obviously the transformation is just fine when `nofpclass(nan)` is there

https://alive2.llvm.org/ce/z/ja96Yf

cc @dtcxzyw @nunoplopes 
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to