xref: /llvm-project/llvm/lib/CodeGen/GlobalISel/CombinerHelperCompares.cpp (revision ee7ca0dddafb609090ad1789570c099d95c0afb6)
15c348f69SThorsten Schütt //===- CombinerHelperCompares.cpp------------------------------------------===//
25c348f69SThorsten Schütt //
35c348f69SThorsten Schütt // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45c348f69SThorsten Schütt // See https://llvm.org/LICENSE.txt for license information.
55c348f69SThorsten Schütt // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65c348f69SThorsten Schütt //
75c348f69SThorsten Schütt //===----------------------------------------------------------------------===//
85c348f69SThorsten Schütt //
95c348f69SThorsten Schütt // This file implements CombinerHelper for G_ICMP.
105c348f69SThorsten Schütt //
115c348f69SThorsten Schütt //===----------------------------------------------------------------------===//
125c348f69SThorsten Schütt #include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
135c348f69SThorsten Schütt #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
145c348f69SThorsten Schütt #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
155c348f69SThorsten Schütt #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
165c348f69SThorsten Schütt #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
175c348f69SThorsten Schütt #include "llvm/CodeGen/GlobalISel/Utils.h"
185c348f69SThorsten Schütt #include "llvm/CodeGen/MachineInstr.h"
195c348f69SThorsten Schütt #include "llvm/CodeGen/MachineOperand.h"
205c348f69SThorsten Schütt #include "llvm/CodeGen/MachineRegisterInfo.h"
215c348f69SThorsten Schütt #include "llvm/IR/Instructions.h"
225c348f69SThorsten Schütt #include "llvm/Support/Casting.h"
235c348f69SThorsten Schütt #include <cstdlib>
245c348f69SThorsten Schütt 
255c348f69SThorsten Schütt #define DEBUG_TYPE "gi-combiner"
265c348f69SThorsten Schütt 
275c348f69SThorsten Schütt using namespace llvm;
285c348f69SThorsten Schütt 
295c348f69SThorsten Schütt bool CombinerHelper::constantFoldICmp(const GICmp &ICmp,
305c348f69SThorsten Schütt                                       const GIConstant &LHSCst,
315c348f69SThorsten Schütt                                       const GIConstant &RHSCst,
32*ee7ca0ddSPaul Bowen-Huggett                                       BuildFnTy &MatchInfo) const {
335c348f69SThorsten Schütt   if (LHSCst.getKind() != GIConstant::GIConstantKind::Scalar)
345c348f69SThorsten Schütt     return false;
355c348f69SThorsten Schütt 
365c348f69SThorsten Schütt   Register Dst = ICmp.getReg(0);
375c348f69SThorsten Schütt   LLT DstTy = MRI.getType(Dst);
385c348f69SThorsten Schütt 
395c348f69SThorsten Schütt   if (!isConstantLegalOrBeforeLegalizer(DstTy))
405c348f69SThorsten Schütt     return false;
415c348f69SThorsten Schütt 
425c348f69SThorsten Schütt   CmpInst::Predicate Pred = ICmp.getCond();
435c348f69SThorsten Schütt   APInt LHS = LHSCst.getScalarValue();
445c348f69SThorsten Schütt   APInt RHS = RHSCst.getScalarValue();
455c348f69SThorsten Schütt 
465c348f69SThorsten Schütt   bool Result = ICmpInst::compare(LHS, RHS, Pred);
475c348f69SThorsten Schütt 
485c348f69SThorsten Schütt   MatchInfo = [=](MachineIRBuilder &B) {
495c348f69SThorsten Schütt     if (Result)
505c348f69SThorsten Schütt       B.buildConstant(Dst, getICmpTrueVal(getTargetLowering(),
515c348f69SThorsten Schütt                                           /*IsVector=*/DstTy.isVector(),
525c348f69SThorsten Schütt                                           /*IsFP=*/false));
535c348f69SThorsten Schütt     else
545c348f69SThorsten Schütt       B.buildConstant(Dst, 0);
555c348f69SThorsten Schütt   };
565c348f69SThorsten Schütt 
575c348f69SThorsten Schütt   return true;
585c348f69SThorsten Schütt }
595c348f69SThorsten Schütt 
60acfa294bSThorsten Schütt bool CombinerHelper::constantFoldFCmp(const GFCmp &FCmp,
61acfa294bSThorsten Schütt                                       const GFConstant &LHSCst,
62acfa294bSThorsten Schütt                                       const GFConstant &RHSCst,
63*ee7ca0ddSPaul Bowen-Huggett                                       BuildFnTy &MatchInfo) const {
64acfa294bSThorsten Schütt   if (LHSCst.getKind() != GFConstant::GFConstantKind::Scalar)
65acfa294bSThorsten Schütt     return false;
66acfa294bSThorsten Schütt 
67acfa294bSThorsten Schütt   Register Dst = FCmp.getReg(0);
68acfa294bSThorsten Schütt   LLT DstTy = MRI.getType(Dst);
69acfa294bSThorsten Schütt 
70acfa294bSThorsten Schütt   if (!isConstantLegalOrBeforeLegalizer(DstTy))
71acfa294bSThorsten Schütt     return false;
72acfa294bSThorsten Schütt 
73acfa294bSThorsten Schütt   CmpInst::Predicate Pred = FCmp.getCond();
74acfa294bSThorsten Schütt   APFloat LHS = LHSCst.getScalarValue();
75acfa294bSThorsten Schütt   APFloat RHS = RHSCst.getScalarValue();
76acfa294bSThorsten Schütt 
77acfa294bSThorsten Schütt   bool Result = FCmpInst::compare(LHS, RHS, Pred);
78acfa294bSThorsten Schütt 
79acfa294bSThorsten Schütt   MatchInfo = [=](MachineIRBuilder &B) {
80acfa294bSThorsten Schütt     if (Result)
81acfa294bSThorsten Schütt       B.buildConstant(Dst, getICmpTrueVal(getTargetLowering(),
82acfa294bSThorsten Schütt                                           /*IsVector=*/DstTy.isVector(),
83acfa294bSThorsten Schütt                                           /*IsFP=*/true));
84acfa294bSThorsten Schütt     else
85acfa294bSThorsten Schütt       B.buildConstant(Dst, 0);
86acfa294bSThorsten Schütt   };
87acfa294bSThorsten Schütt 
88acfa294bSThorsten Schütt   return true;
89acfa294bSThorsten Schütt }
90acfa294bSThorsten Schütt 
915c348f69SThorsten Schütt bool CombinerHelper::matchCanonicalizeICmp(const MachineInstr &MI,
92*ee7ca0ddSPaul Bowen-Huggett                                            BuildFnTy &MatchInfo) const {
935c348f69SThorsten Schütt   const GICmp *Cmp = cast<GICmp>(&MI);
945c348f69SThorsten Schütt 
955c348f69SThorsten Schütt   Register Dst = Cmp->getReg(0);
965c348f69SThorsten Schütt   Register LHS = Cmp->getLHSReg();
975c348f69SThorsten Schütt   Register RHS = Cmp->getRHSReg();
985c348f69SThorsten Schütt 
995c348f69SThorsten Schütt   CmpInst::Predicate Pred = Cmp->getCond();
1005c348f69SThorsten Schütt   assert(CmpInst::isIntPredicate(Pred) && "Not an integer compare!");
1015c348f69SThorsten Schütt   if (auto CLHS = GIConstant::getConstant(LHS, MRI)) {
1025c348f69SThorsten Schütt     if (auto CRHS = GIConstant::getConstant(RHS, MRI))
1035c348f69SThorsten Schütt       return constantFoldICmp(*Cmp, *CLHS, *CRHS, MatchInfo);
1045c348f69SThorsten Schütt 
1055c348f69SThorsten Schütt     // If we have a constant, make sure it is on the RHS.
1065c348f69SThorsten Schütt     std::swap(LHS, RHS);
1075c348f69SThorsten Schütt     Pred = CmpInst::getSwappedPredicate(Pred);
1085c348f69SThorsten Schütt 
1095c348f69SThorsten Schütt     MatchInfo = [=](MachineIRBuilder &B) { B.buildICmp(Pred, Dst, LHS, RHS); };
1105c348f69SThorsten Schütt     return true;
1115c348f69SThorsten Schütt   }
1125c348f69SThorsten Schütt 
1135c348f69SThorsten Schütt   return false;
1145c348f69SThorsten Schütt }
115acfa294bSThorsten Schütt 
116acfa294bSThorsten Schütt bool CombinerHelper::matchCanonicalizeFCmp(const MachineInstr &MI,
117*ee7ca0ddSPaul Bowen-Huggett                                            BuildFnTy &MatchInfo) const {
118acfa294bSThorsten Schütt   const GFCmp *Cmp = cast<GFCmp>(&MI);
119acfa294bSThorsten Schütt 
120acfa294bSThorsten Schütt   Register Dst = Cmp->getReg(0);
121acfa294bSThorsten Schütt   Register LHS = Cmp->getLHSReg();
122acfa294bSThorsten Schütt   Register RHS = Cmp->getRHSReg();
123acfa294bSThorsten Schütt 
124acfa294bSThorsten Schütt   CmpInst::Predicate Pred = Cmp->getCond();
125acfa294bSThorsten Schütt   assert(CmpInst::isFPPredicate(Pred) && "Not an FP compare!");
126acfa294bSThorsten Schütt 
127acfa294bSThorsten Schütt   if (auto CLHS = GFConstant::getConstant(LHS, MRI)) {
128acfa294bSThorsten Schütt     if (auto CRHS = GFConstant::getConstant(RHS, MRI))
129acfa294bSThorsten Schütt       return constantFoldFCmp(*Cmp, *CLHS, *CRHS, MatchInfo);
130acfa294bSThorsten Schütt 
131acfa294bSThorsten Schütt     // If we have a constant, make sure it is on the RHS.
132acfa294bSThorsten Schütt     std::swap(LHS, RHS);
133acfa294bSThorsten Schütt     Pred = CmpInst::getSwappedPredicate(Pred);
134acfa294bSThorsten Schütt 
135acfa294bSThorsten Schütt     MatchInfo = [=](MachineIRBuilder &B) {
136acfa294bSThorsten Schütt       B.buildFCmp(Pred, Dst, LHS, RHS, Cmp->getFlags());
137acfa294bSThorsten Schütt     };
138acfa294bSThorsten Schütt     return true;
139acfa294bSThorsten Schütt   }
140acfa294bSThorsten Schütt 
141acfa294bSThorsten Schütt   return false;
142acfa294bSThorsten Schütt }
143