-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[GlobalISel] Introduce G_POISON
#127825
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
base: main
Are you sure you want to change the base?
[GlobalISel] Introduce G_POISON
#127825
Changes from 6 commits
0d07595
a8569f2
59a800d
a8cc507
c6b0e4e
b62284a
2af2004
386e424
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 |
---|---|---|
|
@@ -330,6 +330,7 @@ bool CombinerHelper::matchCombineConcatVectors( | |
for (const MachineOperand &BuildVecMO : Def->uses()) | ||
Ops.push_back(BuildVecMO.getReg()); | ||
break; | ||
case TargetOpcode::G_POISON: | ||
case TargetOpcode::G_IMPLICIT_DEF: { | ||
LLT OpType = MRI.getType(Reg); | ||
// Keep one undef value for all the undef operands. | ||
|
@@ -2736,13 +2737,26 @@ bool CombinerHelper::matchAnyExplicitUseIsUndef(MachineInstr &MI) const { | |
}); | ||
} | ||
|
||
bool CombinerHelper::matchAnyExplicitUseIsPoison(MachineInstr &MI) const { | ||
return any_of(MI.explicit_uses(), [this](const MachineOperand &MO) { | ||
return MO.isReg() && getOpcodeDef(TargetOpcode::G_POISON, MO.getReg(), MRI); | ||
}); | ||
} | ||
|
||
bool CombinerHelper::matchAllExplicitUsesAreUndef(MachineInstr &MI) const { | ||
return all_of(MI.explicit_uses(), [this](const MachineOperand &MO) { | ||
return !MO.isReg() || | ||
getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, MO.getReg(), MRI); | ||
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 should also catch the poison case (separate patch though, getOpcodeDef is a bad interface) 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. Done! |
||
}); | ||
} | ||
|
||
bool CombinerHelper::matchAllExplicitUsesArePoison(MachineInstr &MI) const { | ||
return all_of(MI.explicit_uses(), [this](const MachineOperand &MO) { | ||
return !MO.isReg() || | ||
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 need to check if the operand is a register, but this is consistent with the other cases |
||
getOpcodeDef(TargetOpcode::G_POISON, MO.getReg(), MRI); | ||
}); | ||
} | ||
|
||
bool CombinerHelper::matchUndefShuffleVectorMask(MachineInstr &MI) const { | ||
assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR); | ||
ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask(); | ||
|
@@ -2755,6 +2769,11 @@ bool CombinerHelper::matchUndefStore(MachineInstr &MI) const { | |
MRI); | ||
} | ||
|
||
bool CombinerHelper::matchPoisonStore(MachineInstr &MI) const { | ||
assert(MI.getOpcode() == TargetOpcode::G_STORE); | ||
return getOpcodeDef(TargetOpcode::G_POISON, MI.getOperand(0).getReg(), MRI); | ||
} | ||
|
||
bool CombinerHelper::matchUndefSelectCmp(MachineInstr &MI) const { | ||
assert(MI.getOpcode() == TargetOpcode::G_SELECT); | ||
return getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, MI.getOperand(1).getReg(), | ||
|
@@ -2994,6 +3013,12 @@ bool CombinerHelper::matchOperandIsUndef(MachineInstr &MI, | |
getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, MO.getReg(), MRI); | ||
} | ||
|
||
bool CombinerHelper::matchOperandIsPoison(MachineInstr &MI, | ||
unsigned OpIdx) const { | ||
MachineOperand &MO = MI.getOperand(OpIdx); | ||
return MO.isReg() && getOpcodeDef(TargetOpcode::G_POISON, MO.getReg(), MRI); | ||
} | ||
|
||
bool CombinerHelper::matchOperandIsKnownToBeAPowerOfTwo(MachineInstr &MI, | ||
unsigned OpIdx) const { | ||
MachineOperand &MO = MI.getOperand(OpIdx); | ||
|
@@ -3033,6 +3058,12 @@ void CombinerHelper::replaceInstWithUndef(MachineInstr &MI) const { | |
MI.eraseFromParent(); | ||
} | ||
|
||
void CombinerHelper::replaceInstWithPoison(MachineInstr &MI) const { | ||
assert(MI.getNumDefs() == 1 && "Expected only one def?"); | ||
Builder.buildPoison(MI.getOperand(0)); | ||
MI.eraseFromParent(); | ||
} | ||
|
||
bool CombinerHelper::matchSimplifyAddToSub( | ||
MachineInstr &MI, std::tuple<Register, Register> &MatchInfo) const { | ||
Register LHS = MI.getOperand(1).getReg(); | ||
|
@@ -3097,6 +3128,7 @@ bool CombinerHelper::matchCombineInsertVecElts( | |
// If we didn't end in a G_IMPLICIT_DEF and the source is not fully | ||
// overwritten, bail out. | ||
return TmpInst->getOpcode() == TargetOpcode::G_IMPLICIT_DEF || | ||
TmpInst->getOpcode() == TargetOpcode::G_POISON || | ||
all_of(MatchInfo, [](Register Reg) { return !!Reg; }); | ||
} | ||
|
||
|
@@ -3467,12 +3499,13 @@ bool CombinerHelper::matchUseVectorTruncate(MachineInstr &MI, | |
if (I < 2) | ||
return false; | ||
|
||
// Check the remaining source elements are only G_IMPLICIT_DEF | ||
// Check the remaining source elements are only G_IMPLICIT_DEF or G_POISON | ||
for (; I < NumOperands; ++I) { | ||
auto SrcMI = MRI.getVRegDef(BuildMI->getSourceReg(I)); | ||
auto SrcMIOpc = SrcMI->getOpcode(); | ||
|
||
if (SrcMIOpc != TargetOpcode::G_IMPLICIT_DEF) | ||
if (SrcMIOpc != TargetOpcode::G_IMPLICIT_DEF && | ||
SrcMIOpc != TargetOpcode::G_POISON) | ||
return false; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1425,6 +1425,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI, | |
switch (MI.getOpcode()) { | ||
default: | ||
return UnableToLegalize; | ||
case TargetOpcode::G_POISON: | ||
case TargetOpcode::G_IMPLICIT_DEF: { | ||
Register DstReg = MI.getOperand(0).getReg(); | ||
LLT DstTy = MRI.getType(DstReg); | ||
|
@@ -3082,6 +3083,7 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) { | |
MI.eraseFromParent(); | ||
return Legalized; | ||
} | ||
case TargetOpcode::G_POISON: | ||
case TargetOpcode::G_IMPLICIT_DEF: { | ||
Observer.changingInstr(MI); | ||
widenScalarDst(MI, WideTy); | ||
|
@@ -5307,6 +5309,7 @@ LegalizerHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx, | |
|
||
switch (MI.getOpcode()) { | ||
case G_IMPLICIT_DEF: | ||
case G_POISON: | ||
case G_TRUNC: | ||
case G_AND: | ||
case G_OR: | ||
|
@@ -6047,6 +6050,7 @@ LegalizerHelper::moreElementsVector(MachineInstr &MI, unsigned TypeIdx, | |
LLT MoreTy) { | ||
unsigned Opc = MI.getOpcode(); | ||
switch (Opc) { | ||
case TargetOpcode::G_POISON: | ||
case TargetOpcode::G_IMPLICIT_DEF: | ||
case TargetOpcode::G_LOAD: { | ||
if (TypeIdx != 0) | ||
|
@@ -8451,7 +8455,8 @@ LegalizerHelper::lowerVECTOR_COMPRESS(llvm::MachineInstr &MI) { | |
auto OutPos = MIRBuilder.buildConstant(IdxTy, 0); | ||
|
||
bool HasPassthru = | ||
MRI.getVRegDef(Passthru)->getOpcode() != TargetOpcode::G_IMPLICIT_DEF; | ||
MRI.getVRegDef(Passthru)->getOpcode() != TargetOpcode::G_IMPLICIT_DEF && | ||
MRI.getVRegDef(Passthru)->getOpcode() != TargetOpcode::G_POISON; | ||
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. Avoid 2 x getVRegDef 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. Done! |
||
|
||
if (HasPassthru) | ||
MIRBuilder.buildStore(Passthru, StackPtr, PtrInfo, VecAlign); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1470,6 +1470,7 @@ static bool isConstantScalar(const MachineInstr &MI, | |
switch (MI.getOpcode()) { | ||
case TargetOpcode::G_CONSTANT: | ||
case TargetOpcode::G_IMPLICIT_DEF: | ||
case TargetOpcode::G_POISON: | ||
return true; | ||
case TargetOpcode::G_FCONSTANT: | ||
return AllowFP; | ||
|
@@ -1547,6 +1548,7 @@ llvm::isConstantOrConstantSplatVectorFP(MachineInstr &MI, | |
bool llvm::isNullOrNullSplat(const MachineInstr &MI, | ||
const MachineRegisterInfo &MRI, bool AllowUndefs) { | ||
switch (MI.getOpcode()) { | ||
case TargetOpcode::G_POISON: | ||
case TargetOpcode::G_IMPLICIT_DEF: | ||
return AllowUndefs; | ||
case TargetOpcode::G_CONSTANT: | ||
|
@@ -1566,6 +1568,7 @@ bool llvm::isAllOnesOrAllOnesSplat(const MachineInstr &MI, | |
const MachineRegisterInfo &MRI, | ||
bool AllowUndefs) { | ||
switch (MI.getOpcode()) { | ||
case TargetOpcode::G_POISON: | ||
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 will need revisiting, poison could be more aggressive here |
||
case TargetOpcode::G_IMPLICIT_DEF: | ||
return AllowUndefs; | ||
case TargetOpcode::G_CONSTANT: | ||
|
@@ -1582,7 +1585,8 @@ bool llvm::matchUnaryPredicate( | |
std::function<bool(const Constant *ConstVal)> Match, bool AllowUndefs) { | ||
|
||
const MachineInstr *Def = getDefIgnoringCopies(Reg, MRI); | ||
if (AllowUndefs && Def->getOpcode() == TargetOpcode::G_IMPLICIT_DEF) | ||
if (AllowUndefs && (Def->getOpcode() == TargetOpcode::G_IMPLICIT_DEF || | ||
Def->getOpcode() == TargetOpcode::G_POISON)) | ||
return Match(nullptr); | ||
|
||
// TODO: Also handle fconstant | ||
|
@@ -1595,7 +1599,8 @@ bool llvm::matchUnaryPredicate( | |
for (unsigned I = 1, E = Def->getNumOperands(); I != E; ++I) { | ||
Register SrcElt = Def->getOperand(I).getReg(); | ||
const MachineInstr *SrcDef = getDefIgnoringCopies(SrcElt, MRI); | ||
if (AllowUndefs && SrcDef->getOpcode() == TargetOpcode::G_IMPLICIT_DEF) { | ||
if (AllowUndefs && (Def->getOpcode() == TargetOpcode::G_IMPLICIT_DEF || | ||
Def->getOpcode() == TargetOpcode::G_POISON)) { | ||
if (!Match(nullptr)) | ||
return false; | ||
continue; | ||
|
@@ -1914,6 +1919,7 @@ static bool isGuaranteedNotToBeUndefOrPoison(Register Reg, | |
switch (RegDef->getOpcode()) { | ||
case TargetOpcode::G_FREEZE: | ||
return true; | ||
case TargetOpcode::G_POISON: | ||
case TargetOpcode::G_IMPLICIT_DEF: | ||
return !includesUndef(Kind); | ||
case TargetOpcode::G_CONSTANT: | ||
|
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.
Beyond the scope of this patch, but we probably should stop CSEing G_IMPLICIT_DEF, and only do it for G_POISON