brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.6 KiB · fc40533 Raw
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