Skip to content

Commit 892497c

Browse files
author
Jessica Paquette
committed
[GlobalISel] Simplify G_ICMP to true/false when the result is known
Use existing KnownBits helpers from KnownBits.h to simplify G_ICMPs. E.g. x == x -> true x != x -> false load(x) > 1 -> true (when the load is known to be greater than 1) And so on. Differential Revision: https://reviews.llvm.org/D102542
1 parent 8998a8a commit 892497c

File tree

15 files changed

+4729
-6741
lines changed

15 files changed

+4729
-6741
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,10 @@ class CombinerHelper {
513513
bool matchRotateOutOfRange(MachineInstr &MI);
514514
void applyRotateOutOfRange(MachineInstr &MI);
515515

516+
/// \returns true if a G_ICMP instruction \p MI can be replaced with a true
517+
/// or false constant based off of KnownBits information.
518+
bool matchICmpToTrueFalseKnownBits(MachineInstr &MI, int64_t &MatchInfo);
519+
516520
/// Try to transform \p MI by using all of the above
517521
/// combine functions. Returns true if changed.
518522
bool tryCombine(MachineInstr &MI);

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ class GIApplyKind;
114114
class GIApplyKindWithArgs;
115115

116116
def register_matchinfo: GIDefMatchData<"Register">;
117+
def int64_matchinfo: GIDefMatchData<"int64_t">;
117118
def build_fn_matchinfo :
118119
GIDefMatchData<"std::function<void(MachineIRBuilder &)>">;
119120

@@ -613,6 +614,12 @@ def rotate_out_of_range : GICombineRule<
613614
(apply [{ Helper.applyRotateOutOfRange(*${root}); }])
614615
>;
615616

617+
def icmp_to_true_false_known_bits : GICombineRule<
618+
(defs root:$d, int64_matchinfo:$matchinfo),
619+
(match (wip_match_opcode G_ICMP):$d,
620+
[{ return Helper.matchICmpToTrueFalseKnownBits(*${d}, ${matchinfo}); }]),
621+
(apply [{ Helper.replaceInstWithConstant(*${d}, ${matchinfo}); }])>;
622+
616623
def funnel_shift_combines : GICombineGroup<[funnel_shift_to_rotate]>;
617624

618625
// FIXME: These should use the custom predicate feature once it lands.
@@ -634,7 +641,7 @@ def const_combines : GICombineGroup<[constant_fp_op, const_ptradd_to_i2p]>;
634641

635642
def known_bits_simplifications : GICombineGroup<[
636643
redundant_and, redundant_sext_inreg, redundant_or, urem_pow2_to_mask,
637-
zext_trunc_fold]>;
644+
zext_trunc_fold, icmp_to_true_false_known_bits]>;
638645

639646
def width_reduction_combines : GICombineGroup<[reduce_shl_of_extend]>;
640647

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3926,6 +3926,59 @@ void CombinerHelper::applyRotateOutOfRange(MachineInstr &MI) {
39263926
Observer.changedInstr(MI);
39273927
}
39283928

3929+
bool CombinerHelper::matchICmpToTrueFalseKnownBits(MachineInstr &MI,
3930+
int64_t &MatchInfo) {
3931+
assert(MI.getOpcode() == TargetOpcode::G_ICMP);
3932+
auto Pred = static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
3933+
auto KnownLHS = KB->getKnownBits(MI.getOperand(2).getReg());
3934+
auto KnownRHS = KB->getKnownBits(MI.getOperand(3).getReg());
3935+
Optional<bool> KnownVal;
3936+
switch (Pred) {
3937+
default:
3938+
llvm_unreachable("Unexpected G_ICMP predicate?");
3939+
case CmpInst::ICMP_EQ:
3940+
KnownVal = KnownBits::eq(KnownLHS, KnownRHS);
3941+
break;
3942+
case CmpInst::ICMP_NE:
3943+
KnownVal = KnownBits::ne(KnownLHS, KnownRHS);
3944+
break;
3945+
case CmpInst::ICMP_SGE:
3946+
KnownVal = KnownBits::sge(KnownLHS, KnownRHS);
3947+
break;
3948+
case CmpInst::ICMP_SGT:
3949+
KnownVal = KnownBits::sgt(KnownLHS, KnownRHS);
3950+
break;
3951+
case CmpInst::ICMP_SLE:
3952+
KnownVal = KnownBits::sle(KnownLHS, KnownRHS);
3953+
break;
3954+
case CmpInst::ICMP_SLT:
3955+
KnownVal = KnownBits::slt(KnownLHS, KnownRHS);
3956+
break;
3957+
case CmpInst::ICMP_UGE:
3958+
KnownVal = KnownBits::uge(KnownLHS, KnownRHS);
3959+
break;
3960+
case CmpInst::ICMP_UGT:
3961+
KnownVal = KnownBits::ugt(KnownLHS, KnownRHS);
3962+
break;
3963+
case CmpInst::ICMP_ULE:
3964+
KnownVal = KnownBits::ule(KnownLHS, KnownRHS);
3965+
break;
3966+
case CmpInst::ICMP_ULT:
3967+
KnownVal = KnownBits::ult(KnownLHS, KnownRHS);
3968+
break;
3969+
}
3970+
if (!KnownVal)
3971+
return false;
3972+
MatchInfo =
3973+
*KnownVal
3974+
? getICmpTrueVal(getTargetLowering(),
3975+
/*IsVector = */
3976+
MRI.getType(MI.getOperand(0).getReg()).isVector(),
3977+
/* IsFP = */ false)
3978+
: 0;
3979+
return true;
3980+
}
3981+
39293982
bool CombinerHelper::tryCombine(MachineInstr &MI) {
39303983
if (tryCombineCopy(MI))
39313984
return true;

llvm/lib/Target/AArch64/AArch64Combine.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ def AArch64PostLegalizerCombinerHelper
210210
redundant_and, xor_of_and_with_same_reg,
211211
extractvecelt_pairwise_add, redundant_or,
212212
mul_const, redundant_sext_inreg,
213-
form_bitfield_extract, rotate_out_of_range]> {
213+
form_bitfield_extract, rotate_out_of_range,
214+
icmp_to_true_false_known_bits]> {
214215
let DisableRuleOption = "aarch64postlegalizercombiner-disable-rule";
215216
}

0 commit comments

Comments
 (0)