The code that originally made me discover this is:
authorDaniel Jasper <djasper@google.com>
Tue, 14 Apr 2015 15:20:37 +0000 (15:20 +0000)
committerDaniel Jasper <djasper@google.com>
Tue, 14 Apr 2015 15:20:37 +0000 (15:20 +0000)
  if ((a & 0x1) == 0x1) {
    ..
  }

In this case we don't actually have any branch probability information and
should not assume to have any. LLVM transforms this into:

  %and = and i32 %a, 1
  %tobool = icmp eq i32 %and, 0

So, in this case, the result of a bitwise and is compared against 0,
but nevertheless, we should not assume to have probability
information.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234898 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/BranchProbabilityInfo.cpp
test/Analysis/BranchProbabilityInfo/basic.ll
test/CodeGen/AArch64/arm64-call-tailcalls.ll
test/CodeGen/Mips/octeon.ll

index 14800f4a28bfb3333e420c8db2243d1fd194b804..d7cee3afaf5975c7d0e508fd738f14f2ce273434 100644 (file)
@@ -379,6 +379,14 @@ bool BranchProbabilityInfo::calcZeroHeuristics(BasicBlock *BB) {
   if (!CV)
     return false;
 
+  // If the LHS is the result of AND'ing a value with a single bit bitmask,
+  // we don't have information about probabilities.
+  if (Instruction *LHS = dyn_cast<Instruction>(CI->getOperand(0)))
+    if (LHS->getOpcode() == Instruction::And)
+      if (ConstantInt *AndRHS = dyn_cast<ConstantInt>(LHS->getOperand(1)))
+        if (AndRHS->getUniqueInteger().isPowerOf2())
+          return false;
+
   bool isProb;
   if (CV->isZero()) {
     switch (CI->getPredicate()) {
index 0f669119bfeabb22680801aa7cb0e2a3e5f44d65..2c9c1561868284d96efd2a8e5af30986d05e0b2c 100644 (file)
@@ -212,3 +212,31 @@ exit:
   ret i32 %result
 }
 
+define i32 @zero3(i32 %i, i32 %a, i32 %b) {
+; CHECK: Printing analysis {{.*}} for function 'zero3'
+entry:
+; AND'ing with a single bit bitmask essentially leads to a bool comparison,
+; meaning we don't have probability information.
+  %and = and i32 %i, 2
+  %tobool = icmp eq i32 %and, 0
+  br i1 %tobool, label %then, label %else
+; CHECK: edge entry -> then probability is 16 / 32
+; CHECK: edge entry -> else probability is 16 / 32
+
+then:
+; AND'ing with other bitmask might be something else, so we still assume the
+; usual probabilities.
+  %and2 = and i32 %i, 5
+  %tobool2 = icmp eq i32 %and2, 0
+  br i1 %tobool2, label %else, label %exit
+; CHECK: edge then -> else probability is 12 / 32
+; CHECK: edge then -> exit probability is 20 / 32
+
+else:
+  br label %exit
+
+exit:
+  %result = phi i32 [ %a, %then ], [ %b, %else ]
+  ret i32 %result
+}
+
index 71d932787cecc212a847196516e3855fa4c0fcde..6621db25da5ba9605203f96d33357c722fe57266 100644 (file)
@@ -53,9 +53,9 @@ bb:                                               ; preds = %entry
 
 define i32 @t8(i32 %x) nounwind ssp {
 ; CHECK-LABEL: t8:
+; CHECK: b     _c
 ; CHECK: b     _a
 ; CHECK: b     _b
-; CHECK: b     _c
   %and = and i32 %x, 1
   %tobool = icmp eq i32 %and, 0
   br i1 %tobool, label %if.end, label %if.then
index 97e12e721f5e80c5dc19d09991abef6712515f73..499ce3c1ddbf048fa121b128075fa98804ad269c 100644 (file)
@@ -93,7 +93,7 @@ entry:
 ; ALL-LABEL: bbit0:
 ; OCTEON: bbit0   $4, 3, $[[BB0:BB[0-9_]+]]
 ; MIPS64: andi  $[[T0:[0-9]+]], $4, 8
-; MIPS64: beqz  $[[T0]], $[[BB0:BB[0-9_]+]]
+; MIPS64: bnez  $[[T0]], $[[BB0:BB[0-9_]+]]
   %bit = and i64 %a, 8
   %res = icmp eq i64 %bit, 0
   br i1 %res, label %endif, label %if
@@ -111,7 +111,7 @@ entry:
 ; MIPS64: daddiu  $[[T0:[0-9]+]], $zero, 1
 ; MIPS64: dsll    $[[T1:[0-9]+]], $[[T0]], 35
 ; MIPS64: and     $[[T2:[0-9]+]], $4, $[[T1]]
-; MIPS64: beqz    $[[T2]], $[[BB0:BB[0-9_]+]]
+; MIPS64: bnez    $[[T2]], $[[BB0:BB[0-9_]+]]
   %bit = and i64 %a, 34359738368
   %res = icmp eq i64 %bit, 0
   br i1 %res, label %endif, label %if