@@ -2863,20 +2863,22 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
2863
2863
}
2864
2864
2865
2865
// Canonicalize select with fcmp to fabs(). -0.0 makes this tricky. We need
2866
- // fast-math-flags (nsz) or fsub with +0.0 (not fneg) for this to work.
2866
+ // fast-math-flags (nsz) or fsub with +0.0 (not fneg) for this to work. We
2867
+ // also require nnan because we do not want to unintentionally change the
2868
+ // sign of a NaN value.
2867
2869
// (X <= +/-0.0) ? (0.0 - X) : X --> fabs(X)
2868
2870
Instruction *FSub;
2869
2871
if (match (CondVal, m_FCmp (Pred, m_Specific (FalseVal), m_AnyZeroFP ())) &&
2870
2872
match (TrueVal, m_FSub (m_PosZeroFP (), m_Specific (FalseVal))) &&
2871
- match (TrueVal, m_Instruction (FSub)) &&
2873
+ match (TrueVal, m_Instruction (FSub)) && FSub-> hasNoNaNs () &&
2872
2874
(Pred == FCmpInst::FCMP_OLE || Pred == FCmpInst::FCMP_ULE)) {
2873
2875
Value *Fabs = Builder.CreateUnaryIntrinsic (Intrinsic::fabs, FalseVal, &SI);
2874
2876
return replaceInstUsesWith (SI, Fabs);
2875
2877
}
2876
2878
// (X > +/-0.0) ? X : (0.0 - X) --> fabs(X)
2877
2879
if (match (CondVal, m_FCmp (Pred, m_Specific (TrueVal), m_AnyZeroFP ())) &&
2878
2880
match (FalseVal, m_FSub (m_PosZeroFP (), m_Specific (TrueVal))) &&
2879
- match (FalseVal, m_Instruction (FSub)) &&
2881
+ match (FalseVal, m_Instruction (FSub)) && FSub-> hasNoNaNs () &&
2880
2882
(Pred == FCmpInst::FCMP_OGT || Pred == FCmpInst::FCMP_UGT)) {
2881
2883
Value *Fabs = Builder.CreateUnaryIntrinsic (Intrinsic::fabs, TrueVal, &SI);
2882
2884
return replaceInstUsesWith (SI, Fabs);
@@ -2887,7 +2889,8 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
2887
2889
Instruction *FNeg;
2888
2890
if (match (CondVal, m_FCmp (Pred, m_Specific (FalseVal), m_AnyZeroFP ())) &&
2889
2891
match (TrueVal, m_FNeg (m_Specific (FalseVal))) &&
2890
- match (TrueVal, m_Instruction (FNeg)) && SI.hasNoSignedZeros () &&
2892
+ match (TrueVal, m_Instruction (FNeg)) && FNeg->hasNoNaNs () &&
2893
+ FNeg->hasNoSignedZeros () && SI.hasNoSignedZeros () &&
2891
2894
(Pred == FCmpInst::FCMP_OLT || Pred == FCmpInst::FCMP_OLE ||
2892
2895
Pred == FCmpInst::FCMP_ULT || Pred == FCmpInst::FCMP_ULE)) {
2893
2896
Value *Fabs = Builder.CreateUnaryIntrinsic (Intrinsic::fabs, FalseVal, &SI);
@@ -2898,7 +2901,8 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
2898
2901
// (X >= +/-0.0) ? X : -X --> fabs(X)
2899
2902
if (match (CondVal, m_FCmp (Pred, m_Specific (TrueVal), m_AnyZeroFP ())) &&
2900
2903
match (FalseVal, m_FNeg (m_Specific (TrueVal))) &&
2901
- match (FalseVal, m_Instruction (FNeg)) && SI.hasNoSignedZeros () &&
2904
+ match (FalseVal, m_Instruction (FNeg)) && FNeg->hasNoNaNs () &&
2905
+ FNeg->hasNoSignedZeros () && SI.hasNoSignedZeros () &&
2902
2906
(Pred == FCmpInst::FCMP_OGT || Pred == FCmpInst::FCMP_OGE ||
2903
2907
Pred == FCmpInst::FCMP_UGT || Pred == FCmpInst::FCMP_UGE)) {
2904
2908
Value *Fabs = Builder.CreateUnaryIntrinsic (Intrinsic::fabs, TrueVal, &SI);
0 commit comments