static const uint32_t FPH_TAKEN_WEIGHT = 20;
static const uint32_t FPH_NONTAKEN_WEIGHT = 12;
+/// This is the probability for an ordered floating point comparison.
+static const uint32_t FPH_ORD_WEIGHT = 1024 * 1024 - 1;
+/// This is the probability for an unordered floating point comparison, it means
+/// one or two of the operands are NaN. Usually it is used to test for an
+/// exceptional case, so the result is unlikely.
+static const uint32_t FPH_UNO_WEIGHT = 1;
+
/// Invoke-terminating normal branch taken weight
///
/// This is the weight for branching to the normal destination of an invoke
if (!FCmp)
return false;
+ uint32_t TakenWeight = FPH_TAKEN_WEIGHT;
+ uint32_t NontakenWeight = FPH_NONTAKEN_WEIGHT;
bool isProb;
if (FCmp->isEquality()) {
// f1 == f2 -> Unlikely
} else if (FCmp->getPredicate() == FCmpInst::FCMP_ORD) {
// !isnan -> Likely
isProb = true;
+ TakenWeight = FPH_ORD_WEIGHT;
+ NontakenWeight = FPH_UNO_WEIGHT;
} else if (FCmp->getPredicate() == FCmpInst::FCMP_UNO) {
// isnan -> Unlikely
isProb = false;
+ TakenWeight = FPH_ORD_WEIGHT;
+ NontakenWeight = FPH_UNO_WEIGHT;
} else {
return false;
}
if (!isProb)
std::swap(TakenIdx, NonTakenIdx);
- BranchProbability TakenProb(FPH_TAKEN_WEIGHT,
- FPH_TAKEN_WEIGHT + FPH_NONTAKEN_WEIGHT);
+ BranchProbability TakenProb(TakenWeight, TakenWeight + NontakenWeight);
setEdgeProbability(BB, TakenIdx, TakenProb);
setEdgeProbability(BB, NonTakenIdx, TakenProb.getCompl());
return true;
--- /dev/null
+; RUN: opt < %s -analyze -branch-prob | FileCheck %s
+
+; This function tests the floating point unorder comparison. The probability
+; of NaN should be extremely small.
+; CHECK: Printing analysis 'Branch Probability Analysis' for function 'uno'
+; CHECK: edge -> a probability is 0x00000800 / 0x80000000 = 0.00%
+; CHECK: edge -> b probability is 0x7ffff800 / 0x80000000 = 100.00% [HOT edge]
+
+define void @uno(float %val1, float %val2) {
+ %cond = fcmp uno float %val1, %val2
+ br i1 %cond, label %a, label %b
+
+a:
+ call void @fa()
+ ret void
+
+b:
+ call void @fb()
+ ret void
+}
+
+; This function tests the floating point order comparison.
+; CHECK: Printing analysis 'Branch Probability Analysis' for function 'ord'
+; CHECK: edge -> a probability is 0x7ffff800 / 0x80000000 = 100.00% [HOT edge]
+; CHECK: edge -> b probability is 0x00000800 / 0x80000000 = 0.00%
+
+define void @ord(float %val1, float %val2) {
+ %cond = fcmp ord float %val1, %val2
+ br i1 %cond, label %a, label %b
+
+a:
+ call void @fa()
+ ret void
+
+b:
+ call void @fb()
+ ret void
+}
+
+declare void @fa()
+declare void @fb()
define void @f25(float %val1, float %val2) {
; CHECK-LABEL: f25:
; CHECK: cebr %f0, %f2
-; CHECK: bor %r1
+; CHECK: jo
; CHECK: br %r14
+; CHECK: br %r1
%fun_a = load volatile void() *, void()** @fun_a;
%cond = fcmp uno float %val1, %val2;
br i1 %cond, label %a, label %b;