1 //===- CombinerHelperCompares.cpp------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements CombinerHelper for G_ICMP.
11 //===----------------------------------------------------------------------===//
12 #include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
13 #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
14 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
15 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
16 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
17 #include "llvm/CodeGen/GlobalISel/Utils.h"
18 #include "llvm/CodeGen/MachineInstr.h"
19 #include "llvm/CodeGen/MachineOperand.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/IR/Instructions.h"
22 #include "llvm/Support/Casting.h"
25 #define DEBUG_TYPE "gi-combiner"
29 bool CombinerHelper::constantFoldICmp(const GICmp
&ICmp
,
30 const GIConstant
&LHSCst
,
31 const GIConstant
&RHSCst
,
32 BuildFnTy
&MatchInfo
) const {
33 if (LHSCst
.getKind() != GIConstant::GIConstantKind::Scalar
)
36 Register Dst
= ICmp
.getReg(0);
37 LLT DstTy
= MRI
.getType(Dst
);
39 if (!isConstantLegalOrBeforeLegalizer(DstTy
))
42 CmpInst::Predicate Pred
= ICmp
.getCond();
43 APInt LHS
= LHSCst
.getScalarValue();
44 APInt RHS
= RHSCst
.getScalarValue();
46 bool Result
= ICmpInst::compare(LHS
, RHS
, Pred
);
48 MatchInfo
= [=](MachineIRBuilder
&B
) {
50 B
.buildConstant(Dst
, getICmpTrueVal(getTargetLowering(),
51 /*IsVector=*/DstTy
.isVector(),
54 B
.buildConstant(Dst
, 0);
60 bool CombinerHelper::constantFoldFCmp(const GFCmp
&FCmp
,
61 const GFConstant
&LHSCst
,
62 const GFConstant
&RHSCst
,
63 BuildFnTy
&MatchInfo
) const {
64 if (LHSCst
.getKind() != GFConstant::GFConstantKind::Scalar
)
67 Register Dst
= FCmp
.getReg(0);
68 LLT DstTy
= MRI
.getType(Dst
);
70 if (!isConstantLegalOrBeforeLegalizer(DstTy
))
73 CmpInst::Predicate Pred
= FCmp
.getCond();
74 APFloat LHS
= LHSCst
.getScalarValue();
75 APFloat RHS
= RHSCst
.getScalarValue();
77 bool Result
= FCmpInst::compare(LHS
, RHS
, Pred
);
79 MatchInfo
= [=](MachineIRBuilder
&B
) {
81 B
.buildConstant(Dst
, getICmpTrueVal(getTargetLowering(),
82 /*IsVector=*/DstTy
.isVector(),
85 B
.buildConstant(Dst
, 0);
91 bool CombinerHelper::matchCanonicalizeICmp(const MachineInstr
&MI
,
92 BuildFnTy
&MatchInfo
) const {
93 const GICmp
*Cmp
= cast
<GICmp
>(&MI
);
95 Register Dst
= Cmp
->getReg(0);
96 Register LHS
= Cmp
->getLHSReg();
97 Register RHS
= Cmp
->getRHSReg();
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
);
105 // If we have a constant, make sure it is on the RHS.
107 Pred
= CmpInst::getSwappedPredicate(Pred
);
109 MatchInfo
= [=](MachineIRBuilder
&B
) { B
.buildICmp(Pred
, Dst
, LHS
, RHS
); };
116 bool CombinerHelper::matchCanonicalizeFCmp(const MachineInstr
&MI
,
117 BuildFnTy
&MatchInfo
) const {
118 const GFCmp
*Cmp
= cast
<GFCmp
>(&MI
);
120 Register Dst
= Cmp
->getReg(0);
121 Register LHS
= Cmp
->getLHSReg();
122 Register RHS
= Cmp
->getRHSReg();
124 CmpInst::Predicate Pred
= Cmp
->getCond();
125 assert(CmpInst::isFPPredicate(Pred
) && "Not an FP compare!");
127 if (auto CLHS
= GFConstant::getConstant(LHS
, MRI
)) {
128 if (auto CRHS
= GFConstant::getConstant(RHS
, MRI
))
129 return constantFoldFCmp(*Cmp
, *CLHS
, *CRHS
, MatchInfo
);
131 // If we have a constant, make sure it is on the RHS.
133 Pred
= CmpInst::getSwappedPredicate(Pred
);
135 MatchInfo
= [=](MachineIRBuilder
&B
) {
136 B
.buildFCmp(Pred
, Dst
, LHS
, RHS
, Cmp
->getFlags());