@@ -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+
433439def 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.
452469def 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.
460486def 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.
467502def 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+
657699def simplify_add_to_sub_matchinfo: GIDefMatchData<"std::tuple<Register, Register>">;
658700def 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+
19842031def 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,
0 commit comments