Skip to content

Commit 0d07595

Browse files
committed
[GlobalISel] Introduce G_POISON
1 parent 6196b4e commit 0d07595

File tree

18 files changed

+178
-13
lines changed

18 files changed

+178
-13
lines changed

llvm/docs/GlobalISel/GenericOpcode.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ An undefined value.
2424
2525
%0:_(s32) = G_IMPLICIT_DEF
2626
27+
G_POISON
28+
^^^^^^^^
29+
30+
A poison value.
31+
32+
.. code-block:: none
33+
34+
%0:_(s32) = G_POISON
35+
2736
G_CONSTANT
2837
^^^^^^^^^^
2938

llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,16 +432,27 @@ class CombinerHelper {
432432
/// G_IMPLICIT_DEF.
433433
bool matchAnyExplicitUseIsUndef(MachineInstr &MI) const;
434434

435+
/// Return true if any explicit use operand on \p MI is defined by a
436+
/// G_POISON.
437+
bool matchAnyExplicitUseIsPoison(MachineInstr &MI) const;
438+
435439
/// Return true if all register explicit use operands on \p MI are defined by
436440
/// a G_IMPLICIT_DEF.
437441
bool matchAllExplicitUsesAreUndef(MachineInstr &MI) const;
438442

443+
/// Return true if all register explicit use operands on \p MI are defined by
444+
/// a G_POISON.
445+
bool matchAllExplicitUsesArePoison(MachineInstr &MI) const;
446+
439447
/// Return true if a G_SHUFFLE_VECTOR instruction \p MI has an undef mask.
440448
bool matchUndefShuffleVectorMask(MachineInstr &MI) const;
441449

442450
/// Return true if a G_STORE instruction \p MI is storing an undef value.
443451
bool matchUndefStore(MachineInstr &MI) const;
444452

453+
/// Return true if a G_STORE instruction \p MI is storing a poison value.
454+
bool matchPoisonStore(MachineInstr &MI) const;
455+
445456
/// Return true if a G_SELECT instruction \p MI has an undef comparison.
446457
bool matchUndefSelectCmp(MachineInstr &MI) const;
447458

@@ -467,6 +478,9 @@ class CombinerHelper {
467478
/// Replace an instruction with a G_IMPLICIT_DEF.
468479
void replaceInstWithUndef(MachineInstr &MI) const;
469480

481+
/// Replace an instruction with a G_POISON.
482+
void replaceInstWithPoison(MachineInstr &MI) const;
483+
470484
/// Delete \p MI and replace all of its uses with its \p OpIdx-th operand.
471485
void replaceSingleDefInstWithOperand(MachineInstr &MI, unsigned OpIdx) const;
472486

@@ -507,6 +521,9 @@ class CombinerHelper {
507521
/// Check if operand \p OpIdx is undef.
508522
bool matchOperandIsUndef(MachineInstr &MI, unsigned OpIdx) const;
509523

524+
/// Check if operand \p OpIdx is poison.
525+
bool matchOperandIsPoison(MachineInstr &MI, unsigned OpIdx) const;
526+
510527
/// Check if operand \p OpIdx is known to be a power of 2.
511528
bool matchOperandIsKnownToBeAPowerOfTwo(MachineInstr &MI,
512529
unsigned OpIdx) const;

llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,14 @@ class GImplicitDef : public GenericMachineInstr {
343343
}
344344
};
345345

346+
/// Represents a G_POISON.
347+
class GPoison : public GenericMachineInstr {
348+
public:
349+
static bool classof(const MachineInstr *MI) {
350+
return MI->getOpcode() == TargetOpcode::G_POISON;
351+
}
352+
};
353+
346354
/// Represents a G_SELECT.
347355
class GSelect : public GenericMachineInstr {
348356
public:

llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1017,9 +1017,12 @@ class MachineIRBuilder {
10171017
/// \return a MachineInstrBuilder for the newly created instruction.
10181018
MachineInstrBuilder buildExtract(const DstOp &Res, const SrcOp &Src, uint64_t Index);
10191019

1020-
/// Build and insert \p Res = IMPLICIT_DEF.
1020+
/// Build and insert \p Res = G_IMPLICIT_DEF.
10211021
MachineInstrBuilder buildUndef(const DstOp &Res);
10221022

1023+
/// Build and insert \p Res = G_POISON.
1024+
MachineInstrBuilder buildPoison(const DstOp &Res);
1025+
10231026
/// Build and insert \p Res = G_MERGE_VALUES \p Op0, ...
10241027
///
10251028
/// G_MERGE_VALUES combines the input elements contiguously into a larger

llvm/include/llvm/Support/TargetOpcodes.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,9 +295,12 @@ HANDLE_TARGET_OPCODE(G_ABDS)
295295
/// Generic absolute difference unsigned instruction.
296296
HANDLE_TARGET_OPCODE(G_ABDU)
297297

298-
298+
// Generic implicit definition.
299299
HANDLE_TARGET_OPCODE(G_IMPLICIT_DEF)
300300

301+
// Generic poison value.
302+
HANDLE_TARGET_OPCODE(G_POISON)
303+
301304
/// Generic PHI instruction with types.
302305
HANDLE_TARGET_OPCODE(G_PHI)
303306

llvm/include/llvm/Target/GenericOpcodes.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ def G_IMPLICIT_DEF : GenericInstruction {
9292
let hasSideEffects = false;
9393
}
9494

95+
def G_POISON : GenericInstruction {
96+
let OutOperandList = (outs type0:$dst);
97+
let InOperandList = (ins);
98+
let hasSideEffects = false;
99+
}
100+
95101
def G_PHI : GenericInstruction {
96102
let OutOperandList = (outs type0:$dst);
97103
let InOperandList = (ins variable_ops);

llvm/include/llvm/Target/GlobalISel/Combine.td

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,12 @@ def binop_right_undef_to_undef: GICombineRule<
430430
[{ return Helper.matchOperandIsUndef(*${root}, 2); }]),
431431
(apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
432432

433+
def binop_right_poison_to_poison
434+
: GICombineRule<(defs root:$root),
435+
(match(wip_match_opcode G_SHL, G_ASHR, G_LSHR):$root,
436+
[{ return Helper.matchOperandIsPoison(*${root}, 2); }]),
437+
(apply [{ Helper.replaceInstWithPoison(*${root}); }])>;
438+
433439
def unary_undef_to_zero: GICombineRule<
434440
(defs root:$root),
435441
(match (wip_match_opcode G_ABS):$root,
@@ -447,6 +453,17 @@ def unary_undef_to_undef : GICombineRule<
447453
(match (unary_undef_to_undef_frags $dst)),
448454
(apply [{ Helper.replaceInstWithUndef(*${dst}.getParent()); }])>;
449455

456+
def unary_poison_to_poison_frags
457+
: GICombinePatFrag<(outs root:$dst), (ins),
458+
!foreach(op,
459+
[G_TRUNC, G_BITCAST, G_ANYEXT, G_PTRTOINT,
460+
G_INTTOPTR, G_FPTOSI, G_FPTOUI],
461+
(pattern(op $dst, $x), (G_POISON $x)))>;
462+
def unary_poison_to_poison
463+
: GICombineRule<
464+
(defs root:$dst), (match(unary_poison_to_poison_frags $dst)),
465+
(apply [{ Helper.replaceInstWithPoison(*${dst}.getParent()); }])>;
466+
450467
// Instructions where if any source operand is undef, the instruction can be
451468
// replaced with undef.
452469
def propagate_undef_any_op: GICombineRule<
@@ -455,6 +472,15 @@ def propagate_undef_any_op: GICombineRule<
455472
[{ return Helper.matchAnyExplicitUseIsUndef(*${root}); }]),
456473
(apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
457474

475+
// Instructions where if any source operand is poison, the instruction can be
476+
// replaced with poison.
477+
def propagate_poison_any_op
478+
: GICombineRule<
479+
(defs root:$root),
480+
(match(wip_match_opcode G_ADD, G_SUB, G_XOR):$root,
481+
[{ return Helper.matchAnyExplicitUseIsPoison(*${root}); }]),
482+
(apply [{ Helper.replaceInstWithPoison(*${root}); }])>;
483+
458484
// Instructions where if all source operands are undef, the instruction can be
459485
// replaced with undef.
460486
def propagate_undef_all_ops: GICombineRule<
@@ -463,6 +489,15 @@ def propagate_undef_all_ops: GICombineRule<
463489
[{ return Helper.matchAllExplicitUsesAreUndef(*${root}); }]),
464490
(apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
465491

492+
// Instructions where if all source operands are poison, the instruction can be
493+
// replaced with poison.
494+
def propagate_poison_all_ops
495+
: GICombineRule<
496+
(defs root:$root),
497+
(match(wip_match_opcode G_SHUFFLE_VECTOR, G_BUILD_VECTOR):$root,
498+
[{ return Helper.matchAllExplicitUsesArePoison(*${root}); }]),
499+
(apply [{ Helper.replaceInstWithPoison(*${root}); }])>;
500+
466501
// Replace a G_SHUFFLE_VECTOR with an undef mask with a G_IMPLICIT_DEF.
467502
def propagate_undef_shuffle_mask: GICombineRule<
468503
(defs root:$root),
@@ -654,6 +689,13 @@ def erase_undef_store : GICombineRule<
654689
(apply [{ Helper.eraseInst(*${root}); }])
655690
>;
656691

692+
// Erase stores of poison values.
693+
def erase_poison_store
694+
: GICombineRule<(defs root:$root),
695+
(match(wip_match_opcode G_STORE):$root,
696+
[{ return Helper.matchPoisonStore(*${root}); }]),
697+
(apply [{ Helper.eraseInst(*${root}); }])>;
698+
657699
def simplify_add_to_sub_matchinfo: GIDefMatchData<"std::tuple<Register, Register>">;
658700
def simplify_add_to_sub: GICombineRule <
659701
(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,
19812023
erase_undef_store,
19822024
insert_extract_vec_elt_out_of_bounds]>;
19832025

2026+
def poison_combines
2027+
: GICombineGroup<[binop_right_poison_to_poison, unary_poison_to_poison,
2028+
propagate_poison_any_op, propagate_poison_all_ops,
2029+
erase_poison_store]>;
2030+
19842031
def identity_combines : GICombineGroup<[select_same_val, right_identity_zero,
19852032
binop_same_val, binop_left_to_zero,
19862033
binop_right_to_zero, p2i_to_i2p,
@@ -2036,7 +2083,7 @@ def all_combines : GICombineGroup<[integer_reassoc_combines, trivial_combines,
20362083
vector_ops_combines, freeze_combines, cast_combines,
20372084
insert_vec_elt_combines, extract_vec_elt_combines, combines_for_extload,
20382085
combine_extracted_vector_load,
2039-
undef_combines, identity_combines, phi_combines,
2086+
undef_combines, poison_combines, identity_combines, phi_combines,
20402087
simplify_add_to_sub, hoist_logic_op_with_same_opcode_hands, shifts_too_big,
20412088
reassocs, ptr_add_immed_chain, cmp_combines,
20422089
shl_ashr_to_sext_inreg, neg_and_one_to_sext_inreg, sext_inreg_of_load,

llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ bool CSEConfigFull::shouldCSEOpc(unsigned Opc) {
5454
case TargetOpcode::G_CONSTANT:
5555
case TargetOpcode::G_FCONSTANT:
5656
case TargetOpcode::G_IMPLICIT_DEF:
57+
case TargetOpcode::G_POISON:
5758
case TargetOpcode::G_ZEXT:
5859
case TargetOpcode::G_SEXT:
5960
case TargetOpcode::G_ANYEXT:
@@ -82,7 +83,7 @@ bool CSEConfigFull::shouldCSEOpc(unsigned Opc) {
8283

8384
bool CSEConfigConstantOnly::shouldCSEOpc(unsigned Opc) {
8485
return Opc == TargetOpcode::G_CONSTANT || Opc == TargetOpcode::G_FCONSTANT ||
85-
Opc == TargetOpcode::G_IMPLICIT_DEF;
86+
Opc == TargetOpcode::G_IMPLICIT_DEF || Opc == TargetOpcode::G_POISON;
8687
}
8788

8889
std::unique_ptr<CSEConfigBase>

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ bool CombinerHelper::matchCombineConcatVectors(
330330
for (const MachineOperand &BuildVecMO : Def->uses())
331331
Ops.push_back(BuildVecMO.getReg());
332332
break;
333+
case TargetOpcode::G_POISON:
333334
case TargetOpcode::G_IMPLICIT_DEF: {
334335
LLT OpType = MRI.getType(Reg);
335336
// Keep one undef value for all the undef operands.
@@ -2736,13 +2737,26 @@ bool CombinerHelper::matchAnyExplicitUseIsUndef(MachineInstr &MI) const {
27362737
});
27372738
}
27382739

2740+
bool CombinerHelper::matchAnyExplicitUseIsPoison(MachineInstr &MI) const {
2741+
return any_of(MI.explicit_uses(), [this](const MachineOperand &MO) {
2742+
return MO.isReg() && getOpcodeDef(TargetOpcode::G_POISON, MO.getReg(), MRI);
2743+
});
2744+
}
2745+
27392746
bool CombinerHelper::matchAllExplicitUsesAreUndef(MachineInstr &MI) const {
27402747
return all_of(MI.explicit_uses(), [this](const MachineOperand &MO) {
27412748
return !MO.isReg() ||
27422749
getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, MO.getReg(), MRI);
27432750
});
27442751
}
27452752

2753+
bool CombinerHelper::matchAllExplicitUsesArePoison(MachineInstr &MI) const {
2754+
return all_of(MI.explicit_uses(), [this](const MachineOperand &MO) {
2755+
return !MO.isReg() ||
2756+
getOpcodeDef(TargetOpcode::G_POISON, MO.getReg(), MRI);
2757+
});
2758+
}
2759+
27462760
bool CombinerHelper::matchUndefShuffleVectorMask(MachineInstr &MI) const {
27472761
assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
27482762
ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask();
@@ -2755,6 +2769,11 @@ bool CombinerHelper::matchUndefStore(MachineInstr &MI) const {
27552769
MRI);
27562770
}
27572771

2772+
bool CombinerHelper::matchPoisonStore(MachineInstr &MI) const {
2773+
assert(MI.getOpcode() == TargetOpcode::G_STORE);
2774+
return getOpcodeDef(TargetOpcode::G_POISON, MI.getOperand(0).getReg(), MRI);
2775+
}
2776+
27582777
bool CombinerHelper::matchUndefSelectCmp(MachineInstr &MI) const {
27592778
assert(MI.getOpcode() == TargetOpcode::G_SELECT);
27602779
return getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, MI.getOperand(1).getReg(),
@@ -2994,6 +3013,12 @@ bool CombinerHelper::matchOperandIsUndef(MachineInstr &MI,
29943013
getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, MO.getReg(), MRI);
29953014
}
29963015

3016+
bool CombinerHelper::matchOperandIsPoison(MachineInstr &MI,
3017+
unsigned OpIdx) const {
3018+
MachineOperand &MO = MI.getOperand(OpIdx);
3019+
return MO.isReg() && getOpcodeDef(TargetOpcode::G_POISON, MO.getReg(), MRI);
3020+
}
3021+
29973022
bool CombinerHelper::matchOperandIsKnownToBeAPowerOfTwo(MachineInstr &MI,
29983023
unsigned OpIdx) const {
29993024
MachineOperand &MO = MI.getOperand(OpIdx);
@@ -3033,6 +3058,12 @@ void CombinerHelper::replaceInstWithUndef(MachineInstr &MI) const {
30333058
MI.eraseFromParent();
30343059
}
30353060

3061+
void CombinerHelper::replaceInstWithPoison(MachineInstr &MI) const {
3062+
assert(MI.getNumDefs() == 1 && "Expected only one def?");
3063+
Builder.buildPoison(MI.getOperand(0));
3064+
MI.eraseFromParent();
3065+
}
3066+
30363067
bool CombinerHelper::matchSimplifyAddToSub(
30373068
MachineInstr &MI, std::tuple<Register, Register> &MatchInfo) const {
30383069
Register LHS = MI.getOperand(1).getReg();
@@ -3097,6 +3128,7 @@ bool CombinerHelper::matchCombineInsertVecElts(
30973128
// If we didn't end in a G_IMPLICIT_DEF and the source is not fully
30983129
// overwritten, bail out.
30993130
return TmpInst->getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
3131+
TmpInst->getOpcode() == TargetOpcode::G_POISON ||
31003132
all_of(MatchInfo, [](Register Reg) { return !!Reg; });
31013133
}
31023134

@@ -3467,12 +3499,13 @@ bool CombinerHelper::matchUseVectorTruncate(MachineInstr &MI,
34673499
if (I < 2)
34683500
return false;
34693501

3470-
// Check the remaining source elements are only G_IMPLICIT_DEF
3502+
// Check the remaining source elements are only G_IMPLICIT_DEF or G_POISON
34713503
for (; I < NumOperands; ++I) {
34723504
auto SrcMI = MRI.getVRegDef(BuildMI->getSourceReg(I));
34733505
auto SrcMIOpc = SrcMI->getOpcode();
34743506

3475-
if (SrcMIOpc != TargetOpcode::G_IMPLICIT_DEF)
3507+
if (SrcMIOpc != TargetOpcode::G_IMPLICIT_DEF &&
3508+
SrcMIOpc != TargetOpcode::G_POISON)
34763509
return false;
34773510
}
34783511

@@ -7933,6 +7966,12 @@ bool CombinerHelper::matchShuffleDisjointMask(MachineInstr &MI,
79337966
if (getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, Shuffle.getSrc2Reg(), MRI))
79347967
return false;
79357968

7969+
if (getOpcodeDef(TargetOpcode::G_POISON, Shuffle.getSrc1Reg(), MRI))
7970+
return false;
7971+
7972+
if (getOpcodeDef(TargetOpcode::G_POISON, Shuffle.getSrc2Reg(), MRI))
7973+
return false;
7974+
79367975
const LLT DstTy = MRI.getType(Shuffle.getReg(0));
79377976
const LLT Src1Ty = MRI.getType(Shuffle.getSrc1Reg());
79387977
if (!isLegalOrBeforeLegalizer(

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3649,6 +3649,8 @@ bool IRTranslator::translate(const Constant &C, Register Reg) {
36493649
EntryBuilder->buildConstant(Reg, *CI);
36503650
else if (auto CF = dyn_cast<ConstantFP>(&C))
36513651
EntryBuilder->buildFConstant(Reg, *CF);
3652+
else if (isa<PoisonValue>(C))
3653+
EntryBuilder->buildPoison(Reg);
36523654
else if (isa<UndefValue>(C))
36533655
EntryBuilder->buildUndef(Reg);
36543656
else if (isa<ConstantPointerNull>(C))

0 commit comments

Comments
 (0)