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