33
33
// ===----------------------------------------------------------------------===//
34
34
35
35
#include " InstCombineInternal.h"
36
+ #include " llvm/ADT/APFloat.h"
36
37
#include " llvm/ADT/APInt.h"
37
38
#include " llvm/ADT/ArrayRef.h"
38
39
#include " llvm/ADT/DenseMap.h"
@@ -4043,52 +4044,57 @@ InstCombinerImpl::foldExtractOfOverflowIntrinsic(ExtractValueInst &EV) {
4043
4044
return nullptr ;
4044
4045
}
4045
4046
4046
- static Value *foldFrexpOfSelect (ExtractValueInst &EV, CallInst *FrexpCall,
4047
+ static Value *foldFrexpOfSelect (ExtractValueInst &EV, IntrinsicInst *FrexpCall,
4047
4048
SelectInst *SelectInst,
4048
4049
InstCombiner::BuilderTy &Builder) {
4049
4050
// Helper to fold frexp of select to select of frexp.
4050
4051
Value *Cond = SelectInst->getCondition ();
4051
4052
Value *TrueVal = SelectInst->getTrueValue ();
4052
4053
Value *FalseVal = SelectInst->getFalseValue ();
4053
- ConstantFP *ConstOp = nullptr ;
4054
+
4055
+ const APFloat *ConstVal = nullptr ;
4054
4056
Value *VarOp = nullptr ;
4055
4057
bool ConstIsTrue = false ;
4056
4058
4057
- if (auto *TrueConst = dyn_cast<ConstantFP>(TrueVal)) {
4058
- ConstOp = TrueConst;
4059
+ if (match (TrueVal, m_APFloat (ConstVal))) {
4059
4060
VarOp = FalseVal;
4060
4061
ConstIsTrue = true ;
4061
- } else if (auto *FalseConst = dyn_cast<ConstantFP>(FalseVal)) {
4062
- ConstOp = FalseConst;
4062
+ } else if (match (FalseVal, m_APFloat (ConstVal))) {
4063
4063
VarOp = TrueVal;
4064
4064
ConstIsTrue = false ;
4065
+ } else {
4066
+ return nullptr ;
4065
4067
}
4066
4068
4067
- if (!ConstOp || !VarOp)
4068
- return nullptr ;
4069
+ Builder.SetInsertPoint (&EV);
4069
4070
4070
4071
CallInst *NewFrexp =
4071
4072
Builder.CreateCall (FrexpCall->getCalledFunction (), {VarOp}, " frexp" );
4073
+ NewFrexp->copyIRFlags (FrexpCall);
4072
4074
4073
4075
Value *NewEV = Builder.CreateExtractValue (NewFrexp, 0 , " mantissa" );
4074
4076
4075
- APFloat ConstVal = ConstOp->getValueAPF ();
4076
- int Exp = 0 ;
4077
- APFloat Mantissa = ConstVal;
4077
+ int Exp;
4078
+ APFloat Mantissa = frexp (*ConstVal, Exp, APFloat::rmNearestTiesToEven);
4078
4079
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);
4081
4088
}
4082
4089
4083
- Constant *ConstantMantissa = ConstantFP::get (ConstOp->getType (), Mantissa);
4084
-
4085
4090
Value *NewSel = Builder.CreateSelect (
4086
4091
Cond, ConstIsTrue ? ConstantMantissa : NewEV,
4087
4092
ConstIsTrue ? NewEV : ConstantMantissa, " select.frexp" );
4093
+ if (auto *NewSelInst = dyn_cast<Instruction>(NewSel))
4094
+ NewSelInst->copyFastMathFlags (SelectInst);
4088
4095
4089
4096
return NewSel;
4090
4097
}
4091
-
4092
4098
Instruction *InstCombinerImpl::visitExtractValueInst (ExtractValueInst &EV) {
4093
4099
Value *Agg = EV.getAggregateOperand ();
4094
4100
@@ -4099,20 +4105,12 @@ Instruction *InstCombinerImpl::visitExtractValueInst(ExtractValueInst &EV) {
4099
4105
SQ.getWithInstruction (&EV)))
4100
4106
return replaceInstUsesWith (EV, V);
4101
4107
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);
4116
4114
}
4117
4115
}
4118
4116
}
0 commit comments