OSDN Git Service

[PowerPC] Use helper functions to check sign-/zero-extended value
authorHiroshi Inoue <inouehrs@jp.ibm.com>
Wed, 18 Oct 2017 10:31:19 +0000 (10:31 +0000)
committerHiroshi Inoue <inouehrs@jp.ibm.com>
Wed, 18 Oct 2017 10:31:19 +0000 (10:31 +0000)
Helper functions to identify sign- and zero-extending machine instruction is introduced in rL315888.
This patch makes PPCInstrInfo::optimizeCompareInstr use the helper functions. It simplifies the code and also makes possible more optimizations since the helper can do more analysis than the original check code; I observed about 5000 more compare instructions are eliminated while building LLVM.

Also, this patch fixes a bug in helpers on ANDIo instruction handling due to the order of checks. This bug causes a failure in an existing test case for optimizeCompareInstr.

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

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

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

index b4da2d6..d12610d 100644 (file)
@@ -1634,37 +1634,20 @@ bool PPCInstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg,
   // Get the unique definition of SrcReg.
   MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg);
   if (!MI) return false;
-  int MIOpC = MI->getOpcode();
 
   bool equalityOnly = false;
   bool noSub = false;
   if (isPPC64) {
     if (is32BitSignedCompare) {
       // We can perform this optimization only if MI is sign-extending.
-      if (MIOpC == PPC::SRAW  || MIOpC == PPC::SRAWo ||
-          MIOpC == PPC::SRAWI || MIOpC == PPC::SRAWIo ||
-          MIOpC == PPC::EXTSB || MIOpC == PPC::EXTSBo ||
-          MIOpC == PPC::EXTSH || MIOpC == PPC::EXTSHo ||
-          MIOpC == PPC::EXTSW || MIOpC == PPC::EXTSWo) {
+      if (isSignExtended(*MI))
         noSub = true;
-      else
+      else
         return false;
     } else if (is32BitUnsignedCompare) {
-      // 32-bit rotate and mask instructions are zero extending only if MB <= ME
-      bool isZeroExtendingRotate  =
-          (MIOpC == PPC::RLWINM || MIOpC == PPC::RLWINMo ||
-           MIOpC == PPC::RLWNM || MIOpC == PPC::RLWNMo)
-          && MI->getOperand(3).getImm() <= MI->getOperand(4).getImm();
-
       // We can perform this optimization, equality only, if MI is
       // zero-extending.
-      // FIXME: Other possible target instructions include ANDISo and
-      //        RLWINM aliases, such as ROTRWI, EXTLWI, SLWI and SRWI.
-      if (MIOpC == PPC::CNTLZW || MIOpC == PPC::CNTLZWo ||
-          MIOpC == PPC::SLW    || MIOpC == PPC::SLWo ||
-          MIOpC == PPC::SRW    || MIOpC == PPC::SRWo ||
-          MIOpC == PPC::ANDIo  ||
-          isZeroExtendingRotate) {
+      if (isZeroExtended(*MI)) {
         noSub = true;
         equalityOnly = true;
       } else
@@ -1811,7 +1794,7 @@ bool PPCInstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg,
   if (!MI) MI = Sub;
 
   int NewOpC = -1;
-  MIOpC = MI->getOpcode();
+  int MIOpC = MI->getOpcode();
   if (MIOpC == PPC::ANDIo || MIOpC == PPC::ANDIo8)
     NewOpC = MIOpC;
   else {
@@ -2223,6 +2206,12 @@ PPCInstrInfo::isSignOrZeroExtended(const MachineInstr &MI, bool SignExt,
   const MachineFunction *MF = MI.getParent()->getParent();
   const MachineRegisterInfo *MRI = &MF->getRegInfo();
 
+  // If we know this instruction returns sign- or zero-extended result,
+  // return true.
+  if (SignExt ? isSignExtendingOp(MI):
+                isZeroExtendingOp(MI))
+    return true;
+
   switch (MI.getOpcode()) {
   case PPC::COPY: {
     unsigned SrcReg = MI.getOperand(1).getReg();
@@ -2339,8 +2328,7 @@ PPCInstrInfo::isSignOrZeroExtended(const MachineInstr &MI, bool SignExt,
   }
 
   default:
-    return SignExt?isSignExtendingOp(MI):
-                   isZeroExtendingOp(MI);
+    break;
   }
   return false;
 }
index b2f17e6..43d4add 100644 (file)
@@ -78,3 +78,24 @@ if.end:
 }
 
 declare void @exit(i32 signext)
+
+; Since %v1 and %v2 are zero-extended 32-bit values, %1 is also zero-extended.
+; In this case, we want to use ORo instead of OR + CMPLWI.
+
+; CHECK-LABEL: fn5
+define zeroext i32 @fn5(i32* %p1, i32* %p2) {
+; CHECK: ORo
+; CHECK-NOT: CMP
+; CHECK: BCC
+  %v1 = load i32, i32* %p1
+  %v2 = load i32, i32* %p2
+  %1 = or i32 %v1, %v2
+  %2 = icmp eq i32 %1, 0
+  br i1 %2, label %foo, label %bar
+
+foo:
+  ret i32 1
+
+bar:
+  ret i32 0
+}