@@ -1252,6 +1252,34 @@ static bool shouldSwapCmpOperands(SDValue Op0, SDValue Op1,
1252
1252
return false ;
1253
1253
}
1254
1254
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
+
1255
1283
// Return true if shift operation N has an in-range constant shift value.
1256
1284
// Store it in ShiftVal if so.
1257
1285
static bool isSimpleShift (SDValue N, unsigned &ShiftVal) {
@@ -1463,14 +1491,12 @@ static SDValue emitCmp(const SystemZTargetMachine &TM, SelectionDAG &DAG,
1463
1491
1464
1492
if (shouldSwapCmpOperands (CmpOp0, CmpOp1, ICmpType)) {
1465
1493
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);
1470
1495
}
1471
1496
1472
1497
adjustForTestUnderMask (DAG, Opcode, CmpOp0, CmpOp1, CCValid, CCMask,
1473
1498
ICmpType);
1499
+ adjustForFNeg (CmpOp0, CmpOp1, CCMask);
1474
1500
if (Opcode == SystemZISD::ICMP || Opcode == SystemZISD::TM)
1475
1501
return DAG.getNode (Opcode, DL, MVT::Glue, CmpOp0, CmpOp1,
1476
1502
DAG.getConstant (ICmpType, MVT::i32 ));
0 commit comments