Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:Update
llvm
backport-llvm-r197032
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File backport-llvm-r197032 of Package llvm
------------------------------------------------------------------------ r197032 | rsandifo | 2013-12-11 12:45:08 +0100 (Wed, 11 Dec 2013) | 5 lines [SystemZ] Optimize fcmp X, 0 in cases where X is also negated In such cases it's often better to test the result of the negation instead, since the negation also sets CC. ------------------------------------------------------------------------ Index: test/CodeGen/SystemZ/fp-cmp-04.ll =================================================================== --- test/CodeGen/SystemZ/fp-cmp-04.ll.orig +++ test/CodeGen/SystemZ/fp-cmp-04.ll @@ -365,3 +365,43 @@ store: exit: ret float %res } + +; Test another form of f7 in which the condition is based on the unnegated +; result. This is what InstCombine would produce. +define float @f18(float %dummy, float %a, float *%dest) { +; CHECK-LABEL: f18: +; CHECK: lnebr %f0, %f2 +; CHECK-NEXT: jl .L{{.*}} +; CHECK: br %r14 +entry: + %abs = call float @llvm.fabs.f32(float %a) + %res = fsub float -0.0, %abs + %cmp = fcmp ogt float %abs, 0.0 + br i1 %cmp, label %exit, label %store + +store: + store float %res, float *%dest + br label %exit + +exit: + ret float %res +} + +; Similarly for f8. +define float @f19(float %dummy, float %a, float *%dest) { +; CHECK-LABEL: f19: +; CHECK: lcebr %f0, %f2 +; CHECK-NEXT: jle .L{{.*}} +; CHECK: br %r14 +entry: + %res = fsub float -0.0, %a + %cmp = fcmp oge float %a, 0.0 + br i1 %cmp, label %exit, label %store + +store: + store float %res, float *%dest + br label %exit + +exit: + ret float %res +} Index: lib/Target/SystemZ/SystemZISelLowering.cpp =================================================================== --- lib/Target/SystemZ/SystemZISelLowering.cpp.orig +++ lib/Target/SystemZ/SystemZISelLowering.cpp @@ -1252,6 +1252,34 @@ static bool shouldSwapCmpOperands(SDValu return false; } +// Return a version of comparison CC mask CCMask in which the LT and GT +// actions are swapped. +static unsigned reverseCCMask(unsigned CCMask) { + return ((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)); +} + +// CmpOp0 and CmpOp1 are being compared using CC mask CCMask. Check whether +// CmpOp0 is a floating-point result that is also negated and if CmpOp1 +// is zero. In this case we can use the negation to set CC, so avoiding +// separate LOAD AND TEST and LOAD (NEGATIVE/COMPLEMENT) instructions. +static void adjustForFNeg(SDValue &CmpOp0, SDValue &CmpOp1, unsigned &CCMask) { + ConstantFPSDNode *C1 = dyn_cast<ConstantFPSDNode>(CmpOp1); + if (C1 && C1->isZero()) { + for (SDNode::use_iterator I = CmpOp0->use_begin(), E = CmpOp0->use_end(); + I != E; ++I) { + SDNode *N = *I; + if (N->getOpcode() == ISD::FNEG) { + CmpOp0 = SDValue(N, 0); + CCMask = reverseCCMask(CCMask); + return; + } + } + } +} + // 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) { @@ -1463,14 +1491,12 @@ static SDValue emitCmp(const SystemZTarg if (shouldSwapCmpOperands(CmpOp0, CmpOp1, ICmpType)) { 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)); + CCMask = reverseCCMask(CCMask); } adjustForTestUnderMask(DAG, Opcode, CmpOp0, CmpOp1, CCValid, CCMask, ICmpType); + adjustForFNeg(CmpOp0, CmpOp1, CCMask); if (Opcode == SystemZISD::ICMP || Opcode == SystemZISD::TM) return DAG.getNode(Opcode, DL, MVT::Glue, CmpOp0, CmpOp1, DAG.getConstant(ICmpType, MVT::i32));
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