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"
@@ -4069,52 +4070,57 @@ InstCombinerImpl::foldExtractOfOverflowIntrinsic(ExtractValueInst &EV) {
40694070 return nullptr ;
40704071}
40714072
4072- static Value *foldFrexpOfSelect (ExtractValueInst &EV, CallInst *FrexpCall,
4073+ static Value *foldFrexpOfSelect (ExtractValueInst &EV, IntrinsicInst *FrexpCall,
40734074 SelectInst *SelectInst,
40744075 InstCombiner::BuilderTy &Builder) {
40754076 // Helper to fold frexp of select to select of frexp.
40764077 Value *Cond = SelectInst->getCondition ();
40774078 Value *TrueVal = SelectInst->getTrueValue ();
40784079 Value *FalseVal = SelectInst->getFalseValue ();
4079- ConstantFP *ConstOp = nullptr ;
4080+
4081+ const APFloat *ConstVal = nullptr ;
40804082 Value *VarOp = nullptr ;
40814083 bool ConstIsTrue = false ;
40824084
4083- if (auto *TrueConst = dyn_cast<ConstantFP>(TrueVal)) {
4084- ConstOp = TrueConst;
4085+ if (match (TrueVal, m_APFloat (ConstVal))) {
40854086 VarOp = FalseVal;
40864087 ConstIsTrue = true ;
4087- } else if (auto *FalseConst = dyn_cast<ConstantFP>(FalseVal)) {
4088- ConstOp = FalseConst;
4088+ } else if (match (FalseVal, m_APFloat (ConstVal))) {
40894089 VarOp = TrueVal;
40904090 ConstIsTrue = false ;
4091+ } else {
4092+ return nullptr ;
40914093 }
40924094
4093- if (!ConstOp || !VarOp)
4094- return nullptr ;
4095+ Builder.SetInsertPoint (&EV);
40954096
40964097 CallInst *NewFrexp =
40974098 Builder.CreateCall (FrexpCall->getCalledFunction (), {VarOp}, " frexp" );
4099+ NewFrexp->copyIRFlags (FrexpCall);
40984100
40994101 Value *NewEV = Builder.CreateExtractValue (NewFrexp, 0 , " mantissa" );
41004102
4101- APFloat ConstVal = ConstOp->getValueAPF ();
4102- int Exp = 0 ;
4103- APFloat Mantissa = ConstVal;
4103+ int Exp;
4104+ APFloat Mantissa = frexp (*ConstVal, Exp, APFloat::rmNearestTiesToEven);
41044105
4105- if (ConstVal.isFiniteNonZero ()) {
4106- Mantissa = frexp (ConstVal, Exp, APFloat::rmNearestTiesToEven);
4106+ Constant *ConstantMantissa;
4107+ if (auto *VecTy = dyn_cast<VectorType>(TrueVal->getType ())) {
4108+ SmallVector<Constant *, 4 > Elems (
4109+ VecTy->getElementCount ().getFixedValue (),
4110+ ConstantFP::get (VecTy->getElementType (), Mantissa));
4111+ ConstantMantissa = ConstantVector::get (Elems);
4112+ } else {
4113+ ConstantMantissa = ConstantFP::get (TrueVal->getType (), Mantissa);
41074114 }
41084115
4109- Constant *ConstantMantissa = ConstantFP::get (ConstOp->getType (), Mantissa);
4110-
41114116 Value *NewSel = Builder.CreateSelect (
41124117 Cond, ConstIsTrue ? ConstantMantissa : NewEV,
41134118 ConstIsTrue ? NewEV : ConstantMantissa, " select.frexp" );
4119+ if (auto *NewSelInst = dyn_cast<Instruction>(NewSel))
4120+ NewSelInst->copyFastMathFlags (SelectInst);
41144121
41154122 return NewSel;
41164123}
4117-
41184124Instruction *InstCombinerImpl::visitExtractValueInst (ExtractValueInst &EV) {
41194125 Value *Agg = EV.getAggregateOperand ();
41204126
@@ -4125,20 +4131,12 @@ Instruction *InstCombinerImpl::visitExtractValueInst(ExtractValueInst &EV) {
41254131 SQ.getWithInstruction (&EV)))
41264132 return replaceInstUsesWith (EV, V);
41274133 if (EV.getNumIndices () == 1 && EV.getIndices ()[0 ] == 0 ) {
4128- if (auto *FrexpCall = dyn_cast<CallInst>(Agg)) {
4129- if (Function *F = FrexpCall->getCalledFunction ()) {
4130- if (F->getIntrinsicID () == Intrinsic::frexp) {
4131- if (auto *SelInst =
4132- dyn_cast<SelectInst>(FrexpCall->getArgOperand (0 ))) {
4133- if (isa<ConstantFP>(SelInst->getTrueValue ()) ||
4134- isa<ConstantFP>(SelInst->getFalseValue ())) {
4135- Builder.SetInsertPoint (&EV);
4136-
4137- if (Value *Result =
4138- foldFrexpOfSelect (EV, FrexpCall, SelInst, Builder)) {
4139- return replaceInstUsesWith (EV, Result);
4140- }
4141- }
4134+ if (auto *FrexpCall = dyn_cast<IntrinsicInst>(Agg)) {
4135+ if (FrexpCall->getIntrinsicID () == Intrinsic::frexp) {
4136+ if (auto *SelInst = dyn_cast<SelectInst>(FrexpCall->getArgOperand (0 ))) {
4137+ if (Value *Result =
4138+ foldFrexpOfSelect (EV, FrexpCall, SelInst, Builder)) {
4139+ return replaceInstUsesWith (EV, Result);
41424140 }
41434141 }
41444142 }
0 commit comments