Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:Update
llvm
backport-llvm-r197804
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File backport-llvm-r197804 of Package llvm
------------------------------------------------------------------------ r197804 | rsandifo | 2013-12-20 12:56:02 +0100 (Fri, 20 Dec 2013) | 10 lines [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. ------------------------------------------------------------------------ Index: lib/Target/SystemZ/SystemZISelLowering.cpp =================================================================== --- lib/Target/SystemZ/SystemZISelLowering.cpp.orig +++ 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<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; } Index: test/CodeGen/SystemZ/int-cmp-44.ll =================================================================== --- test/CodeGen/SystemZ/int-cmp-44.ll.orig +++ 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 +}
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