[BPI] Adjust the probability for floating point unordered comparison
authorGuozhi Wei <carrot@google.com>
Tue, 10 Sep 2019 17:25:11 +0000 (17:25 +0000)
committerGuozhi Wei <carrot@google.com>
Tue, 10 Sep 2019 17:25:11 +0000 (17:25 +0000)
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.

Differential Revision: https://reviews.llvm.org/D65303

llvm-svn: 371541

llvm/lib/Analysis/BranchProbabilityInfo.cpp
llvm/test/Analysis/BranchProbabilityInfo/fcmp.ll [new file with mode: 0644]
llvm/test/CodeGen/SystemZ/call-05.ll

index 65c9cf2..a06ee09 100644 (file)
@@ -118,6 +118,13 @@ static const uint32_t ZH_NONTAKEN_WEIGHT = 12;
 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
@@ -778,6 +785,8 @@ bool BranchProbabilityInfo::calcFloatingPointHeuristics(const BasicBlock *BB) {
   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 @@ bool BranchProbabilityInfo::calcFloatingPointHeuristics(const BasicBlock *BB) {
   } 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 @@ bool BranchProbabilityInfo::calcFloatingPointHeuristics(const BasicBlock *BB) {
   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;
diff --git a/llvm/test/Analysis/BranchProbabilityInfo/fcmp.ll b/llvm/test/Analysis/BranchProbabilityInfo/fcmp.ll
new file mode 100644 (file)
index 0000000..8089916
--- /dev/null
@@ -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 1570453..b958c0b 100644 (file)
@@ -451,8 +451,9 @@ b:
 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;