@@ -7906,6 +7906,51 @@ static Instruction *foldFCmpFNegCommonOp(FCmpInst &I) {
7906
7906
return new FCmpInst (Pred, Op0, Zero, " " , &I);
7907
7907
}
7908
7908
7909
+ static Instruction *foldFCmpFSubIntoFCmp (FCmpInst &I, Instruction *LHSI,
7910
+ Constant *RHSC, InstCombinerImpl &CI) {
7911
+ const CmpInst::Predicate Pred = I.getPredicate ();
7912
+ Value *X, *Y;
7913
+ switch (Pred) {
7914
+ default :
7915
+ break ;
7916
+ case FCmpInst::FCMP_UGT:
7917
+ case FCmpInst::FCMP_ULT:
7918
+ case FCmpInst::FCMP_UNE:
7919
+ case FCmpInst::FCMP_OEQ:
7920
+ case FCmpInst::FCMP_OGE:
7921
+ case FCmpInst::FCMP_OLE:
7922
+ // Skip optimization: fsub x, y unless guaranteed !isinf(x) ||
7923
+ // !isinf(y).
7924
+ if (!LHSI->hasNoNaNs () && !LHSI->hasNoInfs () &&
7925
+ !isKnownNeverInfinity (LHSI->getOperand (1 ), /* Depth=*/ 0 ,
7926
+ CI.getSimplifyQuery ().getWithInstruction (&I)) &&
7927
+ !isKnownNeverInfinity (LHSI->getOperand (0 ), /* Depth=*/ 0 ,
7928
+ CI.getSimplifyQuery ().getWithInstruction (&I)))
7929
+ break ;
7930
+
7931
+ [[fallthrough]];
7932
+ case FCmpInst::FCMP_OGT:
7933
+ case FCmpInst::FCMP_OLT:
7934
+ case FCmpInst::FCMP_ONE:
7935
+ case FCmpInst::FCMP_UEQ:
7936
+ case FCmpInst::FCMP_UGE:
7937
+ case FCmpInst::FCMP_ULE:
7938
+ // fcmp pred (x - y), 0 --> fcmp pred x, y
7939
+ if (match (RHSC, m_AnyZeroFP ()) &&
7940
+ match (LHSI, m_FSub (m_Value (X), m_Value (Y))) &&
7941
+ I.getFunction ()->getDenormalMode (
7942
+ LHSI->getType ()->getScalarType ()->getFltSemantics ()) ==
7943
+ DenormalMode::getIEEE ()) {
7944
+ CI.replaceOperand (I, 0 , X);
7945
+ CI.replaceOperand (I, 1 , Y);
7946
+ return &I;
7947
+ }
7948
+ break ;
7949
+ }
7950
+
7951
+ return nullptr ;
7952
+ }
7953
+
7909
7954
Instruction *InstCombinerImpl::visitFCmpInst (FCmpInst &I) {
7910
7955
bool Changed = false ;
7911
7956
@@ -8077,44 +8122,9 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
8077
8122
return NV;
8078
8123
break ;
8079
8124
case Instruction::FSub:
8080
- switch (Pred) {
8081
- default :
8082
- break ;
8083
- case FCmpInst::FCMP_UGT:
8084
- case FCmpInst::FCMP_ULT:
8085
- case FCmpInst::FCMP_UNE:
8086
- case FCmpInst::FCMP_OEQ:
8087
- case FCmpInst::FCMP_OGE:
8088
- case FCmpInst::FCMP_OLE:
8089
- // Skip optimization: fsub x, y unless guaranteed !isinf(x) ||
8090
- // !isinf(y).
8091
- if (!LHSI->hasOneUse () ||
8092
- (!LHSI->hasNoNaNs () && !LHSI->hasNoInfs () &&
8093
- !isKnownNeverInfinity (LHSI->getOperand (1 ), /* Depth=*/ 0 ,
8094
- getSimplifyQuery ().getWithInstruction (&I)) &&
8095
- !isKnownNeverInfinity (LHSI->getOperand (0 ), /* Depth=*/ 0 ,
8096
- getSimplifyQuery ().getWithInstruction (&I))))
8097
- break ;
8098
-
8099
- [[fallthrough]];
8100
- case FCmpInst::FCMP_OGT:
8101
- case FCmpInst::FCMP_OLT:
8102
- case FCmpInst::FCMP_ONE:
8103
- case FCmpInst::FCMP_UEQ:
8104
- case FCmpInst::FCMP_UGE:
8105
- case FCmpInst::FCMP_ULE:
8106
- // fcmp pred (x - y), 0 --> fcmp pred x, y
8107
- if (match (RHSC, m_AnyZeroFP ()) &&
8108
- match (LHSI, m_OneUse (m_FSub (m_Value (X), m_Value (Y)))) &&
8109
- I.getFunction ()->getDenormalMode (
8110
- LHSI->getType ()->getScalarType ()->getFltSemantics ()) ==
8111
- DenormalMode::getIEEE ()) {
8112
- replaceOperand (I, 0 , X);
8113
- replaceOperand (I, 1 , Y);
8114
- return &I;
8115
- }
8116
- break ;
8117
- }
8125
+ if (LHSI->hasOneUse ())
8126
+ if (Instruction *NV = foldFCmpFSubIntoFCmp (I, LHSI, RHSC, *this ))
8127
+ return NV;
8118
8128
break ;
8119
8129
case Instruction::PHI:
8120
8130
if (Instruction *NV = foldOpIntoPhi (I, cast<PHINode>(LHSI)))
0 commit comments