3333// ===----------------------------------------------------------------------===//
3434
3535#include " InstCombineInternal.h"
36+ #include " llvm/ADT/APFloat.h"
3637#include " llvm/ADT/APInt.h"
3738#include " llvm/ADT/ArrayRef.h"
3839#include " llvm/ADT/DenseMap.h"
@@ -4043,52 +4044,57 @@ InstCombinerImpl::foldExtractOfOverflowIntrinsic(ExtractValueInst &EV) {
40434044 return nullptr ;
40444045}
40454046
4046- static Value *foldFrexpOfSelect (ExtractValueInst &EV, CallInst *FrexpCall,
4047+ static Value *foldFrexpOfSelect (ExtractValueInst &EV, IntrinsicInst *FrexpCall,
40474048 SelectInst *SelectInst,
40484049 InstCombiner::BuilderTy &Builder) {
40494050 // Helper to fold frexp of select to select of frexp.
40504051 Value *Cond = SelectInst->getCondition ();
40514052 Value *TrueVal = SelectInst->getTrueValue ();
40524053 Value *FalseVal = SelectInst->getFalseValue ();
4053- ConstantFP *ConstOp = nullptr ;
4054+
4055+ const APFloat *ConstVal = nullptr ;
40544056 Value *VarOp = nullptr ;
40554057 bool ConstIsTrue = false ;
40564058
4057- if (auto *TrueConst = dyn_cast<ConstantFP>(TrueVal)) {
4058- ConstOp = TrueConst;
4059+ if (match (TrueVal, m_APFloat (ConstVal))) {
40594060 VarOp = FalseVal;
40604061 ConstIsTrue = true ;
4061- } else if (auto *FalseConst = dyn_cast<ConstantFP>(FalseVal)) {
4062- ConstOp = FalseConst;
4062+ } else if (match (FalseVal, m_APFloat (ConstVal))) {
40634063 VarOp = TrueVal;
40644064 ConstIsTrue = false ;
4065+ } else {
4066+ return nullptr ;
40654067 }
40664068
4067- if (!ConstOp || !VarOp)
4068- return nullptr ;
4069+ Builder.SetInsertPoint (&EV);
40694070
40704071 CallInst *NewFrexp =
40714072 Builder.CreateCall (FrexpCall->getCalledFunction (), {VarOp}, " frexp" );
4073+ NewFrexp->copyIRFlags (FrexpCall);
40724074
40734075 Value *NewEV = Builder.CreateExtractValue (NewFrexp, 0 , " mantissa" );
40744076
4075- APFloat ConstVal = ConstOp->getValueAPF ();
4076- int Exp = 0 ;
4077- APFloat Mantissa = ConstVal;
4077+ int Exp;
4078+ APFloat Mantissa = frexp (*ConstVal, Exp, APFloat::rmNearestTiesToEven);
40784079
4079- if (ConstVal.isFiniteNonZero ()) {
4080- Mantissa = frexp (ConstVal, Exp, APFloat::rmNearestTiesToEven);
4080+ Constant *ConstantMantissa;
4081+ if (auto *VecTy = dyn_cast<VectorType>(TrueVal->getType ())) {
4082+ SmallVector<Constant *, 4 > Elems (
4083+ VecTy->getElementCount ().getFixedValue (),
4084+ ConstantFP::get (VecTy->getElementType (), Mantissa));
4085+ ConstantMantissa = ConstantVector::get (Elems);
4086+ } else {
4087+ ConstantMantissa = ConstantFP::get (TrueVal->getType (), Mantissa);
40814088 }
40824089
4083- Constant *ConstantMantissa = ConstantFP::get (ConstOp->getType (), Mantissa);
4084-
40854090 Value *NewSel = Builder.CreateSelect (
40864091 Cond, ConstIsTrue ? ConstantMantissa : NewEV,
40874092 ConstIsTrue ? NewEV : ConstantMantissa, " select.frexp" );
4093+ if (auto *NewSelInst = dyn_cast<Instruction>(NewSel))
4094+ NewSelInst->copyFastMathFlags (SelectInst);
40884095
40894096 return NewSel;
40904097}
4091-
40924098Instruction *InstCombinerImpl::visitExtractValueInst (ExtractValueInst &EV) {
40934099 Value *Agg = EV.getAggregateOperand ();
40944100
@@ -4099,20 +4105,12 @@ Instruction *InstCombinerImpl::visitExtractValueInst(ExtractValueInst &EV) {
40994105 SQ.getWithInstruction (&EV)))
41004106 return replaceInstUsesWith (EV, V);
41014107 if (EV.getNumIndices () == 1 && EV.getIndices ()[0 ] == 0 ) {
4102- if (auto *FrexpCall = dyn_cast<CallInst>(Agg)) {
4103- if (Function *F = FrexpCall->getCalledFunction ()) {
4104- if (F->getIntrinsicID () == Intrinsic::frexp) {
4105- if (auto *SelInst =
4106- dyn_cast<SelectInst>(FrexpCall->getArgOperand (0 ))) {
4107- if (isa<ConstantFP>(SelInst->getTrueValue ()) ||
4108- isa<ConstantFP>(SelInst->getFalseValue ())) {
4109- Builder.SetInsertPoint (&EV);
4110-
4111- if (Value *Result =
4112- foldFrexpOfSelect (EV, FrexpCall, SelInst, Builder)) {
4113- return replaceInstUsesWith (EV, Result);
4114- }
4115- }
4108+ if (auto *FrexpCall = dyn_cast<IntrinsicInst>(Agg)) {
4109+ if (FrexpCall->getIntrinsicID () == Intrinsic::frexp) {
4110+ if (auto *SelInst = dyn_cast<SelectInst>(FrexpCall->getArgOperand (0 ))) {
4111+ if (Value *Result =
4112+ foldFrexpOfSelect (EV, FrexpCall, SelInst, Builder)) {
4113+ return replaceInstUsesWith (EV, Result);
41164114 }
41174115 }
41184116 }
0 commit comments