@@ -481,6 +481,60 @@ Optional<APInt> llvm::ConstantFoldBinOp(unsigned Opcode, const Register Op1,
481
481
return None;
482
482
}
483
483
484
+ Optional<APFloat> llvm::ConstantFoldFPBinOp (unsigned Opcode, const Register Op1,
485
+ const Register Op2,
486
+ const MachineRegisterInfo &MRI) {
487
+ const ConstantFP *Op2Cst = getConstantFPVRegVal (Op2, MRI);
488
+ if (!Op2Cst)
489
+ return None;
490
+
491
+ const ConstantFP *Op1Cst = getConstantFPVRegVal (Op1, MRI);
492
+ if (!Op1Cst)
493
+ return None;
494
+
495
+ APFloat C1 = Op1Cst->getValueAPF ();
496
+ const APFloat &C2 = Op2Cst->getValueAPF ();
497
+ switch (Opcode) {
498
+ case TargetOpcode::G_FADD:
499
+ C1.add (C2, APFloat::rmNearestTiesToEven);
500
+ return C1;
501
+ case TargetOpcode::G_FSUB:
502
+ C1.subtract (C2, APFloat::rmNearestTiesToEven);
503
+ return C1;
504
+ case TargetOpcode::G_FMUL:
505
+ C1.multiply (C2, APFloat::rmNearestTiesToEven);
506
+ return C1;
507
+ case TargetOpcode::G_FDIV:
508
+ C1.divide (C2, APFloat::rmNearestTiesToEven);
509
+ return C1;
510
+ case TargetOpcode::G_FREM:
511
+ C1.mod (C2);
512
+ return C1;
513
+ case TargetOpcode::G_FCOPYSIGN:
514
+ C1.copySign (C2);
515
+ return C1;
516
+ case TargetOpcode::G_FMINNUM:
517
+ return minnum (C1, C2);
518
+ case TargetOpcode::G_FMAXNUM:
519
+ return maxnum (C1, C2);
520
+ case TargetOpcode::G_FMINIMUM:
521
+ return minimum (C1, C2);
522
+ case TargetOpcode::G_FMAXIMUM:
523
+ return maximum (C1, C2);
524
+ case TargetOpcode::G_FMINNUM_IEEE:
525
+ case TargetOpcode::G_FMAXNUM_IEEE:
526
+ // FIXME: These operations were unfortunately named. fminnum/fmaxnum do not
527
+ // follow the IEEE behavior for signaling nans and follow libm's fmin/fmax,
528
+ // and currently there isn't a nice wrapper in APFloat for the version with
529
+ // correct snan handling.
530
+ break ;
531
+ default :
532
+ break ;
533
+ }
534
+
535
+ return None;
536
+ }
537
+
484
538
bool llvm::isKnownNeverNaN (Register Val, const MachineRegisterInfo &MRI,
485
539
bool SNaN) {
486
540
const MachineInstr *DefMI = MRI.getVRegDef (Val);
0 commit comments