Skip to content

Commit 73170f8

Browse files
author
Richard Sandiford
committed
[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. llvm-svn: 197032
1 parent 9fc2b96 commit 73170f8

File tree

2 files changed

+70
-4
lines changed

2 files changed

+70
-4
lines changed

llvm/lib/Target/SystemZ/SystemZISelLowering.cpp

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,6 +1252,34 @@ static bool shouldSwapCmpOperands(SDValue Op0, SDValue Op1,
12521252
return false;
12531253
}
12541254

1255+
// Return a version of comparison CC mask CCMask in which the LT and GT
1256+
// actions are swapped.
1257+
static unsigned reverseCCMask(unsigned CCMask) {
1258+
return ((CCMask & SystemZ::CCMASK_CMP_EQ) |
1259+
(CCMask & SystemZ::CCMASK_CMP_GT ? SystemZ::CCMASK_CMP_LT : 0) |
1260+
(CCMask & SystemZ::CCMASK_CMP_LT ? SystemZ::CCMASK_CMP_GT : 0) |
1261+
(CCMask & SystemZ::CCMASK_CMP_UO));
1262+
}
1263+
1264+
// CmpOp0 and CmpOp1 are being compared using CC mask CCMask. Check whether
1265+
// CmpOp0 is a floating-point result that is also negated and if CmpOp1
1266+
// is zero. In this case we can use the negation to set CC, so avoiding
1267+
// separate LOAD AND TEST and LOAD (NEGATIVE/COMPLEMENT) instructions.
1268+
static void adjustForFNeg(SDValue &CmpOp0, SDValue &CmpOp1, unsigned &CCMask) {
1269+
ConstantFPSDNode *C1 = dyn_cast<ConstantFPSDNode>(CmpOp1);
1270+
if (C1 && C1->isZero()) {
1271+
for (SDNode::use_iterator I = CmpOp0->use_begin(), E = CmpOp0->use_end();
1272+
I != E; ++I) {
1273+
SDNode *N = *I;
1274+
if (N->getOpcode() == ISD::FNEG) {
1275+
CmpOp0 = SDValue(N, 0);
1276+
CCMask = reverseCCMask(CCMask);
1277+
return;
1278+
}
1279+
}
1280+
}
1281+
}
1282+
12551283
// Return true if shift operation N has an in-range constant shift value.
12561284
// Store it in ShiftVal if so.
12571285
static bool isSimpleShift(SDValue N, unsigned &ShiftVal) {
@@ -1463,14 +1491,12 @@ static SDValue emitCmp(const SystemZTargetMachine &TM, SelectionDAG &DAG,
14631491

14641492
if (shouldSwapCmpOperands(CmpOp0, CmpOp1, ICmpType)) {
14651493
std::swap(CmpOp0, CmpOp1);
1466-
CCMask = ((CCMask & SystemZ::CCMASK_CMP_EQ) |
1467-
(CCMask & SystemZ::CCMASK_CMP_GT ? SystemZ::CCMASK_CMP_LT : 0) |
1468-
(CCMask & SystemZ::CCMASK_CMP_LT ? SystemZ::CCMASK_CMP_GT : 0) |
1469-
(CCMask & SystemZ::CCMASK_CMP_UO));
1494+
CCMask = reverseCCMask(CCMask);
14701495
}
14711496

14721497
adjustForTestUnderMask(DAG, Opcode, CmpOp0, CmpOp1, CCValid, CCMask,
14731498
ICmpType);
1499+
adjustForFNeg(CmpOp0, CmpOp1, CCMask);
14741500
if (Opcode == SystemZISD::ICMP || Opcode == SystemZISD::TM)
14751501
return DAG.getNode(Opcode, DL, MVT::Glue, CmpOp0, CmpOp1,
14761502
DAG.getConstant(ICmpType, MVT::i32));

llvm/test/CodeGen/SystemZ/fp-cmp-04.ll

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,3 +365,43 @@ store:
365365
exit:
366366
ret float %res
367367
}
368+
369+
; Test another form of f7 in which the condition is based on the unnegated
370+
; result. This is what InstCombine would produce.
371+
define float @f18(float %dummy, float %a, float *%dest) {
372+
; CHECK-LABEL: f18:
373+
; CHECK: lnebr %f0, %f2
374+
; CHECK-NEXT: jl .L{{.*}}
375+
; CHECK: br %r14
376+
entry:
377+
%abs = call float @llvm.fabs.f32(float %a)
378+
%res = fsub float -0.0, %abs
379+
%cmp = fcmp ogt float %abs, 0.0
380+
br i1 %cmp, label %exit, label %store
381+
382+
store:
383+
store float %res, float *%dest
384+
br label %exit
385+
386+
exit:
387+
ret float %res
388+
}
389+
390+
; Similarly for f8.
391+
define float @f19(float %dummy, float %a, float *%dest) {
392+
; CHECK-LABEL: f19:
393+
; CHECK: lcebr %f0, %f2
394+
; CHECK-NEXT: jle .L{{.*}}
395+
; CHECK: br %r14
396+
entry:
397+
%res = fsub float -0.0, %a
398+
%cmp = fcmp oge float %a, 0.0
399+
br i1 %cmp, label %exit, label %store
400+
401+
store:
402+
store float %res, float *%dest
403+
br label %exit
404+
405+
exit:
406+
ret float %res
407+
}

0 commit comments

Comments
 (0)