143 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements CombinerHelper for G_ICMP.10//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>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 {33 if (LHSCst.getKind() != GIConstant::GIConstantKind::Scalar)34 return false;35 36 Register Dst = ICmp.getReg(0);37 LLT DstTy = MRI.getType(Dst);38 39 if (!isConstantLegalOrBeforeLegalizer(DstTy))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 else54 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 {64 if (LHSCst.getKind() != GFConstant::GFConstantKind::Scalar)65 return false;66 67 Register Dst = FCmp.getReg(0);68 LLT DstTy = MRI.getType(Dst);69 70 if (!isConstantLegalOrBeforeLegalizer(DstTy))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 else85 B.buildConstant(Dst, 0);86 };87 88 return true;89}90 91bool CombinerHelper::matchCanonicalizeICmp(const MachineInstr &MI,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 116bool CombinerHelper::matchCanonicalizeFCmp(const MachineInstr &MI,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}143