Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
llvm.7809
backport-llvm-r197238
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File backport-llvm-r197238 of Package llvm.7809
------------------------------------------------------------------------ r197238 | rsandifo | 2013-12-13 16:46:55 +0100 (Fri, 13 Dec 2013) | 8 lines [SystemZ] Make more use of TMHH This originally came about after noticing that InstCombine turns some of the TMHH (icmp (and...), ...) tests into plain comparisons. Since there is no instruction to compare with a 64-bit immediate, TMHH is generally better than an ordered comparison for the cases that it can handle. ------------------------------------------------------------------------ Index: lib/Target/SystemZ/SystemZISelLowering.cpp =================================================================== --- lib/Target/SystemZ/SystemZISelLowering.cpp.orig +++ lib/Target/SystemZ/SystemZISelLowering.cpp @@ -1440,47 +1440,75 @@ static void adjustForTestUnderMask(Selec uint64_t CmpVal = ConstOp1->getZExtValue(); // Check whether the nonconstant input is an AND with a constant mask. - if (C.Op0.getOpcode() != ISD::AND) - return; - SDValue AndOp0 = C.Op0.getOperand(0); - SDValue AndOp1 = C.Op0.getOperand(1); - ConstantSDNode *Mask = dyn_cast<ConstantSDNode>(AndOp1.getNode()); - if (!Mask) - return; - uint64_t MaskVal = Mask->getZExtValue(); + Comparison NewC(C); + uint64_t MaskVal; + ConstantSDNode *Mask = 0; + if (C.Op0.getOpcode() == ISD::AND) { + NewC.Op0 = C.Op0.getOperand(0); + NewC.Op1 = C.Op0.getOperand(1); + Mask = dyn_cast<ConstantSDNode>(NewC.Op1); + if (!Mask) + return; + MaskVal = Mask->getZExtValue(); + } else { + // There is no instruction to compare with a 64-bit immediate + // so use TMHH instead if possible. We need an unsigned ordered + // comparison with an i64 immediate. + if (NewC.Op0.getValueType() != MVT::i64 || + NewC.CCMask == SystemZ::CCMASK_CMP_EQ || + NewC.CCMask == SystemZ::CCMASK_CMP_NE || + NewC.ICmpType == SystemZICMP::SignedOnly) + return; + // Convert LE and GT comparisons into LT and GE. + if (NewC.CCMask == SystemZ::CCMASK_CMP_LE || + NewC.CCMask == SystemZ::CCMASK_CMP_GT) { + if (CmpVal == uint64_t(-1)) + return; + CmpVal += 1; + NewC.CCMask ^= SystemZ::CCMASK_CMP_EQ; + } + // If the low N bits of Op1 are zero than the low N bits of Op0 can + // be masked off without changing the result. + MaskVal = -(CmpVal & -CmpVal); + NewC.ICmpType = SystemZICMP::UnsignedOnly; + } // Check whether the combination of mask, comparison value and comparison // type are suitable. - unsigned BitSize = C.Op0.getValueType().getSizeInBits(); + unsigned BitSize = NewC.Op0.getValueType().getSizeInBits(); unsigned NewCCMask, ShiftVal; - if (C.ICmpType != SystemZICMP::SignedOnly && - AndOp0.getOpcode() == ISD::SHL && - isSimpleShift(AndOp0, ShiftVal) && - (NewCCMask = getTestUnderMaskCond(BitSize, C.CCMask, MaskVal >> ShiftVal, + if (NewC.ICmpType != SystemZICMP::SignedOnly && + NewC.Op0.getOpcode() == ISD::SHL && + isSimpleShift(NewC.Op0, ShiftVal) && + (NewCCMask = getTestUnderMaskCond(BitSize, NewC.CCMask, + MaskVal >> ShiftVal, CmpVal >> ShiftVal, SystemZICMP::Any))) { - AndOp0 = AndOp0.getOperand(0); - AndOp1 = DAG.getConstant(MaskVal >> ShiftVal, AndOp0.getValueType()); - } else if (C.ICmpType != SystemZICMP::SignedOnly && - AndOp0.getOpcode() == ISD::SRL && - isSimpleShift(AndOp0, ShiftVal) && - (NewCCMask = getTestUnderMaskCond(BitSize, C.CCMask, + NewC.Op0 = NewC.Op0.getOperand(0); + MaskVal >>= ShiftVal; + } else if (NewC.ICmpType != SystemZICMP::SignedOnly && + NewC.Op0.getOpcode() == ISD::SRL && + isSimpleShift(NewC.Op0, ShiftVal) && + (NewCCMask = getTestUnderMaskCond(BitSize, NewC.CCMask, MaskVal << ShiftVal, CmpVal << ShiftVal, SystemZICMP::UnsignedOnly))) { - AndOp0 = AndOp0.getOperand(0); - AndOp1 = DAG.getConstant(MaskVal << ShiftVal, AndOp0.getValueType()); + NewC.Op0 = NewC.Op0.getOperand(0); + MaskVal <<= ShiftVal; } else { - NewCCMask = getTestUnderMaskCond(BitSize, C.CCMask, MaskVal, CmpVal, - C.ICmpType); + NewCCMask = getTestUnderMaskCond(BitSize, NewC.CCMask, MaskVal, CmpVal, + NewC.ICmpType); if (!NewCCMask) return; } // Go ahead and make the change. C.Opcode = SystemZISD::TM; - C.Op0 = AndOp0; - C.Op1 = AndOp1; + C.Op0 = NewC.Op0; + if (Mask && Mask->getZExtValue() == MaskVal) + C.Op1 = SDValue(Mask, 0); + else + C.Op1 = DAG.getConstant(MaskVal, C.Op0.getValueType()); C.CCValid = SystemZ::CCMASK_TM; C.CCMask = NewCCMask; } Index: test/CodeGen/SystemZ/int-cmp-47.ll =================================================================== --- test/CodeGen/SystemZ/int-cmp-47.ll.orig +++ test/CodeGen/SystemZ/int-cmp-47.ll @@ -232,3 +232,112 @@ store: exit: ret void } + +; Check a case where TMHH can be used to implement a ult comparison. +define void @f13(i64 %a) { +; CHECK-LABEL: f13: +; CHECK: tmhh %r2, 49152 +; CHECK: jno {{\.L.*}} +; CHECK: br %r14 +entry: + %cmp = icmp ult i64 %a, 13835058055282163712 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} + +; And again with ule. +define void @f14(i64 %a) { +; CHECK-LABEL: f14: +; CHECK: tmhh %r2, 49152 +; CHECK: jno {{\.L.*}} +; CHECK: br %r14 +entry: + %cmp = icmp ule i64 %a, 13835058055282163711 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} + +; And again with ugt. +define void @f15(i64 %a) { +; CHECK-LABEL: f15: +; CHECK: tmhh %r2, 49152 +; CHECK: jo {{\.L.*}} +; CHECK: br %r14 +entry: + %cmp = icmp ugt i64 %a, 13835058055282163711 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} + +; And again with uge. +define void @f16(i64 %a) { +; CHECK-LABEL: f16: +; CHECK: tmhh %r2, 49152 +; CHECK: jo {{\.L.*}} +; CHECK: br %r14 +entry: + %cmp = icmp uge i64 %a, 13835058055282163712 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} + +; Decrease the constant from f13 to make TMHH invalid. +define void @f17(i64 %a) { +; CHECK-LABEL: f17: +; CHECK-NOT: tmhh +; CHECK: llihh {{%r[0-5]}}, 49151 +; CHECK-NOT: tmhh +; CHECK: br %r14 +entry: + %cmp = icmp ult i64 %a, 13834776580305453056 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} + +; Check that we don't use TMHH just to test the top bit. +define void @f18(i64 %a) { +; CHECK-LABEL: f18: +; CHECK-NOT: tmhh +; CHECK: cgijhe %r2, 0, +; CHECK: br %r14 +entry: + %cmp = icmp ult i64 %a, 9223372036854775808 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +}
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor