[llvm] r197804 - [SystemZ] Optimize comparisons with truncated extended loads

Richard Sandiford rsandifo at linux.vnet.ibm.com
Fri Dec 20 03:56:03 PST 2013


Author: rsandifo
Date: Fri Dec 20 05:56:02 2013
New Revision: 197804

URL: http://llvm.org/viewvc/llvm-project?rev=197804&view=rev
Log:
[SystemZ] Optimize comparisons with truncated extended loads

If the extension of a loaded value is compared against zero and used in
other arithmetic, InstCombine will change the comparison to use the
unextended load.  It's also possible that the comparison could be against
the unextended load from the outset.

In DAG form this becomes a truncation of an extending load.  We want to
strip the truncation if possible so that we can use load-and-test instructions.

Modified:
    llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp
    llvm/trunk/test/CodeGen/SystemZ/int-cmp-44.ll

Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp?rev=197804&r1=197803&r2=197804&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp Fri Dec 20 05:56:02 2013
@@ -1339,6 +1339,27 @@ static void adjustForLTGFR(Comparison &C
   }
 }
 
+// If C compares the truncation of an extending load, try to compare
+// the untruncated value instead.  This exposes more opportunities to
+// reuse CC.
+static void adjustICmpTruncate(SelectionDAG &DAG, Comparison &C) {
+  if (C.Op0.getOpcode() == ISD::TRUNCATE &&
+      C.Op0.getOperand(0).getOpcode() == ISD::LOAD &&
+      C.Op1.getOpcode() == ISD::Constant &&
+      cast<ConstantSDNode>(C.Op1)->getZExtValue() == 0) {
+    LoadSDNode *L = cast<LoadSDNode>(C.Op0.getOperand(0));
+    if (L->getMemoryVT().getStoreSizeInBits()
+        <= C.Op0.getValueType().getSizeInBits()) {
+      unsigned Type = L->getExtensionType();
+      if ((Type == ISD::ZEXTLOAD && C.ICmpType != SystemZICMP::SignedOnly) ||
+          (Type == ISD::SEXTLOAD && C.ICmpType != SystemZICMP::UnsignedOnly)) {
+        C.Op0 = C.Op0.getOperand(0);
+        C.Op1 = DAG.getConstant(0, C.Op0.getValueType());
+      }
+    }
+  }
+}
+
 // Return true if shift operation N has an in-range constant shift value.
 // Store it in ShiftVal if so.
 static bool isSimpleShift(SDValue N, unsigned &ShiftVal) {
@@ -1541,6 +1562,7 @@ static Comparison getCmp(SelectionDAG &D
   if (C.Op0.getValueType().isFloatingPoint()) {
     C.CCValid = SystemZ::CCMASK_FCMP;
     C.Opcode = SystemZISD::FCMP;
+    adjustForFNeg(C);
   } else {
     C.CCValid = SystemZ::CCMASK_ICMP;
     C.Opcode = SystemZISD::ICMP;
@@ -1561,6 +1583,8 @@ static Comparison getCmp(SelectionDAG &D
     adjustZeroCmp(DAG, C);
     adjustSubwordCmp(DAG, C);
     adjustForSubtraction(DAG, C);
+    adjustForLTGFR(C);
+    adjustICmpTruncate(DAG, C);
   }
 
   if (shouldSwapCmpOperands(C)) {
@@ -1569,8 +1593,6 @@ static Comparison getCmp(SelectionDAG &D
   }
 
   adjustForTestUnderMask(DAG, C);
-  adjustForFNeg(C);
-  adjustForLTGFR(C);
   return C;
 }
 

Modified: llvm/trunk/test/CodeGen/SystemZ/int-cmp-44.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/int-cmp-44.ll?rev=197804&r1=197803&r2=197804&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/int-cmp-44.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/int-cmp-44.ll Fri Dec 20 05:56:02 2013
@@ -865,3 +865,25 @@ store:
 exit:
   ret i32 %res
 }
+
+; A version of f32 that tests the unextended value.
+define i64 @f42(i64 %base, i64 %index, i64 *%dest) {
+; CHECK-LABEL: f42:
+; CHECK: ltgf %r2, 0({{%r2,%r3|%r3,%r2}})
+; CHECK-NEXT: jh .L{{.*}}
+; CHECK: br %r14
+entry:
+  %add = add i64 %base, %index
+  %ptr = inttoptr i64 %add to i32 *
+  %val = load i32 *%ptr
+  %res = sext i32 %val to i64
+  %cmp = icmp sgt i32 %val, 0
+  br i1 %cmp, label %exit, label %store
+
+store:
+  store i64 %res, i64 *%dest
+  br label %exit
+
+exit:
+  ret i64 %res
+}





More information about the llvm-commits mailing list