Diff Detail
Event Timeline
SimplifyIntrinsic() is structured in a confusing way; can you rearrange the whole function (in a separate patch) to look more like the following?
if (IsIdempotent(IID)) { [...] } switch (IID) { case Intrinsic::usub_with_overflow: [...] case Intrinsic::fabs: [...] }
test/Transforms/InstSimplify/floating-point-arithmetic.ll | ||
---|---|---|
133–134 | fabs() returns +0 if the input is -0, so we can't eliminate it here. |
lib/Analysis/ValueTracking.cpp | ||
---|---|---|
2612–2613 | I think the sign of a NaN is OK to ignore |
lib/Analysis/ValueTracking.cpp | ||
---|---|---|
2612–2613 | It's OK [in the IEEE 754 sense] to ignore the sign of NaN with all operations *except* abs, copysign, copy, and negate. So fabs(x) is not equivalent to x if x is NaN, but fabs(x*x) -> x*x is OK if x might be NaN, because the sign of x*x has no meaning if x is NaN. |
lib/Analysis/ValueTracking.cpp | ||
---|---|---|
2612–2613 | Okay, since there seems to be some confusion here, I went and took a look at the standard. It says "For all other operations, this standard does not specify the sign bit of a NaN result." So x*x has an unspecified sign, and fabs(x*x) has a sign bit which is always clear. From this we can conclude that something like fabs(x*x) + 1 -> x*x + 1 is a legal transformation, but the general transform proposed here is not legal. For example, copysign(1, fabs(x*x)) == 1, but copysign(1, x*x) could be either 1 or -1 depending on the target. |
lib/Analysis/ValueTracking.cpp | ||
---|---|---|
2612–2613 | Correct. Sorry for the confusion. |
LGTM.
include/llvm/Analysis/ValueTracking.h | ||
---|---|---|
179 | Minor tweak: Depth is never explicitly passed in, so might as well get rid of the argument. |
Minor tweak: Depth is never explicitly passed in, so might as well get rid of the argument.