[llvm] r316647 - [PowerPC] Use record-form instruction for Less-or-Equal -1 and Greater-or-Equal 1

Hiroshi Inoue via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 26 02:01:51 PDT 2017


Author: inouehrs
Date: Thu Oct 26 02:01:51 2017
New Revision: 316647

URL: http://llvm.org/viewvc/llvm-project?rev=316647&view=rev
Log:
[PowerPC] Use record-form instruction for Less-or-Equal -1 and Greater-or-Equal 1

Currently a record-form instruction is used for comparison of "greater than -1" and "less than 1" by modifying the predicate (e.g. LT 1 into LE 0) in addition to the naive case of comparison against 0.
This patch also enables emitting a record-form instruction for "less than or equal to -1" (i.e. "less than 0") and "greater than or equal to 1" (i.e. "greater than 0") to increase the optimization opportunities.

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


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

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=316647&r1=316646&r2=316647&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp Thu Oct 26 02:01:51 2017
@@ -1715,38 +1715,47 @@ bool PPCInstrInfo::optimizeCompareInstr(
   else if (MI->getParent() != CmpInstr.getParent())
     return false;
   else if (Value != 0) {
-    // The record-form instructions set CR bit based on signed comparison against 0.
-    // We try to convert a compare against 1 or -1 into a compare against 0.
-    bool Success = false;
-    if (!equalityOnly && MRI->hasOneUse(CRReg)) {
-      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;
-
-        // 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::getPredicate(PPC::PRED_GE, PredHint)));
-          Success = true;
-        }
-        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::getPredicate(PPC::PRED_LE, PredHint)));
-          Success = true;
-        }
-      }
-    }
+    // The record-form instructions set CR bit based on signed comparison
+    // against 0. We try to convert a compare against 1 or -1 into a compare
+    // against 0 to exploit record-form instructions. For example, we change
+    // the condition "greater than -1" into "greater than or equal to 0"
+    // and "less than 1" into "less than or equal to 0".
 
-    // PPC does not have a record-form SUBri.
-    if (!Success)
+    // Since we optimize comparison based on a specific branch condition,
+    // we don't optimize if condition code is used by more than once.
+    if (equalityOnly || !MRI->hasOneUse(CRReg))
       return false;
+
+    MachineInstr *UseMI = &*MRI->use_instr_begin(CRReg);
+    if (UseMI->getOpcode() != PPC::BCC)
+      return false;
+
+    PPC::Predicate Pred = (PPC::Predicate)UseMI->getOperand(0).getImm();
+    PPC::Predicate NewPred = Pred;
+    unsigned PredCond = PPC::getPredicateCondition(Pred);
+    unsigned PredHint = PPC::getPredicateHint(Pred);
+    int16_t Immed = (int16_t)Value;
+
+    // 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
+      NewPred = PPC::getPredicate(PPC::PRED_GE, PredHint);
+    else if (Immed == -1 && PredCond == PPC::PRED_LE)
+      // We convert "less than or equal to -1" into "less than 0".
+      NewPred = PPC::getPredicate(PPC::PRED_LT, PredHint);
+    else if (Immed == 1 && PredCond == PPC::PRED_LT)
+      // We convert "less than 1" into "less than or equal to 0".
+      NewPred = PPC::getPredicate(PPC::PRED_LE, PredHint);
+    else if (Immed == 1 && PredCond == PPC::PRED_GE)
+      // We convert "greater than or equal to 1" into "greater than 0".
+      NewPred = PPC::getPredicate(PPC::PRED_GT, PredHint);
+    else
+      return false;
+
+    PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)),
+                                            NewPred));
   }
 
   // Search for Sub.

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=316647&r1=316646&r2=316647&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 Oct 26 02:01:51 2017
@@ -1,4 +1,5 @@
 ; RUN: llc -verify-machineinstrs -print-before=peephole-opt -print-after=peephole-opt -mtriple=powerpc64-unknown-linux-gnu -o /dev/null 2>&1 < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -print-before=peephole-opt -print-after=peephole-opt -mtriple=powerpc64le-unknown-linux-gnu -o /dev/null 2>&1 < %s | FileCheck %s
 
 ; CHECK-LABEL: fn1
 define signext i32 @fn1(i32 %baz) {
@@ -99,3 +100,38 @@ foo:
 bar:
   ret i32 0
 }
+
+; This test confirms record-form instructions are emitted for comparison
+; against a non-zero value.
+
+; CHECK-LABEL: fn6
+define i8* @fn6(i8* readonly %p) {
+; CHECK: LBZU
+; CHECK: EXTSBo
+; CHECK-NOT: CMP
+; CHECK: BCC
+; CHECK: LBZU
+; CHECK: EXTSBo
+; CHECK-NOT: CMP
+; CHECK: BCC
+
+entry:
+  %incdec.ptr = getelementptr inbounds i8, i8* %p, i64 -1
+  %0 = load i8, i8* %incdec.ptr
+  %cmp = icmp sgt i8 %0, -1
+  br i1 %cmp, label %out, label %if.end
+
+if.end:
+  %incdec.ptr2 = getelementptr inbounds i8, i8* %p, i64 -2
+  %1 = load i8, i8* %incdec.ptr2
+  %cmp4 = icmp sgt i8 %1, -1
+  br i1 %cmp4, label %out, label %cleanup
+
+out:
+  %p.addr.0 = phi i8* [ %incdec.ptr, %entry ], [ %incdec.ptr2, %if.end ]
+  br label %cleanup
+
+cleanup:
+  %retval.0 = phi i8* [ %p.addr.0, %out ], [ null, %if.end ]
+  ret i8* %retval.0
+}




More information about the llvm-commits mailing list