LLVM 20.0.0git
CombinerHelperCompares.cpp
Go to the documentation of this file.
1//===- CombinerHelperCompares.cpp------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements CombinerHelper for G_ICMP.
10//
11//===----------------------------------------------------------------------===//
23#include <cstdlib>
24
25#define DEBUG_TYPE "gi-combiner"
26
27using namespace llvm;
28
29bool CombinerHelper::constantFoldICmp(const GICmp &ICmp,
30 const GIConstant &LHSCst,
31 const GIConstant &RHSCst,
32 BuildFnTy &MatchInfo) const {
34 return false;
35
36 Register Dst = ICmp.getReg(0);
37 LLT DstTy = MRI.getType(Dst);
38
40 return false;
41
42 CmpInst::Predicate Pred = ICmp.getCond();
43 APInt LHS = LHSCst.getScalarValue();
44 APInt RHS = RHSCst.getScalarValue();
45
46 bool Result = ICmpInst::compare(LHS, RHS, Pred);
47
48 MatchInfo = [=](MachineIRBuilder &B) {
49 if (Result)
50 B.buildConstant(Dst, getICmpTrueVal(getTargetLowering(),
51 /*IsVector=*/DstTy.isVector(),
52 /*IsFP=*/false));
53 else
54 B.buildConstant(Dst, 0);
55 };
56
57 return true;
58}
59
60bool CombinerHelper::constantFoldFCmp(const GFCmp &FCmp,
61 const GFConstant &LHSCst,
62 const GFConstant &RHSCst,
63 BuildFnTy &MatchInfo) const {
65 return false;
66
67 Register Dst = FCmp.getReg(0);
68 LLT DstTy = MRI.getType(Dst);
69
71 return false;
72
73 CmpInst::Predicate Pred = FCmp.getCond();
74 APFloat LHS = LHSCst.getScalarValue();
75 APFloat RHS = RHSCst.getScalarValue();
76
77 bool Result = FCmpInst::compare(LHS, RHS, Pred);
78
79 MatchInfo = [=](MachineIRBuilder &B) {
80 if (Result)
81 B.buildConstant(Dst, getICmpTrueVal(getTargetLowering(),
82 /*IsVector=*/DstTy.isVector(),
83 /*IsFP=*/true));
84 else
85 B.buildConstant(Dst, 0);
86 };
87
88 return true;
89}
90
92 BuildFnTy &MatchInfo) const {
93 const GICmp *Cmp = cast<GICmp>(&MI);
94
95 Register Dst = Cmp->getReg(0);
96 Register LHS = Cmp->getLHSReg();
97 Register RHS = Cmp->getRHSReg();
98
99 CmpInst::Predicate Pred = Cmp->getCond();
100 assert(CmpInst::isIntPredicate(Pred) && "Not an integer compare!");
101 if (auto CLHS = GIConstant::getConstant(LHS, MRI)) {
102 if (auto CRHS = GIConstant::getConstant(RHS, MRI))
103 return constantFoldICmp(*Cmp, *CLHS, *CRHS, MatchInfo);
104
105 // If we have a constant, make sure it is on the RHS.
106 std::swap(LHS, RHS);
107 Pred = CmpInst::getSwappedPredicate(Pred);
108
109 MatchInfo = [=](MachineIRBuilder &B) { B.buildICmp(Pred, Dst, LHS, RHS); };
110 return true;
111 }
112
113 return false;
114}
115
117 BuildFnTy &MatchInfo) const {
118 const GFCmp *Cmp = cast<GFCmp>(&MI);
119
120 Register Dst = Cmp->getReg(0);
121 Register LHS = Cmp->getLHSReg();
122 Register RHS = Cmp->getRHSReg();
123
124 CmpInst::Predicate Pred = Cmp->getCond();
125 assert(CmpInst::isFPPredicate(Pred) && "Not an FP compare!");
126
127 if (auto CLHS = GFConstant::getConstant(LHS, MRI)) {
128 if (auto CRHS = GFConstant::getConstant(RHS, MRI))
129 return constantFoldFCmp(*Cmp, *CLHS, *CRHS, MatchInfo);
130
131 // If we have a constant, make sure it is on the RHS.
132 std::swap(LHS, RHS);
133 Pred = CmpInst::getSwappedPredicate(Pred);
134
135 MatchInfo = [=](MachineIRBuilder &B) {
136 B.buildFCmp(Pred, Dst, LHS, RHS, Cmp->getFlags());
137 };
138 return true;
139 }
140
141 return false;
142}
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This contains common combine transformations that may be used in a combine pass,or by the target else...
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
IRTranslator LLVM IR MI
Interface for Targets to specify which operations they can successfully select and how the others sho...
This file declares the MachineIRBuilder class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition: APInt.h:78
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:673
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Definition: InstrTypes.h:825
bool isFPPredicate() const
Definition: InstrTypes.h:780
bool isIntPredicate() const
Definition: InstrTypes.h:781
const TargetLowering & getTargetLowering() const
bool matchCanonicalizeFCmp(const MachineInstr &MI, BuildFnTy &MatchInfo) const
bool isConstantLegalOrBeforeLegalizer(const LLT Ty) const
MachineRegisterInfo & MRI
bool matchCanonicalizeICmp(const MachineInstr &MI, BuildFnTy &MatchInfo) const
static bool compare(const APFloat &LHS, const APFloat &RHS, FCmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
CmpInst::Predicate getCond() const
Represent a G_FCMP.
An floating-point-like constant.
Definition: Utils.h:645
static std::optional< GFConstant > getConstant(Register Const, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:2014
GFConstantKind getKind() const
Returns the kind of of this constant, e.g, Scalar.
Definition: Utils.h:661
APFloat getScalarValue() const
Returns the value, if this constant is a scalar.
Definition: Utils.cpp:2007
Represent a G_ICMP.
An integer-like constant.
Definition: Utils.h:606
APInt getScalarValue() const
Returns the value, if this constant is a scalar.
Definition: Utils.cpp:1967
static std::optional< GIConstant > getConstant(Register Const, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:1974
GIConstantKind getKind() const
Returns the kind of of this constant, e.g, Scalar.
Definition: Utils.h:622
Register getReg(unsigned Idx) const
Access the Idx'th operand as a register and return it.
static bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
constexpr bool isVector() const
Definition: LowLevelType.h:148
Helper class to build MachineInstr.
Representation of each machine instruction.
Definition: MachineInstr.h:69
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
std::function< void(MachineIRBuilder &)> BuildFnTy
int64_t getICmpTrueVal(const TargetLowering &TLI, bool IsVector, bool IsFP)
Returns an integer representing true, as defined by the TargetBooleanContents.
Definition: Utils.cpp:1610
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:860