This is an archive of the discontinued LLVM Phabricator instance.

ValueTracking: fadd +0 cannot return -0
ClosedPublic

Authored by arsenm on Apr 13 2023, 7:08 AM.

Diff Detail

Event Timeline

arsenm created this revision.Apr 13 2023, 7:08 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 13 2023, 7:08 AM
arsenm requested review of this revision.Apr 13 2023, 7:08 AM
Herald added a reviewer: sstefan1. · View Herald Transcript
Herald added a project: Restricted Project. · View Herald Transcript
Herald added a subscriber: wdng. · View Herald Transcript
kpn added inline comments.Apr 13 2023, 7:15 AM
llvm/lib/Analysis/ValueTracking.cpp
4557

We're in the default FP environment here since we're looking at FAdd and FSub instructions. The check for FAdd isn't needed?

arsenm updated this revision to Diff 513228.Apr 13 2023, 7:28 AM

Also handle sub

llvm/lib/Analysis/ValueTracking.cpp
4557

I was just copying from CannotBeNegativeZero but I guess we can improve on it at the same time

foad added inline comments.Apr 13 2023, 8:30 AM
llvm/lib/Analysis/ValueTracking.cpp
4557

As I understand it, with default rounding the only addition that can return -0 is -0 + -0. So if either operand is known not to be -0, the result cannot be -0. And the only subtraction that can return -0 is -0 - +0.

arsenm added inline comments.Apr 13 2023, 8:57 AM
llvm/lib/Analysis/ValueTracking.cpp
4557

Checking what instcombine thinks,

define float @fsub_p0_p0(float %arg0) {
  %sub = fsub float 0.0, 0.0
  ret float %sub
}

define float @fsub_n0_n0(float %arg0) {
  %sub = fsub float -0.0, -0.0
  ret float %sub
}

define float @fsub_p0_n0(float %arg0) {
  %sub = fsub float 0.0, -0.0
  ret float %sub
}

define float @fsub_n0_p0(float %arg0) {
  %sub = fsub float -0.0, 0.0
  ret float %sub
}
define float @fsub_p0_p0(float %arg0) {
  ret float 0.000000e+00
}

define float @fsub_n0_n0(float %arg0) {
  ret float 0.000000e+00
}

define float @fsub_p0_n0(float %arg0) {
  ret float 0.000000e+00
}

define float @fsub_n0_p0(float %arg0) {
  ret float -0.000000e+00
}

The missing optimization we could do here is check if DAZ is enabled and also cover denormal inputs

foad added inline comments.Apr 20 2023, 2:48 AM
llvm/lib/Analysis/ValueTracking.cpp
4557

First, this is wrong for FSub, since -0 - +0 = -0

Second, you can generalize KnownRHS.KnownFPClasses == fcPosZero to KnownRHS.isKnownNot(fcNegZero) (or fcPosZero for FSub).

Third you could do a similar check on the LHS. For both FAdd and FSub, if the LHS is not -0 then the result can't be -0.

arsenm updated this revision to Diff 515504.Apr 20 2023, 3:19 PM

Fix fsub and DAZ handling

arsenm planned changes to this revision.Apr 20 2023, 5:33 PM
arsenm updated this revision to Diff 515548.Apr 20 2023, 5:45 PM
arsenm updated this revision to Diff 515550.Apr 20 2023, 6:08 PM
foad added inline comments.Apr 21 2023, 3:55 AM
llvm/include/llvm/Analysis/ValueTracking.h
281

Matter of taste I guess, but I don't think a helper function this simple actually helps.

llvm/lib/Analysis/ValueTracking.cpp
3936–3961

Could use inputDenormalIsIEEEOrPosZero here.

3968

This doesn't work. If denormal mode is PosZero then a denormal can be flushed to +0, so this function should return false.

arsenm updated this revision to Diff 516503.Apr 24 2023, 12:42 PM
arsenm marked an inline comment as done.

Fix pos zero bug by just fully handling the denormal modes

ping

llvm/include/llvm/Analysis/ValueTracking.h
281

Mostly for consistency with the others

foad accepted this revision.May 5 2023, 2:40 AM

LGTM

llvm/lib/Analysis/ValueTracking.cpp
3945

Nit: might as well push this into the PositiveZero/default case.

This revision is now accepted and ready to land.May 5 2023, 2:40 AM
arsenm added inline comments.May 16 2023, 3:47 AM
llvm/lib/Analysis/ValueTracking.cpp
3945

That wouldn't short circuit the attribute parsing