Index: lib/Analysis/BranchProbabilityInfo.cpp =================================================================== --- lib/Analysis/BranchProbabilityInfo.cpp +++ lib/Analysis/BranchProbabilityInfo.cpp @@ -118,6 +118,13 @@ 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, it should be extremely rare in normal +/// programs, usually it means something is wrong in the code when it occurs. +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 @@ -778,6 +785,8 @@ if (!FCmp) return false; + uint32_t TakenWeight = FPH_TAKEN_WEIGHT; + uint32_t NontakenWeight = FPH_NONTAKEN_WEIGHT; bool isProb; if (FCmp->isEquality()) { // f1 == f2 -> Unlikely @@ -786,9 +795,13 @@ } 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; } @@ -798,8 +811,7 @@ 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; Index: test/Analysis/BranchProbabilityInfo/fcmp.ll =================================================================== --- test/Analysis/BranchProbabilityInfo/fcmp.ll +++ test/Analysis/BranchProbabilityInfo/fcmp.ll @@ -0,0 +1,41 @@ +; 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() Index: test/CodeGen/SystemZ/call-05.ll =================================================================== --- test/CodeGen/SystemZ/call-05.ll +++ test/CodeGen/SystemZ/call-05.ll @@ -451,8 +451,9 @@ 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;