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"
@@ -4069,52 +4070,57 @@ InstCombinerImpl::foldExtractOfOverflowIntrinsic(ExtractValueInst &EV) {
4069
4070
return nullptr ;
4070
4071
}
4071
4072
4072
- static Value *foldFrexpOfSelect (ExtractValueInst &EV, CallInst *FrexpCall,
4073
+ static Value *foldFrexpOfSelect (ExtractValueInst &EV, IntrinsicInst *FrexpCall,
4073
4074
SelectInst *SelectInst,
4074
4075
InstCombiner::BuilderTy &Builder) {
4075
4076
// Helper to fold frexp of select to select of frexp.
4076
4077
Value *Cond = SelectInst->getCondition ();
4077
4078
Value *TrueVal = SelectInst->getTrueValue ();
4078
4079
Value *FalseVal = SelectInst->getFalseValue ();
4079
- ConstantFP *ConstOp = nullptr ;
4080
+
4081
+ const APFloat *ConstVal = nullptr ;
4080
4082
Value *VarOp = nullptr ;
4081
4083
bool ConstIsTrue = false ;
4082
4084
4083
- if (auto *TrueConst = dyn_cast<ConstantFP>(TrueVal)) {
4084
- ConstOp = TrueConst;
4085
+ if (match (TrueVal, m_APFloat (ConstVal))) {
4085
4086
VarOp = FalseVal;
4086
4087
ConstIsTrue = true ;
4087
- } else if (auto *FalseConst = dyn_cast<ConstantFP>(FalseVal)) {
4088
- ConstOp = FalseConst;
4088
+ } else if (match (FalseVal, m_APFloat (ConstVal))) {
4089
4089
VarOp = TrueVal;
4090
4090
ConstIsTrue = false ;
4091
+ } else {
4092
+ return nullptr ;
4091
4093
}
4092
4094
4093
- if (!ConstOp || !VarOp)
4094
- return nullptr ;
4095
+ Builder.SetInsertPoint (&EV);
4095
4096
4096
4097
CallInst *NewFrexp =
4097
4098
Builder.CreateCall (FrexpCall->getCalledFunction (), {VarOp}, " frexp" );
4099
+ NewFrexp->copyIRFlags (FrexpCall);
4098
4100
4099
4101
Value *NewEV = Builder.CreateExtractValue (NewFrexp, 0 , " mantissa" );
4100
4102
4101
- APFloat ConstVal = ConstOp->getValueAPF ();
4102
- int Exp = 0 ;
4103
- APFloat Mantissa = ConstVal;
4103
+ int Exp;
4104
+ APFloat Mantissa = frexp (*ConstVal, Exp, APFloat::rmNearestTiesToEven);
4104
4105
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);
4107
4114
}
4108
4115
4109
- Constant *ConstantMantissa = ConstantFP::get (ConstOp->getType (), Mantissa);
4110
-
4111
4116
Value *NewSel = Builder.CreateSelect (
4112
4117
Cond, ConstIsTrue ? ConstantMantissa : NewEV,
4113
4118
ConstIsTrue ? NewEV : ConstantMantissa, " select.frexp" );
4119
+ if (auto *NewSelInst = dyn_cast<Instruction>(NewSel))
4120
+ NewSelInst->copyFastMathFlags (SelectInst);
4114
4121
4115
4122
return NewSel;
4116
4123
}
4117
-
4118
4124
Instruction *InstCombinerImpl::visitExtractValueInst (ExtractValueInst &EV) {
4119
4125
Value *Agg = EV.getAggregateOperand ();
4120
4126
@@ -4125,20 +4131,12 @@ Instruction *InstCombinerImpl::visitExtractValueInst(ExtractValueInst &EV) {
4125
4131
SQ.getWithInstruction (&EV)))
4126
4132
return replaceInstUsesWith (EV, V);
4127
4133
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);
4142
4140
}
4143
4141
}
4144
4142
}
0 commit comments