From 35c93e4e42d7a35a90e89211fa62f478e25ba0a4 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Fri, 23 Aug 2013 11:27:19 +0000 Subject: [SystemZ] Try reversing comparisons whose first operand is in memory This allows us to make more use of the many compare reg,mem instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189099 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/SystemZ/SystemZISelLowering.cpp | 71 ++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'lib/Target/SystemZ') diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index a1eecd7..65b2ad2 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -1110,6 +1110,69 @@ static bool preferUnsignedComparison(SelectionDAG &DAG, SDValue CmpOp0, return false; } +// Return true if Op is either an unextended load, or a load with the +// extension type given by IsUnsigned. +static bool isNaturalMemoryOperand(SDValue Op, bool IsUnsigned) { + LoadSDNode *Load = dyn_cast(Op.getNode()); + if (Load) + switch (Load->getExtensionType()) { + case ISD::NON_EXTLOAD: + case ISD::EXTLOAD: + return true; + case ISD::SEXTLOAD: + return !IsUnsigned; + case ISD::ZEXTLOAD: + return IsUnsigned; + default: + break; + } + return false; +} + +// Return true if it is better to swap comparison operands Op0 and Op1. +// IsUnsigned says whether an integer comparison is signed or unsigned. +static bool shouldSwapCmpOperands(SDValue Op0, SDValue Op1, + bool IsUnsigned) { + // Leave f128 comparisons alone, since they have no memory forms. + if (Op0.getValueType() == MVT::f128) + return false; + + // Always keep a floating-point constant second, since comparisons with + // zero can use LOAD TEST and comparisons with other constants make a + // natural memory operand. + if (isa(Op1)) + return false; + + // Never swap comparisons with zero since there are many ways to optimize + // those later. + ConstantSDNode *COp1 = dyn_cast(Op1); + if (COp1 && COp1->getZExtValue() == 0) + return false; + + // Look for cases where Cmp0 is a single-use load and Cmp1 isn't. + // In that case we generally prefer the memory to be second. + if ((isNaturalMemoryOperand(Op0, IsUnsigned) && Op0.hasOneUse()) && + !(isNaturalMemoryOperand(Op1, IsUnsigned) && Op1.hasOneUse())) { + // The only exceptions are when the second operand is a constant and + // we can use things like CHHSI. + if (!COp1) + return true; + if (IsUnsigned) { + // The memory-immediate instructions require 16-bit unsigned integers. + if (isUInt<16>(COp1->getZExtValue())) + return false; + } else { + // There are no comparisons between integers and signed memory bytes. + // The others require 16-bit signed integers. + if (cast(Op0.getNode())->getMemoryVT() == MVT::i8 || + isInt<16>(COp1->getSExtValue())) + return false; + } + return true; + } + return false; +} + // Return a target node that compares CmpOp0 with CmpOp1 and stores a // 2-bit result in CC. Set CCValid to the CCMASK_* of all possible // 2-bit results and CCMask to the subset of those results that are @@ -1131,6 +1194,14 @@ static SDValue emitCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1, IsUnsigned = true; } + if (shouldSwapCmpOperands(CmpOp0, CmpOp1, IsUnsigned)) { + std::swap(CmpOp0, CmpOp1); + CCMask = ((CCMask & SystemZ::CCMASK_CMP_EQ) | + (CCMask & SystemZ::CCMASK_CMP_GT ? SystemZ::CCMASK_CMP_LT : 0) | + (CCMask & SystemZ::CCMASK_CMP_LT ? SystemZ::CCMASK_CMP_GT : 0) | + (CCMask & SystemZ::CCMASK_CMP_UO)); + } + SDLoc DL(CmpOp0); return DAG.getNode((IsUnsigned ? SystemZISD::UCMP : SystemZISD::CMP), DL, MVT::Glue, CmpOp0, CmpOp1); -- cgit v1.1