diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index baef2c1d0b3..e916771efa8 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -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(C.Op1)->getZExtValue() == 0) { + LoadSDNode *L = cast(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 &DAG, SDValue CmpOp0, SDValue CmpOp1, 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 &DAG, SDValue CmpOp0, SDValue CmpOp1, 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 &DAG, SDValue CmpOp0, SDValue CmpOp1, } adjustForTestUnderMask(DAG, C); - adjustForFNeg(C); - adjustForLTGFR(C); return C; } diff --git a/test/CodeGen/SystemZ/int-cmp-44.ll b/test/CodeGen/SystemZ/int-cmp-44.ll index 8ab67f70e62..822dcac3059 100644 --- a/test/CodeGen/SystemZ/int-cmp-44.ll +++ b/test/CodeGen/SystemZ/int-cmp-44.ll @@ -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 +}