-
Notifications
You must be signed in to change notification settings - Fork 13.7k
[InstCombine] Fix for folding select
into floating point binary operators.
#83200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -536,19 +536,29 @@ Instruction *InstCombinerImpl::foldSelectIntoOp(SelectInst &SI, Value *TrueVal, | |
// between 0, 1 and -1. | ||
const APInt *OOpC; | ||
bool OOpIsAPInt = match(OOp, m_APInt(OOpC)); | ||
if (!isa<Constant>(OOp) || | ||
(OOpIsAPInt && isSelect01(C->getUniqueInteger(), *OOpC))) { | ||
Value *NewSel = Builder.CreateSelect(SI.getCondition(), Swapped ? C : OOp, | ||
Swapped ? OOp : C, "", &SI); | ||
if (isa<FPMathOperator>(&SI)) | ||
cast<Instruction>(NewSel)->setFastMathFlags(FMF); | ||
NewSel->takeName(TVI); | ||
BinaryOperator *BO = | ||
BinaryOperator::Create(TVI->getOpcode(), FalseVal, NewSel); | ||
BO->copyIRFlags(TVI); | ||
return BO; | ||
} | ||
return nullptr; | ||
if (isa<Constant>(OOp) && | ||
(!OOpIsAPInt || !isSelect01(C->getUniqueInteger(), *OOpC))) | ||
return nullptr; | ||
|
||
// If the false value is a NaN then we have that the floating point math | ||
// operation in the transformed code may not preserve the exact NaN | ||
// bit-pattern -- e.g. `fadd sNaN, 0.0 -> qNaN`. | ||
// This makes the transformation incorrect since the original program would | ||
// have preserved the exact NaN bit-pattern. | ||
// Avoid the folding if the false value might be a NaN. | ||
if (isa<FPMathOperator>(&SI) && | ||
!computeKnownFPClass(FalseVal, FMF, fcNan, &SI).isKnownNeverNaN()) | ||
return nullptr; | ||
|
||
Value *NewSel = Builder.CreateSelect(SI.getCondition(), Swapped ? C : OOp, | ||
Swapped ? OOp : C, "", &SI); | ||
if (isa<FPMathOperator>(&SI)) | ||
cast<Instruction>(NewSel)->setFastMathFlags(FMF); | ||
NewSel->takeName(TVI); | ||
BinaryOperator *BO = | ||
BinaryOperator::Create(TVI->getOpcode(), FalseVal, NewSel); | ||
BO->copyIRFlags(TVI); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this can or in the value flags from the select There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. alive2 is really slow here without known-no-infs on the inputs though, so I'm not sure the exact flag rewrite rules yet There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe (nnan_bo | nnan_select) | (others_flags_bo & other_flags_select) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't even know what does it mean :( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Ok, I guess I've deciphered it. I guess what you propose is to 'or' the flags copied from TVI with value flags from the select. Trouble is, SI don't have any FMF flags, they were not generated by simplifyCFG pass since they were lost in SROA pass. |
||
return BO; | ||
}; | ||
|
||
if (Instruction *R = TryFoldSelectIntoOp(SI, TrueVal, FalseVal, false)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ought to try to make use of the nnan flag on the select before trying the computeKnownFPClass query. There's a wrapper around computeKnownFPClass which takes an additional FastMathFlags
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sorry, I'm sometimes lost here.
There's a wrapper around computeKnownFPClass which takes an additional FastMathFlags
Did you mean
The wrapper around computeKnownFPClass called here takes an additional FastMathFlags
? That's how I see here, InstCombineSelect.cpp defines two wrappers aroundcomputeKnownFPClass
:and
The one called here is the one which takes
FastMathFlags FMF
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you say what use would that be?