-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[GISel][CombinerHelper] Push freeze through non-poison-producing operands #90618
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
8988e58
5fb40cf
7114b96
519bd0f
1f99a07
40a9d0f
c829e42
b619129
929c0f2
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 |
---|---|---|
|
@@ -223,6 +223,70 @@ void CombinerHelper::applyCombineCopy(MachineInstr &MI) { | |
replaceRegWith(MRI, DstReg, SrcReg); | ||
} | ||
|
||
bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand( | ||
MachineInstr &MI, BuildFnTy &MatchInfo) { | ||
// Ported from InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating. | ||
Register DstOp = MI.getOperand(0).getReg(); | ||
Register OrigOp = MI.getOperand(1).getReg(); | ||
|
||
if (!MRI.hasOneNonDBGUse(OrigOp)) | ||
return false; | ||
|
||
MachineInstr *OrigDef = MRI.getUniqueVRegDef(OrigOp); | ||
// Even if only a single operand of the PHI is not guaranteed non-poison, | ||
// moving freeze() backwards across a PHI can cause optimization issues for | ||
// other users of that operand. | ||
// | ||
// Moving freeze() from one of the output registers of a G_UNMERGE_VALUES to | ||
// the source register is unprofitable because it makes the freeze() more | ||
// strict than is necessary (it would affect the whole register instead of | ||
// just the subreg being frozen). | ||
if (OrigDef->isPHI() || isa<GUnmerge>(OrigDef)) | ||
return false; | ||
|
||
if (canCreateUndefOrPoison(OrigOp, MRI, | ||
/*ConsiderFlagsAndMetadata=*/false)) | ||
return false; | ||
|
||
std::optional<MachineOperand> MaybePoisonOperand; | ||
for (MachineOperand &Operand : OrigDef->uses()) { | ||
if (!Operand.isReg()) | ||
return false; | ||
|
||
if (isGuaranteedNotToBeUndefOrPoison(Operand.getReg(), MRI)) | ||
continue; | ||
|
||
if (!MaybePoisonOperand) | ||
MaybePoisonOperand = Operand; | ||
else { | ||
// We have more than one maybe-poison operand. Moving the freeze is | ||
// unsafe. | ||
return false; | ||
} | ||
} | ||
|
||
cast<GenericMachineInstr>(OrigDef)->dropPoisonGeneratingFlags(); | ||
|
||
// Eliminate freeze if all operands are guaranteed non-poison. | ||
if (!MaybePoisonOperand) { | ||
MatchInfo = [=](MachineIRBuilder &B) { MRI.replaceRegWith(DstOp, OrigOp); }; | ||
return true; | ||
} | ||
|
||
Register MaybePoisonOperandReg = MaybePoisonOperand->getReg(); | ||
LLT MaybePoisonOperandRegTy = MRI.getType(MaybePoisonOperandReg); | ||
|
||
MatchInfo = [=](MachineIRBuilder &B) mutable { | ||
B.setInsertPt(*OrigDef->getParent(), OrigDef->getIterator()); | ||
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. This shouldn't be necessary anymore 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. The new freeze has to be inserted before the use which will come before the old freeze that is being removed, so the insert point has to be moved back. 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. The OrigDef is the root freeze instruction. The insert point for the apply is supposed to be set to before the root instruction, so this is just setting it to what it already should be 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. No, Removing the
Where the first test has
and the second test fails in the machine verifier:
|
||
auto Freeze = B.buildFreeze(MaybePoisonOperandRegTy, MaybePoisonOperandReg); | ||
replaceRegOpWith( | ||
MRI, *OrigDef->findRegisterUseOperand(MaybePoisonOperandReg, TRI), | ||
Freeze.getReg(0)); | ||
replaceRegWith(MRI, DstOp, OrigOp); | ||
}; | ||
return true; | ||
} | ||
|
||
bool CombinerHelper::matchCombineConcatVectors(MachineInstr &MI, | ||
SmallVector<Register> &Ops) { | ||
assert(MI.getOpcode() == TargetOpcode::G_CONCAT_VECTORS && | ||
|
Uh oh!
There was an error while loading. Please reload this page.