AMDGPU: Mark test as XFAIL in expensive_checks builds
[llvm-project.git] / llvm / lib / CodeGen / GlobalISel / CombinerHelperCompares.cpp
blobfc40533cf3dc95739da1c2f25cf3f15d0322d35c
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.
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"
23 #include <cstdlib>
25 #define DEBUG_TYPE "gi-combiner"
27 using namespace llvm;
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)
34 return false;
36 Register Dst = ICmp.getReg(0);
37 LLT DstTy = MRI.getType(Dst);
39 if (!isConstantLegalOrBeforeLegalizer(DstTy))
40 return false;
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) {
49 if (Result)
50 B.buildConstant(Dst, getICmpTrueVal(getTargetLowering(),
51 /*IsVector=*/DstTy.isVector(),
52 /*IsFP=*/false));
53 else
54 B.buildConstant(Dst, 0);
57 return true;
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)
65 return false;
67 Register Dst = FCmp.getReg(0);
68 LLT DstTy = MRI.getType(Dst);
70 if (!isConstantLegalOrBeforeLegalizer(DstTy))
71 return false;
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) {
80 if (Result)
81 B.buildConstant(Dst, getICmpTrueVal(getTargetLowering(),
82 /*IsVector=*/DstTy.isVector(),
83 /*IsFP=*/true));
84 else
85 B.buildConstant(Dst, 0);
88 return true;
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.
106 std::swap(LHS, RHS);
107 Pred = CmpInst::getSwappedPredicate(Pred);
109 MatchInfo = [=](MachineIRBuilder &B) { B.buildICmp(Pred, Dst, LHS, RHS); };
110 return true;
113 return false;
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.
132 std::swap(LHS, RHS);
133 Pred = CmpInst::getSwappedPredicate(Pred);
135 MatchInfo = [=](MachineIRBuilder &B) {
136 B.buildFCmp(Pred, Dst, LHS, RHS, Cmp->getFlags());
138 return true;
141 return false;