[llvm] r322161 - [SystemZ] Check for legality before doing LOAD AND TEST transformations.

Jonas Paulsson via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 10 01:18:17 PST 2018


Author: jonpa
Date: Wed Jan 10 01:18:17 2018
New Revision: 322161

URL: http://llvm.org/viewvc/llvm-project?rev=322161&view=rev
Log:
[SystemZ]  Check for legality before doing LOAD AND TEST transformations.

Since a load and test instruction treat its operands as signed, it can only
replace a logical compare for EQ/NE uses.

Review: Ulrich Weigand
https://bugs.llvm.org/show_bug.cgi?id=35662

Added:
    llvm/trunk/test/CodeGen/SystemZ/load-and-test.mir
Modified:
    llvm/trunk/lib/Target/SystemZ/SystemZElimCompare.cpp

Modified: llvm/trunk/lib/Target/SystemZ/SystemZElimCompare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZElimCompare.cpp?rev=322161&r1=322160&r2=322161&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZElimCompare.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZElimCompare.cpp Wed Jan 10 01:18:17 2018
@@ -86,9 +86,11 @@ private:
                      SmallVectorImpl<MachineInstr *> &CCUsers);
   bool convertToLoadAndTrap(MachineInstr &MI, MachineInstr &Compare,
                             SmallVectorImpl<MachineInstr *> &CCUsers);
-  bool convertToLoadAndTest(MachineInstr &MI);
+  bool convertToLoadAndTest(MachineInstr &MI, MachineInstr &Compare,
+                            SmallVectorImpl<MachineInstr *> &CCUsers);
   bool adjustCCMasksForInstr(MachineInstr &MI, MachineInstr &Compare,
-                             SmallVectorImpl<MachineInstr *> &CCUsers);
+                             SmallVectorImpl<MachineInstr *> &CCUsers,
+                             unsigned ConvOpc = 0);
   bool optimizeCompareZero(MachineInstr &Compare,
                            SmallVectorImpl<MachineInstr *> &CCUsers);
   bool fuseCompareOperations(MachineInstr &Compare,
@@ -282,9 +284,13 @@ bool SystemZElimCompare::convertToLoadAn
 
 // If MI is a load instruction, try to convert it into a LOAD AND TEST.
 // Return true on success.
-bool SystemZElimCompare::convertToLoadAndTest(MachineInstr &MI) {
+bool SystemZElimCompare::convertToLoadAndTest(
+    MachineInstr &MI, MachineInstr &Compare,
+    SmallVectorImpl<MachineInstr *> &CCUsers) {
+
+  // Try to adjust CC masks for a LOAD AND TEST opcode that could replace MI.
   unsigned Opcode = TII->getLoadAndTest(MI.getOpcode());
-  if (!Opcode)
+  if (!Opcode || !adjustCCMasksForInstr(MI, Compare, CCUsers, Opcode))
     return false;
 
   MI.setDesc(TII->get(Opcode));
@@ -294,14 +300,16 @@ bool SystemZElimCompare::convertToLoadAn
 }
 
 // The CC users in CCUsers are testing the result of a comparison of some
-// value X against zero and we know that any CC value produced by MI
-// would also reflect the value of X.  Try to adjust CCUsers so that
-// they test the result of MI directly, returning true on success.
-// Leave everything unchanged on failure.
+// value X against zero and we know that any CC value produced by MI would
+// also reflect the value of X.  ConvOpc may be used to pass the transfomed
+// opcode MI will have if this succeeds.  Try to adjust CCUsers so that they
+// test the result of MI directly, returning true on success.  Leave
+// everything unchanged on failure.
 bool SystemZElimCompare::adjustCCMasksForInstr(
     MachineInstr &MI, MachineInstr &Compare,
-    SmallVectorImpl<MachineInstr *> &CCUsers) {
-  int Opcode = MI.getOpcode();
+    SmallVectorImpl<MachineInstr *> &CCUsers,
+    unsigned ConvOpc) {
+  int Opcode = (ConvOpc ? ConvOpc : MI.getOpcode());
   const MCInstrDesc &Desc = TII->get(Opcode);
   unsigned MIFlags = Desc.TSFlags;
 
@@ -358,9 +366,11 @@ bool SystemZElimCompare::adjustCCMasksFo
   }
 
   // CC is now live after MI.
-  int CCDef = MI.findRegisterDefOperandIdx(SystemZ::CC, false, true, TRI);
-  assert(CCDef >= 0 && "Couldn't find CC set");
-  MI.getOperand(CCDef).setIsDead(false);
+  if (!ConvOpc) {
+    int CCDef = MI.findRegisterDefOperandIdx(SystemZ::CC, false, true, TRI);
+    assert(CCDef >= 0 && "Couldn't find CC set");
+    MI.getOperand(CCDef).setIsDead(false);
+  }
 
   // Clear any intervening kills of CC.
   MachineBasicBlock::iterator MBBI = MI, MBBE = Compare;
@@ -419,7 +429,7 @@ bool SystemZElimCompare::optimizeCompare
         }
       }
       // Try to eliminate Compare by reusing a CC result from MI.
-      if ((!CCRefs && convertToLoadAndTest(MI)) ||
+      if ((!CCRefs && convertToLoadAndTest(MI, Compare, CCUsers)) ||
           (!CCRefs.Def && adjustCCMasksForInstr(MI, Compare, CCUsers))) {
         EliminatedComparisons += 1;
         return true;
@@ -441,7 +451,7 @@ bool SystemZElimCompare::optimizeCompare
     MachineInstr &MI = *MBBI;
     if (preservesValueOf(MI, SrcReg)) {
       // Try to eliminate Compare by reusing a CC result from MI.
-      if (convertToLoadAndTest(MI)) {
+      if (convertToLoadAndTest(MI, Compare, CCUsers)) {
         EliminatedComparisons += 1;
         return true;
       }

Added: llvm/trunk/test/CodeGen/SystemZ/load-and-test.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/load-and-test.mir?rev=322161&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/load-and-test.mir (added)
+++ llvm/trunk/test/CodeGen/SystemZ/load-and-test.mir Wed Jan 10 01:18:17 2018
@@ -0,0 +1,52 @@
+# RUN: llc -mtriple=s390x-linux-gnu -mcpu=z13 -start-before=postrapseudos %s -o - \
+# RUN:   | FileCheck %s
+#
+# Check that integer load and test instructions are not emitted for unsigned
+# comparisons unless checking for equality. That would be wrong, since the
+# operands are implicitly treated as signed values.
+
+# Not legal: Logical comparison used for >= (CCMask is 10).
+# CHECK-LABEL: fun0
+# CHECK-NOT: lt
+---
+name:            fun0
+tracksRegLiveness: true
+body:             |
+  bb.0 ():
+    liveins: %r1d
+    renamable %r0l = L %r1d, 0, %noreg
+    CLFIMux killed renamable %r0l, 0, implicit-def %cc
+    BRC 14, 10, %bb.2, implicit %cc
+
+  bb.1 ():
+    liveins: %r0l
+    ST killed renamable %r0l, %r15d, 164, %noreg
+
+  bb.2 ():
+    liveins: %r0l
+    ST killed renamable %r0l, %r15d, 164, %noreg
+    Return
+...
+
+# Legal: Logical comparison used for == (CCMask is 8).
+# CHECK-LABEL: fun1
+# CHECK: lt
+---
+name:            fun1
+tracksRegLiveness: true
+body:             |
+  bb.0 ():
+    liveins: %r1d
+    renamable %r0l = L %r1d, 0, %noreg
+    CLFIMux killed renamable %r0l, 0, implicit-def %cc
+    BRC 14, 8, %bb.2, implicit %cc
+
+  bb.1 ():
+    liveins: %r0l
+    ST killed renamable %r0l, %r15d, 164, %noreg
+
+  bb.2 ():
+    liveins: %r0l
+    ST killed renamable %r0l, %r15d, 164, %noreg
+    Return
+...




More information about the llvm-commits mailing list