[llvm] r309255 - [PowerPC] enable optimizeCompareInstr for branch with static branch hint

Hiroshi Inoue via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 27 01:14:48 PDT 2017


Author: inouehrs
Date: Thu Jul 27 01:14:48 2017
New Revision: 309255

URL: http://llvm.org/viewvc/llvm-project?rev=309255&view=rev
Log:
[PowerPC] enable optimizeCompareInstr for branch with static branch hint

In optimizeCompareInstr, a compare instruction is eliminated by using a record form instruction if possible.
If the branch instruction that uses the result of the compare has a static branch hint, the optimization does not happen.
This patch makes this optimization happen regardless of the branch hint by splitting branch hint and branch condition before checking the predicate to identify the possible optimizations.

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


Modified:
    llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h
    llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp
    llvm/trunk/test/CodeGen/PowerPC/opt-cmp-inst-cr0-live.ll

Modified: llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h?rev=309255&r1=309254&r2=309255&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h (original)
+++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h Thu Jul 27 01:14:48 2017
@@ -70,6 +70,22 @@ namespace PPC {
   /// Assume the condition register is set by MI(a,b), return the predicate if
   /// we modify the instructions such that condition register is set by MI(b,a).
   Predicate getSwappedPredicate(Predicate Opcode);
+
+  /// Return the condition without hint bits.
+  inline unsigned getPredicateCondition(Predicate Opcode) {
+    return (unsigned)(Opcode & ~BR_HINT_MASK);
+  }
+
+  /// Return the hint bits of the predicate.
+  inline unsigned getPredicateHint(Predicate Opcode) {
+    return (unsigned)(Opcode & BR_HINT_MASK);
+  }
+
+  /// Return predicate consisting of specified condition and hint bits.
+  inline Predicate getPredicate(unsigned Condition, unsigned Hint) {
+    return (Predicate)((Condition & ~BR_HINT_MASK) |
+                       (Hint & BR_HINT_MASK));
+  }
 }
 }
 

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=309255&r1=309254&r2=309255&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp Thu Jul 27 01:14:48 2017
@@ -1640,8 +1640,10 @@ bool PPCInstrInfo::optimizeCompareInstr(
          I != IE; ++I) {
       MachineInstr *UseMI = &*I;
       if (UseMI->getOpcode() == PPC::BCC) {
-        unsigned Pred = UseMI->getOperand(0).getImm();
-        if (Pred != PPC::PRED_EQ && Pred != PPC::PRED_NE)
+        PPC::Predicate Pred = (PPC::Predicate)UseMI->getOperand(0).getImm();
+        unsigned PredCond = PPC::getPredicateCondition(Pred);
+        // We ignore hint bits when checking for non-equality comparisons.
+        if (PredCond != PPC::PRED_EQ && PredCond != PPC::PRED_NE)
           return false;
       } else if (UseMI->getOpcode() == PPC::ISEL ||
                  UseMI->getOpcode() == PPC::ISEL8) {
@@ -1695,19 +1697,23 @@ bool PPCInstrInfo::optimizeCompareInstr(
       MachineInstr *UseMI = &*MRI->use_instr_begin(CRReg);
       if (UseMI->getOpcode() == PPC::BCC) {
         PPC::Predicate Pred = (PPC::Predicate)UseMI->getOperand(0).getImm();
+        unsigned PredCond = PPC::getPredicateCondition(Pred);
+        unsigned PredHint = PPC::getPredicateHint(Pred);
         int16_t Immed = (int16_t)Value;
 
-        if (Immed == -1 && Pred == PPC::PRED_GT) {
+        // When modyfing the condition in the predicate, we propagate hint bits
+        // from the original predicate to the new one.
+        if (Immed == -1 && PredCond == PPC::PRED_GT) {
           // We convert "greater than -1" into "greater than or equal to 0",
           // since we are assuming signed comparison by !equalityOnly
           PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)),
-                                  PPC::PRED_GE));
+                                  PPC::getPredicate(PPC::PRED_GE, PredHint)));
           Success = true;
         }
-        else if (Immed == 1 && Pred == PPC::PRED_LT) {
+        else if (Immed == 1 && PredCond == PPC::PRED_LT) {
           // We convert "less than 1" into "less than or equal to 0".
           PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)),
-                                  PPC::PRED_LE));
+                                  PPC::getPredicate(PPC::PRED_LE, PredHint)));
           Success = true;
         }
       }
@@ -1804,9 +1810,11 @@ bool PPCInstrInfo::optimizeCompareInstr(
       MachineInstr *UseMI = &*I;
       if (UseMI->getOpcode() == PPC::BCC) {
         PPC::Predicate Pred = (PPC::Predicate) UseMI->getOperand(0).getImm();
+        unsigned PredCond = PPC::getPredicateCondition(Pred);
         assert((!equalityOnly ||
-                Pred == PPC::PRED_EQ || Pred == PPC::PRED_NE) &&
+                PredCond == PPC::PRED_EQ || PredCond == PPC::PRED_NE) &&
                "Invalid predicate for equality-only optimization");
+        (void)PredCond; // To suppress warning in release build.
         PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)),
                                 PPC::getSwappedPredicate(Pred)));
       } else if (UseMI->getOpcode() == PPC::ISEL ||

Modified: llvm/trunk/test/CodeGen/PowerPC/opt-cmp-inst-cr0-live.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/opt-cmp-inst-cr0-live.ll?rev=309255&r1=309254&r2=309255&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/opt-cmp-inst-cr0-live.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/opt-cmp-inst-cr0-live.ll Thu Jul 27 01:14:48 2017
@@ -54,3 +54,27 @@ foo:
 bar:
   ret i32 0
 }
+
+; This test case confirms that a record-form instruction is
+; generated even if the branch has a static branch hint.
+
+; CHECK-LABEL: fn4
+define i64 @fn4(i64 %a, i64 %b) {
+; CHECK: ADD8o
+; CHECK-NOT: CMP
+; CHECK: BCC 71
+
+entry:
+  %add = add nsw i64 %b, %a
+  %cmp = icmp eq i64 %add, 0
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @exit(i32 signext 0) #3
+  unreachable
+
+if.end:
+  ret i64 %add
+}
+
+declare void @exit(i32 signext)




More information about the llvm-commits mailing list