Since NaN is very rare in normal programs, so the probability for floating point unordered comparison should be extremely small. Current probability is 3/8, it is too large, this patch changes it to a tiny number.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
I've never looked to this piece of code before. For that reason I would like some one more familiar with this part to make a review.
lib/Analysis/BranchProbabilityInfo.cpp | ||
---|---|---|
122 ↗ | (On Diff #211842) | How was this weight selected? Why 2**20 - 1 in particular? If it's just to match IH_TAKEN_WEIGHT, let's use that value instead of repeating it here. The comment could probable use a little work, too. I broadly agree with the *effect* of this change, but I don't think that unordered is that rare--rather, NaN is often an indication that something has gone wrong, and it makes sense to move that off the hot path. |
Comment change.
lib/Analysis/BranchProbabilityInfo.cpp | ||
---|---|---|
122 ↗ | (On Diff #211842) | It has no semantic relation with IH_TAKEN_WEIGHT, I looked for an appropriate weight to represent the extremely likely probability, and IH_TAKEN_WEIGHT has the similar effect on control flow, so I used the same number. Do you still think it's better to use IH_TAKEN_WEIGHT here, or what probability is more appropriate here? |
isnan() is lowered to fcmp uno, in this case the taken probability may be higher, but still much smaller than ordered result, and the usage of isnan() is already very rare, most of uno comparisons are generated from different math library functions.
On the other side I guess most of the taken uno comparisons in a correct program comes from explicitly isnan() call.
It's not that NaN is rare in normal programs, or that it indicates a bug in the code. It's that testing for NaN is usually an indication that you're testing for an exceptional case, and it makes sense to move those off the hot path (i.e. NaN is actually pretty common, but the likelihood of handling it on the normal-value path through code is small).
test/CodeGen/SystemZ/call-05.ll | ||
---|---|---|
456 ↗ | (On Diff #211944) | I know nothing about Z architecture; is this codegen change actually an improvement? What architectural considerations are at work here? |
test/CodeGen/SystemZ/call-05.ll | ||
---|---|---|
456 ↗ | (On Diff #211944) | In this case, the machine code if conversion only considers branch and a target with non trivial probability, the original probability is 3/8, large enough to enable this if conversion. After reducing the probability, if conversion thinks it is too small, not worth the effort to optimize it. |
What will this do to software that does frequently use NaNs and doesn't treat them as exceptional?
static prediction is intended to help common use cases, so for corner cases when NaNs are used frequently, user will need to resort to source annotation (such as builtin_expect).
I think this patch was motivated by the perf of some (micro)benchmarks attached in @Carrot’s previous patch and patch fixes the perf issue.
But I agree, more benchmark results would be useful.