[llvm] [GlobalIsel] Visit ICmp (PR #105991)
Thorsten Schütt via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 25 22:03:21 PDT 2024
================
@@ -0,0 +1,292 @@
+//===- CombinerHelperCompares.cpp------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements CombinerHelper for G_ICMP
+//
+//===----------------------------------------------------------------------===//
+#include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
+#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
+#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
+#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
+#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+#include "llvm/CodeGen/GlobalISel/Utils.h"
+#include "llvm/CodeGen/LowLevelTypeUtils.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/TargetOpcodes.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cstdlib>
+
+#define DEBUG_TYPE "gi-combiner"
+
+using namespace llvm;
+
+bool CombinerHelper::constantFoldICmp(const GICmp &ICmp,
+ const GIConstant &LHSCst,
+ const GIConstant &RHSCst,
+ BuildFnTy &MatchInfo) {
+ if (LHSCst.getKind() != GIConstantKind::Scalar)
+ return false;
+
+ Register Dst = ICmp.getReg(0);
+ LLT DstTy = MRI.getType(Dst);
+
+ if (!isConstantLegalOrBeforeLegalizer(DstTy))
+ return false;
+
+ CmpInst::Predicate Pred = ICmp.getCond();
+ APInt LHS = LHSCst.getScalarValue();
+ APInt RHS = RHSCst.getScalarValue();
+
+ bool Result;
+
+ switch (Pred) {
+ case CmpInst::Predicate::ICMP_EQ:
+ Result = LHS.eq(RHS);
+ break;
+ case CmpInst::Predicate::ICMP_NE:
+ Result = LHS.ne(RHS);
+ break;
+ case CmpInst::Predicate::ICMP_UGT:
+ Result = LHS.ugt(RHS);
+ break;
+ case CmpInst::Predicate::ICMP_UGE:
+ Result = LHS.uge(RHS);
+ break;
+ case CmpInst::Predicate::ICMP_ULT:
+ Result = LHS.ult(RHS);
+ break;
+ case CmpInst::Predicate::ICMP_ULE:
+ Result = LHS.ule(RHS);
+ break;
+ case CmpInst::Predicate::ICMP_SGT:
+ Result = LHS.sgt(RHS);
+ break;
+ case CmpInst::Predicate::ICMP_SGE:
+ Result = LHS.sge(RHS);
+ break;
+ case CmpInst::Predicate::ICMP_SLT:
+ Result = LHS.slt(RHS);
+ break;
+ case CmpInst::Predicate::ICMP_SLE:
+ Result = LHS.sle(RHS);
+ break;
+ default:
+ llvm_unreachable("Unexpected predicate");
+ }
+
+ MatchInfo = [=](MachineIRBuilder &B) {
+ if (Result)
+ B.buildConstant(Dst, getICmpTrueVal(getTargetLowering(),
+ /*IsVector=*/DstTy.isVector(),
+ /*IsFP=*/false));
+ else
+ B.buildConstant(Dst, 0);
+ };
+
+ return true;
+}
+
+bool CombinerHelper::visitICmp(const MachineInstr &MI, BuildFnTy &MatchInfo) {
+ const GICmp *Cmp = cast<GICmp>(&MI);
+
+ Register Dst = Cmp->getReg(0);
+ LLT DstTy = MRI.getType(Dst);
+ Register LHS = Cmp->getLHSReg();
+ Register RHS = Cmp->getRHSReg();
+
+ CmpInst::Predicate Pred = Cmp->getCond();
+ assert(CmpInst::isIntPredicate(Pred) && "Not an integer compare!");
+ if (auto CLHS = GIConstant::getConstant(LHS, MRI)) {
+ if (auto CRHS = GIConstant::getConstant(RHS, MRI))
+ return constantFoldICmp(*Cmp, *CLHS, *CRHS, MatchInfo);
+
+ // If we have a constant, make sure it is on the RHS.
+ std::swap(LHS, RHS);
+ Pred = CmpInst::getSwappedPredicate(Pred);
----------------
tschuett wrote:
Yes:
https://github.com/llvm/llvm-project/blob/52ae891036e3ab1f668eb103c46ca57257901c6b/llvm/include/llvm/Target/GlobalISel/Combine.td#L481
Otherwise:
```
def icmp_of_zero : GICombineRule<
(defs root:$root, build_fn_matchinfo:$matchinfo),
(match (G_CONSTANT $zero, 0),
(G_ICMP $root, $pred, $lhs, $zero):$cmp,
[{ return Helper.matchCmpOfZero(*${cmp}, ${matchinfo}); }]),
(apply [{ Helper.applyBuildFn(*${cmp}, ${matchinfo}); }])>;
```
would hit less often, see my first comment above.
https://github.com/llvm/llvm-project/pull/105991
More information about the llvm-commits
mailing list