Skip to content

Commit 6f076a2

Browse files
committed
[GlobalISel] Combine (X == 0) & (Y == 0) -> (X | Y) == 0
Also combine (X != 0) | (Y != 0) -> (X | Y) != 0
1 parent 8e2bd05 commit 6f076a2

File tree

5 files changed

+829
-37
lines changed

5 files changed

+829
-37
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,10 @@ class CombinerHelper {
805805
/// (X ^ Y) != X -> Y != 0
806806
bool matchRedundantBinOpInEquality(MachineInstr &MI, BuildFnTy &MatchInfo);
807807

808+
/// Transform: (X == 0 & Y == 0) -> (X | Y) == 0
809+
/// (X != 0 | Y != 0) -> (X | Y) != 0
810+
bool matchDoubleICmpZeroAndOr(MachineInstr &MI, BuildFnTy &MatchInfo);
811+
808812
/// Match shifts greater or equal to the bitwidth of the operation.
809813
bool matchShiftsTooBig(MachineInstr &MI);
810814

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,12 @@ def redundant_binop_in_equality : GICombineRule<
903903
[{ return Helper.matchRedundantBinOpInEquality(*${root}, ${info}); }]),
904904
(apply [{ Helper.applyBuildFn(*${root}, ${info}); }])>;
905905

906+
def double_icmp_zero_and_or_combine : GICombineRule<
907+
(defs root:$root, build_fn_matchinfo:$info),
908+
(match (wip_match_opcode G_AND, G_OR):$root,
909+
[{ return Helper.matchDoubleICmpZeroAndOr(*${root}, ${info}); }]),
910+
(apply [{ Helper.applyBuildFn(*${root}, ${info}); }])>;
911+
906912
def and_or_disjoint_mask : GICombineRule<
907913
(defs root:$root, build_fn_matchinfo:$info),
908914
(match (wip_match_opcode G_AND):$root,
@@ -1265,7 +1271,7 @@ def all_combines : GICombineGroup<[trivial_combines, insert_vec_elt_combines,
12651271
intdiv_combines, mulh_combines, redundant_neg_operands,
12661272
and_or_disjoint_mask, fma_combines, fold_binop_into_select,
12671273
sub_add_reg, select_to_minmax, redundant_binop_in_equality,
1268-
fsub_to_fneg, commute_constant_to_rhs]>;
1274+
double_icmp_zero_and_or_combine, fsub_to_fneg, commute_constant_to_rhs]>;
12691275

12701276
// A combine group used to for prelegalizer combiners at -O0. The combines in
12711277
// this group have been selected based on experiments to balance code size and

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6066,6 +6066,47 @@ bool CombinerHelper::matchRedundantBinOpInEquality(MachineInstr &MI,
60666066
return CmpInst::isEquality(Pred) && Y.isValid();
60676067
}
60686068

6069+
bool CombinerHelper::matchDoubleICmpZeroAndOr(
6070+
MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
6071+
const unsigned Opcode = MI.getOpcode();
6072+
assert(Opcode == TargetOpcode::G_OR || Opcode == TargetOpcode::G_AND);
6073+
6074+
const Register Dst = MI.getOperand(0).getReg();
6075+
CmpInst::Predicate LHSPred, RHSPred;
6076+
int64_t LHSImm, RHSImm;
6077+
Register LHSCmpSrc, RHSCmpSrc;
6078+
if (!mi_match(
6079+
Dst, MRI,
6080+
m_BinOp(Opcode,
6081+
m_GICmp(m_Pred(LHSPred), m_Reg(LHSCmpSrc), m_ICst(LHSImm)),
6082+
m_GICmp(m_Pred(RHSPred), m_Reg(RHSCmpSrc), m_ICst(RHSImm)))))
6083+
return false;
6084+
6085+
// G_OR and G_AND cannot handle pointers
6086+
const auto LHSSrcTy = MRI.getType(LHSCmpSrc);
6087+
if (LHSSrcTy != MRI.getType(RHSCmpSrc) || LHSSrcTy.isPointer())
6088+
return false;
6089+
6090+
const bool IsAnd = Opcode == TargetOpcode::G_AND;
6091+
if ((IsAnd && LHSPred != CmpInst::ICMP_EQ) ||
6092+
(!IsAnd && LHSPred != CmpInst::ICMP_NE) || LHSPred != RHSPred)
6093+
return false;
6094+
6095+
if (LHSImm != 0 || RHSImm != 0)
6096+
return false;
6097+
6098+
MatchInfo = [=](MachineIRBuilder &B) {
6099+
const Register OrDst = MRI.createGenericVirtualRegister(LHSSrcTy);
6100+
auto Zero = B.buildConstant(LHSSrcTy, 0);
6101+
B.buildOr(OrDst, LHSCmpSrc, RHSCmpSrc);
6102+
B.buildICmp(IsAnd ? CmpInst::Predicate::ICMP_EQ
6103+
: CmpInst::Predicate::ICMP_NE,
6104+
Dst, OrDst, Zero);
6105+
};
6106+
6107+
return true;
6108+
}
6109+
60696110
bool CombinerHelper::matchShiftsTooBig(MachineInstr &MI) {
60706111
Register ShiftReg = MI.getOperand(2).getReg();
60716112
LLT ResTy = MRI.getType(MI.getOperand(0).getReg());

0 commit comments

Comments
 (0)