@@ -257,6 +257,8 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &tm,
257
257
setCondCodeAction (ISD::SETUGE, MVT::f32 , Expand);
258
258
setCondCodeAction (ISD::SETUGT, MVT::f32 , Expand);
259
259
260
+ setTargetDAGCombine (ISD::FADD);
261
+ setTargetDAGCombine (ISD::FSUB);
260
262
setTargetDAGCombine (ISD::BRCOND);
261
263
}
262
264
@@ -395,6 +397,57 @@ void XtensaTargetLowering::LowerAsmOperandForConstraint(
395
397
// DAG Combine functions
396
398
// ===----------------------------------------------------------------------===//
397
399
400
+ static SDValue performMADD_MSUBCombine (SDNode *ROOTNode, SelectionDAG &CurDAG,
401
+ const XtensaSubtarget &Subtarget) {
402
+ if (ROOTNode->getOperand (0 ).getValueType () != MVT::f32 )
403
+ return SDValue ();
404
+
405
+ if (ROOTNode->getOperand (0 ).getOpcode () != ISD::FMUL &&
406
+ ROOTNode->getOperand (1 ).getOpcode () != ISD::FMUL)
407
+ return SDValue ();
408
+
409
+ SDValue Mult = ROOTNode->getOperand (0 ).getOpcode () == ISD::FMUL
410
+ ? ROOTNode->getOperand (0 )
411
+ : ROOTNode->getOperand (1 );
412
+
413
+ SDValue AddOperand = ROOTNode->getOperand (0 ).getOpcode () == ISD::FMUL
414
+ ? ROOTNode->getOperand (1 )
415
+ : ROOTNode->getOperand (0 );
416
+
417
+ if (!Mult.hasOneUse ())
418
+ return SDValue ();
419
+
420
+ SDLoc DL (ROOTNode);
421
+
422
+ bool IsAdd = ROOTNode->getOpcode () == ISD::FADD;
423
+ unsigned Opcode = IsAdd ? XtensaISD::MADD : XtensaISD::MSUB;
424
+ SDValue MAddOps[3 ] = {AddOperand, Mult->getOperand (0 ), Mult->getOperand (1 )};
425
+ EVT VTs[3 ] = {MVT::f32 , MVT::f32 , MVT::f32 };
426
+ SDValue MAdd = CurDAG.getNode (Opcode, DL, VTs, MAddOps);
427
+
428
+ return MAdd;
429
+ }
430
+
431
+ static SDValue performSUBCombine (SDNode *N, SelectionDAG &DAG,
432
+ TargetLowering::DAGCombinerInfo &DCI,
433
+ const XtensaSubtarget &Subtarget) {
434
+ if (DCI.isBeforeLegalizeOps ()) {
435
+ if (Subtarget.hasSingleFloat () && N->getValueType (0 ) == MVT::f32 )
436
+ return performMADD_MSUBCombine (N, DAG, Subtarget);
437
+ }
438
+ return SDValue ();
439
+ }
440
+
441
+ static SDValue performADDCombine (SDNode *N, SelectionDAG &DAG,
442
+ TargetLowering::DAGCombinerInfo &DCI,
443
+ const XtensaSubtarget &Subtarget) {
444
+ if (DCI.isBeforeLegalizeOps ()) {
445
+ if (Subtarget.hasSingleFloat () && N->getValueType (0 ) == MVT::f32 )
446
+ return performMADD_MSUBCombine (N, DAG, Subtarget);
447
+ }
448
+ return SDValue ();
449
+ }
450
+
398
451
static SDValue PerformBRCONDCombine (SDNode *N, SelectionDAG &DAG,
399
452
TargetLowering::DAGCombinerInfo &DCI,
400
453
const XtensaSubtarget &Subtarget) {
@@ -428,6 +481,10 @@ SDValue XtensaTargetLowering::PerformDAGCombine(SDNode *N,
428
481
switch (Opc) {
429
482
default :
430
483
break ;
484
+ case ISD::FADD:
485
+ return performADDCombine (N, DAG, DCI, Subtarget);
486
+ case ISD::FSUB:
487
+ return performSUBCombine (N, DAG, DCI, Subtarget);
431
488
case ISD::BRCOND:
432
489
return PerformBRCONDCombine (N, DAG, DCI, Subtarget);
433
490
}
0 commit comments