[llvm] [GlobalISel] Introduce `G_POISON` (PR #127825)
Mateusz Sokół via llvm-commits
llvm-commits at lists.llvm.org
Sun Apr 20 10:43:50 PDT 2025
https://github.com/mtsokol updated https://github.com/llvm/llvm-project/pull/127825
>From 0d075956f954ff1349d9309eb5c7f39e57fc7ada Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mateusz=20Sok=C3=B3=C5=82?= <mat646 at gmail.com>
Date: Wed, 19 Feb 2025 16:02:55 +0000
Subject: [PATCH 1/2] [GlobalISel] Introduce `G_POISON`
---
llvm/docs/GlobalISel/GenericOpcode.rst | 9 ++++
.../llvm/CodeGen/GlobalISel/CombinerHelper.h | 17 +++++++
.../CodeGen/GlobalISel/GenericMachineInstrs.h | 8 +++
.../CodeGen/GlobalISel/MachineIRBuilder.h | 5 +-
llvm/include/llvm/Support/TargetOpcodes.def | 5 +-
llvm/include/llvm/Target/GenericOpcodes.td | 6 +++
.../include/llvm/Target/GlobalISel/Combine.td | 49 ++++++++++++++++++-
llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp | 3 +-
.../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 43 +++++++++++++++-
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 2 +
.../GlobalISel/LegacyLegalizerInfo.cpp | 2 +
.../CodeGen/GlobalISel/LegalizerHelper.cpp | 7 ++-
.../GlobalISel/LostDebugLocObserver.cpp | 1 +
.../CodeGen/GlobalISel/MachineIRBuilder.cpp | 4 ++
llvm/lib/CodeGen/GlobalISel/Utils.cpp | 10 +++-
llvm/lib/CodeGen/MachineSSAContext.cpp | 3 +-
.../X86/GlobalISel/calllowering-nocrashret.ll | 15 +++++-
.../GlobalISelEmitter/GlobalISelEmitter.td | 2 +-
18 files changed, 178 insertions(+), 13 deletions(-)
diff --git a/llvm/docs/GlobalISel/GenericOpcode.rst b/llvm/docs/GlobalISel/GenericOpcode.rst
index 5291b42d80870..3e80f608a82aa 100644
--- a/llvm/docs/GlobalISel/GenericOpcode.rst
+++ b/llvm/docs/GlobalISel/GenericOpcode.rst
@@ -24,6 +24,15 @@ An undefined value.
%0:_(s32) = G_IMPLICIT_DEF
+G_POISON
+^^^^^^^^
+
+A poison value.
+
+.. code-block:: none
+
+ %0:_(s32) = G_POISON
+
G_CONSTANT
^^^^^^^^^^
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index c15263e0b06f8..f40f84aa60ba4 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -432,16 +432,27 @@ class CombinerHelper {
/// G_IMPLICIT_DEF.
bool matchAnyExplicitUseIsUndef(MachineInstr &MI) const;
+ /// Return true if any explicit use operand on \p MI is defined by a
+ /// G_POISON.
+ bool matchAnyExplicitUseIsPoison(MachineInstr &MI) const;
+
/// Return true if all register explicit use operands on \p MI are defined by
/// a G_IMPLICIT_DEF.
bool matchAllExplicitUsesAreUndef(MachineInstr &MI) const;
+ /// Return true if all register explicit use operands on \p MI are defined by
+ /// a G_POISON.
+ bool matchAllExplicitUsesArePoison(MachineInstr &MI) const;
+
/// Return true if a G_SHUFFLE_VECTOR instruction \p MI has an undef mask.
bool matchUndefShuffleVectorMask(MachineInstr &MI) const;
/// Return true if a G_STORE instruction \p MI is storing an undef value.
bool matchUndefStore(MachineInstr &MI) const;
+ /// Return true if a G_STORE instruction \p MI is storing a poison value.
+ bool matchPoisonStore(MachineInstr &MI) const;
+
/// Return true if a G_SELECT instruction \p MI has an undef comparison.
bool matchUndefSelectCmp(MachineInstr &MI) const;
@@ -467,6 +478,9 @@ class CombinerHelper {
/// Replace an instruction with a G_IMPLICIT_DEF.
void replaceInstWithUndef(MachineInstr &MI) const;
+ /// Replace an instruction with a G_POISON.
+ void replaceInstWithPoison(MachineInstr &MI) const;
+
/// Delete \p MI and replace all of its uses with its \p OpIdx-th operand.
void replaceSingleDefInstWithOperand(MachineInstr &MI, unsigned OpIdx) const;
@@ -507,6 +521,9 @@ class CombinerHelper {
/// Check if operand \p OpIdx is undef.
bool matchOperandIsUndef(MachineInstr &MI, unsigned OpIdx) const;
+ /// Check if operand \p OpIdx is poison.
+ bool matchOperandIsPoison(MachineInstr &MI, unsigned OpIdx) const;
+
/// Check if operand \p OpIdx is known to be a power of 2.
bool matchOperandIsKnownToBeAPowerOfTwo(MachineInstr &MI,
unsigned OpIdx) const;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
index 9e5d4d34f24d2..ddcff441cea3b 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
@@ -343,6 +343,14 @@ class GImplicitDef : public GenericMachineInstr {
}
};
+/// Represents a G_POISON.
+class GPoison : public GenericMachineInstr {
+public:
+ static bool classof(const MachineInstr *MI) {
+ return MI->getOpcode() == TargetOpcode::G_POISON;
+ }
+};
+
/// Represents a G_SELECT.
class GSelect : public GenericMachineInstr {
public:
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index f9dcbeb370bef..d3d506a0b9b3d 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -1017,9 +1017,12 @@ class MachineIRBuilder {
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildExtract(const DstOp &Res, const SrcOp &Src, uint64_t Index);
- /// Build and insert \p Res = IMPLICIT_DEF.
+ /// Build and insert \p Res = G_IMPLICIT_DEF.
MachineInstrBuilder buildUndef(const DstOp &Res);
+ /// Build and insert \p Res = G_POISON.
+ MachineInstrBuilder buildPoison(const DstOp &Res);
+
/// Build and insert \p Res = G_MERGE_VALUES \p Op0, ...
///
/// G_MERGE_VALUES combines the input elements contiguously into a larger
diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def
index 5ef3707b81fe9..0170ac327c855 100644
--- a/llvm/include/llvm/Support/TargetOpcodes.def
+++ b/llvm/include/llvm/Support/TargetOpcodes.def
@@ -295,9 +295,12 @@ HANDLE_TARGET_OPCODE(G_ABDS)
/// Generic absolute difference unsigned instruction.
HANDLE_TARGET_OPCODE(G_ABDU)
-
+// Generic implicit definition.
HANDLE_TARGET_OPCODE(G_IMPLICIT_DEF)
+// Generic poison value.
+HANDLE_TARGET_OPCODE(G_POISON)
+
/// Generic PHI instruction with types.
HANDLE_TARGET_OPCODE(G_PHI)
diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td
index e134bab61bf63..5b71641854eac 100644
--- a/llvm/include/llvm/Target/GenericOpcodes.td
+++ b/llvm/include/llvm/Target/GenericOpcodes.td
@@ -92,6 +92,12 @@ def G_IMPLICIT_DEF : GenericInstruction {
let hasSideEffects = false;
}
+def G_POISON : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins);
+ let hasSideEffects = false;
+}
+
def G_PHI : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins variable_ops);
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index e5e19a1d93486..258e846e52e5f 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -430,6 +430,12 @@ def binop_right_undef_to_undef: GICombineRule<
[{ return Helper.matchOperandIsUndef(*${root}, 2); }]),
(apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
+def binop_right_poison_to_poison
+ : GICombineRule<(defs root:$root),
+ (match(wip_match_opcode G_SHL, G_ASHR, G_LSHR):$root,
+ [{ return Helper.matchOperandIsPoison(*${root}, 2); }]),
+ (apply [{ Helper.replaceInstWithPoison(*${root}); }])>;
+
def unary_undef_to_zero: GICombineRule<
(defs root:$root),
(match (wip_match_opcode G_ABS):$root,
@@ -447,6 +453,17 @@ def unary_undef_to_undef : GICombineRule<
(match (unary_undef_to_undef_frags $dst)),
(apply [{ Helper.replaceInstWithUndef(*${dst}.getParent()); }])>;
+def unary_poison_to_poison_frags
+ : GICombinePatFrag<(outs root:$dst), (ins),
+ !foreach(op,
+ [G_TRUNC, G_BITCAST, G_ANYEXT, G_PTRTOINT,
+ G_INTTOPTR, G_FPTOSI, G_FPTOUI],
+ (pattern(op $dst, $x), (G_POISON $x)))>;
+def unary_poison_to_poison
+ : GICombineRule<
+ (defs root:$dst), (match(unary_poison_to_poison_frags $dst)),
+ (apply [{ Helper.replaceInstWithPoison(*${dst}.getParent()); }])>;
+
// Instructions where if any source operand is undef, the instruction can be
// replaced with undef.
def propagate_undef_any_op: GICombineRule<
@@ -455,6 +472,15 @@ def propagate_undef_any_op: GICombineRule<
[{ return Helper.matchAnyExplicitUseIsUndef(*${root}); }]),
(apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
+// Instructions where if any source operand is poison, the instruction can be
+// replaced with poison.
+def propagate_poison_any_op
+ : GICombineRule<
+ (defs root:$root),
+ (match(wip_match_opcode G_ADD, G_SUB, G_XOR):$root,
+ [{ return Helper.matchAnyExplicitUseIsPoison(*${root}); }]),
+ (apply [{ Helper.replaceInstWithPoison(*${root}); }])>;
+
// Instructions where if all source operands are undef, the instruction can be
// replaced with undef.
def propagate_undef_all_ops: GICombineRule<
@@ -463,6 +489,15 @@ def propagate_undef_all_ops: GICombineRule<
[{ return Helper.matchAllExplicitUsesAreUndef(*${root}); }]),
(apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
+// Instructions where if all source operands are poison, the instruction can be
+// replaced with poison.
+def propagate_poison_all_ops
+ : GICombineRule<
+ (defs root:$root),
+ (match(wip_match_opcode G_SHUFFLE_VECTOR, G_BUILD_VECTOR):$root,
+ [{ return Helper.matchAllExplicitUsesArePoison(*${root}); }]),
+ (apply [{ Helper.replaceInstWithPoison(*${root}); }])>;
+
// Replace a G_SHUFFLE_VECTOR with an undef mask with a G_IMPLICIT_DEF.
def propagate_undef_shuffle_mask: GICombineRule<
(defs root:$root),
@@ -654,6 +689,13 @@ def erase_undef_store : GICombineRule<
(apply [{ Helper.eraseInst(*${root}); }])
>;
+// Erase stores of poison values.
+def erase_poison_store
+ : GICombineRule<(defs root:$root),
+ (match(wip_match_opcode G_STORE):$root,
+ [{ return Helper.matchPoisonStore(*${root}); }]),
+ (apply [{ Helper.eraseInst(*${root}); }])>;
+
def simplify_add_to_sub_matchinfo: GIDefMatchData<"std::tuple<Register, Register>">;
def simplify_add_to_sub: GICombineRule <
(defs root:$root, simplify_add_to_sub_matchinfo:$info),
@@ -1981,6 +2023,11 @@ def undef_combines : GICombineGroup<[undef_to_fp_zero, undef_to_int_zero,
erase_undef_store,
insert_extract_vec_elt_out_of_bounds]>;
+def poison_combines
+ : GICombineGroup<[binop_right_poison_to_poison, unary_poison_to_poison,
+ propagate_poison_any_op, propagate_poison_all_ops,
+ erase_poison_store]>;
+
def identity_combines : GICombineGroup<[select_same_val, right_identity_zero,
binop_same_val, binop_left_to_zero,
binop_right_to_zero, p2i_to_i2p,
@@ -2036,7 +2083,7 @@ def all_combines : GICombineGroup<[integer_reassoc_combines, trivial_combines,
vector_ops_combines, freeze_combines, cast_combines,
insert_vec_elt_combines, extract_vec_elt_combines, combines_for_extload,
combine_extracted_vector_load,
- undef_combines, identity_combines, phi_combines,
+ undef_combines, poison_combines, identity_combines, phi_combines,
simplify_add_to_sub, hoist_logic_op_with_same_opcode_hands, shifts_too_big,
reassocs, ptr_add_immed_chain, cmp_combines,
shl_ashr_to_sext_inreg, neg_and_one_to_sext_inreg, sext_inreg_of_load,
diff --git a/llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp b/llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp
index fd89e40a5a1ee..71dd850a7142b 100644
--- a/llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp
@@ -54,6 +54,7 @@ bool CSEConfigFull::shouldCSEOpc(unsigned Opc) {
case TargetOpcode::G_CONSTANT:
case TargetOpcode::G_FCONSTANT:
case TargetOpcode::G_IMPLICIT_DEF:
+ case TargetOpcode::G_POISON:
case TargetOpcode::G_ZEXT:
case TargetOpcode::G_SEXT:
case TargetOpcode::G_ANYEXT:
@@ -82,7 +83,7 @@ bool CSEConfigFull::shouldCSEOpc(unsigned Opc) {
bool CSEConfigConstantOnly::shouldCSEOpc(unsigned Opc) {
return Opc == TargetOpcode::G_CONSTANT || Opc == TargetOpcode::G_FCONSTANT ||
- Opc == TargetOpcode::G_IMPLICIT_DEF;
+ Opc == TargetOpcode::G_IMPLICIT_DEF || Opc == TargetOpcode::G_POISON;
}
std::unique_ptr<CSEConfigBase>
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 333f0c17bacc5..610d3dd5f95c1 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -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,6 +2737,12 @@ 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() ||
@@ -2743,6 +2750,13 @@ bool CombinerHelper::matchAllExplicitUsesAreUndef(MachineInstr &MI) const {
});
}
+bool CombinerHelper::matchAllExplicitUsesArePoison(MachineInstr &MI) const {
+ return all_of(MI.explicit_uses(), [this](const MachineOperand &MO) {
+ return !MO.isReg() ||
+ 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;
}
@@ -7933,6 +7966,12 @@ bool CombinerHelper::matchShuffleDisjointMask(MachineInstr &MI,
if (getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, Shuffle.getSrc2Reg(), MRI))
return false;
+ if (getOpcodeDef(TargetOpcode::G_POISON, Shuffle.getSrc1Reg(), MRI))
+ return false;
+
+ if (getOpcodeDef(TargetOpcode::G_POISON, Shuffle.getSrc2Reg(), MRI))
+ return false;
+
const LLT DstTy = MRI.getType(Shuffle.getReg(0));
const LLT Src1Ty = MRI.getType(Shuffle.getSrc1Reg());
if (!isLegalOrBeforeLegalizer(
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 931e4fe19e69a..7343360c9b808 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -3649,6 +3649,8 @@ bool IRTranslator::translate(const Constant &C, Register Reg) {
EntryBuilder->buildConstant(Reg, *CI);
else if (auto CF = dyn_cast<ConstantFP>(&C))
EntryBuilder->buildFConstant(Reg, *CF);
+ else if (isa<PoisonValue>(C))
+ EntryBuilder->buildPoison(Reg);
else if (isa<UndefValue>(C))
EntryBuilder->buildUndef(Reg);
else if (isa<ConstantPointerNull>(C))
diff --git a/llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp b/llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp
index 05923e5fc97cc..412f2373ac471 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp
@@ -82,6 +82,8 @@ LegacyLegalizerInfo::LegacyLegalizerInfo() {
setLegalizeScalarToDifferentSizeStrategy(
TargetOpcode::G_IMPLICIT_DEF, 0, narrowToSmallerAndUnsupportedIfTooSmall);
+ setLegalizeScalarToDifferentSizeStrategy(
+ TargetOpcode::G_POISON, 0, narrowToSmallerAndUnsupportedIfTooSmall);
setLegalizeScalarToDifferentSizeStrategy(
TargetOpcode::G_ADD, 0, widenToLargerTypesAndNarrowToLargest);
setLegalizeScalarToDifferentSizeStrategy(
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 0aa853389bf1a..58e5769a0a055 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -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;
if (HasPassthru)
MIRBuilder.buildStore(Passthru, StackPtr, PtrInfo, VecAlign);
diff --git a/llvm/lib/CodeGen/GlobalISel/LostDebugLocObserver.cpp b/llvm/lib/CodeGen/GlobalISel/LostDebugLocObserver.cpp
index 6d606e5550f1a..8c19dd39a4aa8 100644
--- a/llvm/lib/CodeGen/GlobalISel/LostDebugLocObserver.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LostDebugLocObserver.cpp
@@ -85,6 +85,7 @@ static bool irTranslatorNeverAddsLocations(unsigned Opcode) {
case TargetOpcode::G_CONSTANT:
case TargetOpcode::G_FCONSTANT:
case TargetOpcode::G_IMPLICIT_DEF:
+ case TargetOpcode::G_POISON:
case TargetOpcode::G_GLOBAL_VALUE:
return true;
}
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 359677027f52f..d1af81a80f998 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -642,6 +642,10 @@ MachineInstrBuilder MachineIRBuilder::buildUndef(const DstOp &Res) {
return buildInstr(TargetOpcode::G_IMPLICIT_DEF, {Res}, {});
}
+MachineInstrBuilder MachineIRBuilder::buildPoison(const DstOp &Res) {
+ return buildInstr(TargetOpcode::G_POISON, {Res}, {});
+}
+
MachineInstrBuilder MachineIRBuilder::buildMergeValues(const DstOp &Res,
ArrayRef<Register> Ops) {
// Unfortunately to convert from ArrayRef<LLT> to ArrayRef<SrcOp>,
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index 223d69c362185..80b3c94c51064 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -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:
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:
diff --git a/llvm/lib/CodeGen/MachineSSAContext.cpp b/llvm/lib/CodeGen/MachineSSAContext.cpp
index bbbfb3ce2788d..a1ab9ffc191ac 100644
--- a/llvm/lib/CodeGen/MachineSSAContext.cpp
+++ b/llvm/lib/CodeGen/MachineSSAContext.cpp
@@ -56,7 +56,8 @@ const MachineBasicBlock *MachineSSAContext::getDefBlock(Register value) const {
static bool isUndef(const MachineInstr &MI) {
return MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
- MI.getOpcode() == TargetOpcode::IMPLICIT_DEF;
+ MI.getOpcode() == TargetOpcode::IMPLICIT_DEF ||
+ MI.getOpcode() == TargetOpcode::G_POISON;
}
/// MachineInstr equivalent of PHINode::hasConstantOrUndefValue() for G_PHI.
diff --git a/llvm/test/CodeGen/X86/GlobalISel/calllowering-nocrashret.ll b/llvm/test/CodeGen/X86/GlobalISel/calllowering-nocrashret.ll
index 5e9311559b400..74363203f8fca 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/calllowering-nocrashret.ll
+++ b/llvm/test/CodeGen/X86/GlobalISel/calllowering-nocrashret.ll
@@ -1,8 +1,8 @@
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
; RUN: llc -mtriple=x86_64-linux-gnu -o - -global-isel %s -stop-after=irtranslator | FileCheck %s
-define <4 x i1> @foo() {
- ; CHECK-LABEL: name: foo
+define <4 x i1> @foo_undef() {
+ ; CHECK-LABEL: name: foo_undef
; CHECK: bb.1.entry:
; CHECK: [[DEF:%[0-9]+]]:_(<4 x s1>) = G_IMPLICIT_DEF
; CHECK: [[ANYEXT:%[0-9]+]]:_(<4 x s32>) = G_ANYEXT [[DEF]](<4 x s1>)
@@ -11,3 +11,14 @@ define <4 x i1> @foo() {
entry:
ret <4 x i1> undef ;
}
+
+define <4 x i1> @foo_poison() {
+ ; CHECK-LABEL: name: foo_poison
+ ; CHECK: bb.1.entry:
+ ; CHECK: [[DEF:%[0-9]+]]:_(<4 x s1>) = G_POISON
+ ; CHECK: [[ANYEXT:%[0-9]+]]:_(<4 x s32>) = G_ANYEXT [[DEF]](<4 x s1>)
+ ; CHECK: $xmm0 = COPY [[ANYEXT]](<4 x s32>)
+ ; CHECK: RET 0, implicit $xmm0
+entry:
+ ret <4 x i1> poison ;
+}
diff --git a/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td b/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td
index b7132bf2bcd8c..d1c0e5d9d3105 100644
--- a/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td
+++ b/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td
@@ -513,7 +513,7 @@ def : Pat<(frag GPR32:$src1, complex:$src2, complex:$src3),
// R00O-NEXT: GIM_Reject,
// R00O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]]
// R00O-NEXT: GIM_Reject,
-// R00O-NEXT: }; // Size: 1840 bytes
+// R00O-NEXT: }; // Size: 1844 bytes
def INSNBOB : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3, GPR32:$src4),
[(set GPR32:$dst,
>From a8569f2498b70e7475b963a145abc4100f9a7788 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mateusz=20Sok=C3=B3=C5=82?= <mat646 at gmail.com>
Date: Sun, 20 Apr 2025 17:14:44 +0000
Subject: [PATCH 2/2] Adjust targets for `G_POISON`
---
.../AArch64/GISel/AArch64InstructionSelector.cpp | 12 +++++++++---
.../Target/AArch64/GISel/AArch64LegalizerInfo.cpp | 2 +-
.../AArch64/GISel/AArch64PostLegalizerLowering.cpp | 5 +++--
llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp | 1 +
llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp | 3 ++-
.../Target/RISCV/GISel/RISCVInstructionSelector.cpp | 4 +++-
llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp | 5 +++--
.../lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp | 3 ++-
llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp | 7 +++++--
llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp | 3 ++-
llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | 3 ++-
llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp | 12 ++++++++----
llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp | 2 +-
llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp | 1 +
14 files changed, 43 insertions(+), 20 deletions(-)
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 2afd24555b28c..2daf3ba392cde 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -3594,7 +3594,8 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
return selectIntrinsic(I, MRI);
case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
return selectIntrinsicWithSideEffects(I, MRI);
- case TargetOpcode::G_IMPLICIT_DEF: {
+ case TargetOpcode::G_IMPLICIT_DEF:
+ case TargetOpcode::G_POISON: {
I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));
const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
const Register DstReg = I.getOperand(0).getReg();
@@ -5860,8 +5861,13 @@ bool AArch64InstructionSelector::tryOptBuildVecToSubregToReg(
const RegisterBank &DstRB = *RBI.getRegBank(Dst, MRI, TRI);
if (EltRB != DstRB)
return false;
- if (any_of(drop_begin(I.operands(), 2), [&MRI](const MachineOperand &Op) {
- return !getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, Op.getReg(), MRI);
+ if (any_of(drop_begin(I.operands(), 2),
+ [&MRI](const MachineOperand &Op) {
+ return !getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, Op.getReg(),
+ MRI);
+ }) &&
+ any_of(drop_begin(I.operands(), 2), [&MRI](const MachineOperand &Op) {
+ return !getOpcodeDef(TargetOpcode::G_POISON, Op.getReg(), MRI);
}))
return false;
unsigned SubReg;
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index c36b20badfc09..5248e535f6f0e 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -92,7 +92,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
const bool HasSVE = ST.hasSVE();
getActionDefinitionsBuilder(
- {G_IMPLICIT_DEF, G_FREEZE, G_CONSTANT_FOLD_BARRIER})
+ {G_IMPLICIT_DEF, G_POISON, G_FREEZE, G_CONSTANT_FOLD_BARRIER})
.legalFor({p0, s8, s16, s32, s64})
.legalFor({v2s8, v4s8, v8s8, v16s8, v2s16, v4s16, v8s16, v2s32, v4s32,
v2s64, v2p0})
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
index 4785c7b68d94d..9b3dd18db8810 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
@@ -266,9 +266,10 @@ bool matchDupFromInsertVectorElt(int Lane, MachineInstr &MI,
MI.getOperand(1).getReg(), MRI);
if (!InsMI)
return false;
- // Match the undef vector operand.
+ // Match the undef/poison vector operand.
if (!getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, InsMI->getOperand(1).getReg(),
- MRI))
+ MRI) &&
+ !getOpcodeDef(TargetOpcode::G_POISON, InsMI->getOperand(1).getReg(), MRI))
return false;
// Match the index constant 0.
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
index 6ef7505ec6f62..14d264fb6caa0 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
@@ -4047,6 +4047,7 @@ bool AMDGPUInstructionSelector::select(MachineInstr &I) {
case TargetOpcode::G_BUILD_VECTOR_TRUNC:
return selectG_BUILD_VECTOR(I);
case TargetOpcode::G_IMPLICIT_DEF:
+ case TargetOpcode::G_POISON:
return selectG_IMPLICIT_DEF(I);
case TargetOpcode::G_INSERT:
return selectG_INSERT(I);
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp
index 1d0e81db5a5db..61d8e845fce10 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp
@@ -477,7 +477,8 @@ AMDGPURegisterBankInfo::getInstrAlternativeMappings(
InstructionMappings AltMappings;
switch (MI.getOpcode()) {
case TargetOpcode::G_CONSTANT:
- case TargetOpcode::G_IMPLICIT_DEF: {
+ case TargetOpcode::G_IMPLICIT_DEF:
+ case TargetOpcode::G_POISON: {
unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
if (Size == 1) {
static const OpRegBankEntry<1> Table[3] = {
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index f83c2b6da8923..e548c63fc28d5 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -812,6 +812,7 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
return true;
}
case TargetOpcode::G_IMPLICIT_DEF:
+ case TargetOpcode::G_POISON:
return selectImplicitDef(MI, MIB);
case TargetOpcode::G_UNMERGE_VALUES:
return selectUnmergeValues(MI, MIB);
@@ -1030,7 +1031,8 @@ bool RISCVInstructionSelector::selectCopy(MachineInstr &MI) const {
bool RISCVInstructionSelector::selectImplicitDef(MachineInstr &MI,
MachineIRBuilder &MIB) const {
- assert(MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF);
+ assert(MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
+ MI.getOpcode() == TargetOpcode::G_POISON);
const Register DstReg = MI.getOperand(0).getReg();
const TargetRegisterClass *DstRC = getRegClassForTypeOnBank(
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index e88f33d6859ec..db017c082fce7 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -255,7 +255,7 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
// TODO: transform illegal vector types into legal vector type
// TODO: Merge with G_FREEZE?
getActionDefinitionsBuilder(
- {G_IMPLICIT_DEF, G_CONSTANT_FOLD_BARRIER})
+ {G_IMPLICIT_DEF, G_POISON, G_CONSTANT_FOLD_BARRIER})
.legalFor({s32, sXLen, p0})
.legalIf(typeIsLegalBoolVec(0, BoolVecTys, ST))
.legalIf(typeIsLegalIntOrFPVec(0, IntOrFPVecTys, ST))
@@ -1172,7 +1172,8 @@ bool RISCVLegalizerInfo::legalizeInsertSubvector(MachineInstr &MI,
LLT LitTy = MRI.getType(LitVec);
if (Idx == 0 ||
- MRI.getVRegDef(BigVec)->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
+ MRI.getVRegDef(BigVec)->getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
+ MRI.getVRegDef(BigVec)->getOpcode() == TargetOpcode::G_POISON)
return true;
// We don't have the ability to slide mask vectors up indexed by their i1
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
index a082b18867666..280ac780da458 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
@@ -288,7 +288,8 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case TargetOpcode::G_ZEXTLOAD:
return getInstructionMapping(DefaultMappingID, /*Cost=*/1, GPRValueMapping,
NumOperands);
- case TargetOpcode::G_IMPLICIT_DEF: {
+ case TargetOpcode::G_IMPLICIT_DEF:
+ case TargetOpcode::G_POISON: {
Register Dst = MI.getOperand(0).getReg();
LLT DstTy = MRI.getType(Dst);
unsigned DstMinSize = DstTy.getSizeInBits().getKnownMinValue();
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 79f6b43f3aded..1dfb2bc6f407e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -548,7 +548,8 @@ bool SPIRVInstructionSelector::select(MachineInstr &I) {
Register ResVReg = HasDefs ? I.getOperand(0).getReg() : Register(0);
SPIRVType *ResType = HasDefs ? GR.getSPIRVTypeForVReg(ResVReg) : nullptr;
assert(!HasDefs || ResType || I.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
- I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF);
+ I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
+ I.getOpcode() == TargetOpcode::G_POISON);
if (spvSelect(ResVReg, ResType, I)) {
if (HasDefs) // Make all vregs 64 bits (for SPIR-V IDs).
for (unsigned i = 0; i < I.getNumDefs(); ++i)
@@ -598,6 +599,7 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg,
case TargetOpcode::G_GLOBAL_VALUE:
return selectGlobalValue(ResVReg, I);
case TargetOpcode::G_IMPLICIT_DEF:
+ case TargetOpcode::G_POISON:
return selectOpUndef(ResVReg, ResType, I);
case TargetOpcode::G_FREEZE:
return selectFreeze(ResVReg, ResType, I);
@@ -2326,7 +2328,8 @@ bool SPIRVInstructionSelector::selectFreeze(Register ResVReg,
case SPIRV::ASSIGN_TYPE:
if (MachineInstr *AssignToDef =
MRI->getVRegDef(Def->getOperand(1).getReg())) {
- if (AssignToDef->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
+ if (AssignToDef->getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
+ AssignToDef->getOpcode() == TargetOpcode::G_POISON)
Reg = Def->getOperand(2).getReg();
}
break;
diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
index 578e82881f6e8..906a16ffcdf49 100644
--- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
@@ -222,7 +222,8 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
all(typeInSet(0, allPtrsScalarsAndVectors),
typeInSet(1, allPtrsScalarsAndVectors)));
- getActionDefinitionsBuilder({G_IMPLICIT_DEF, G_FREEZE}).alwaysLegal();
+ getActionDefinitionsBuilder({G_IMPLICIT_DEF, G_POISON, G_FREEZE})
+ .alwaysLegal();
getActionDefinitionsBuilder({G_STACKSAVE, G_STACKRESTORE}).alwaysLegal();
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index 3fcff3dd8f553..e288803eebf23 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -93,7 +93,8 @@ addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR,
if (SrcMI)
GR->add(Const, SrcMI);
if (SrcMI && (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT ||
- SrcMI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF))
+ SrcMI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
+ SrcMI->getOpcode() == TargetOpcode::G_POISON))
TargetExtConstTypes[SrcMI] = Const->getType();
if (Const->isNullValue()) {
MachineBasicBlock &DepMBB = MF.front();
diff --git a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
index 64a1fa1780a77..3660303e7cc47 100644
--- a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
+++ b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
@@ -113,7 +113,8 @@ class X86InstructionSelector : public InstructionSelector {
const TargetRegisterClass *SrcRC) const;
bool materializeFP(MachineInstr &I, MachineRegisterInfo &MRI,
MachineFunction &MF) const;
- bool selectImplicitDefOrPHI(MachineInstr &I, MachineRegisterInfo &MRI) const;
+ bool selectImplicitDefOrPoisonOrPHI(MachineInstr &I,
+ MachineRegisterInfo &MRI) const;
bool selectMulDivRem(MachineInstr &I, MachineRegisterInfo &MRI,
MachineFunction &MF) const;
bool selectSelect(MachineInstr &I, MachineRegisterInfo &MRI,
@@ -428,8 +429,9 @@ bool X86InstructionSelector::select(MachineInstr &I) {
case TargetOpcode::G_BRCOND:
return selectCondBranch(I, MRI, MF);
case TargetOpcode::G_IMPLICIT_DEF:
+ case TargetOpcode::G_POISON:
case TargetOpcode::G_PHI:
- return selectImplicitDefOrPHI(I, MRI);
+ return selectImplicitDefOrPoisonOrPHI(I, MRI);
case TargetOpcode::G_MUL:
case TargetOpcode::G_SMULH:
case TargetOpcode::G_UMULH:
@@ -1585,9 +1587,10 @@ bool X86InstructionSelector::materializeFP(MachineInstr &I,
return true;
}
-bool X86InstructionSelector::selectImplicitDefOrPHI(
+bool X86InstructionSelector::selectImplicitDefOrPoisonOrPHI(
MachineInstr &I, MachineRegisterInfo &MRI) const {
assert((I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
+ I.getOpcode() == TargetOpcode::G_POISON ||
I.getOpcode() == TargetOpcode::G_PHI) &&
"unexpected instruction");
@@ -1604,7 +1607,8 @@ bool X86InstructionSelector::selectImplicitDefOrPHI(
}
}
- if (I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
+ if (I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
+ I.getOpcode() == TargetOpcode::G_POISON)
I.setDesc(TII.get(X86::IMPLICIT_DEF));
else
I.setDesc(TII.get(X86::PHI));
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index ba9fa254a477a..560e296773173 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -82,7 +82,7 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
// todo: AVX512 bool vector predicate types
// implicit/constants
- getActionDefinitionsBuilder(G_IMPLICIT_DEF)
+ getActionDefinitionsBuilder({G_IMPLICIT_DEF, G_POISON})
.legalIf([=](const LegalityQuery &Query) -> bool {
// 32/64-bits needs support for s64/s128 to handle cases:
// s64 = EXTEND (G_IMPLICIT_DEF s32) -> s64 = G_IMPLICIT_DEF
diff --git a/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp b/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp
index 0baca81494694..cde06fe1f164e 100644
--- a/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp
@@ -404,6 +404,7 @@ X86RegisterBankInfo::getInstrAlternativeMappings(const MachineInstr &MI) const {
switch (MI.getOpcode()) {
case TargetOpcode::G_LOAD:
case TargetOpcode::G_STORE:
+ case TargetOpcode::G_POISON:
case TargetOpcode::G_IMPLICIT_DEF: {
// we going to try to map 32/64/80 bit to PMI_FP32/PMI_FP64/PMI_FP80
unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
More information about the llvm-commits
mailing list