12ca300f9SThorsten Schütt //===- CombinerHelperCasts.cpp---------------------------------------------===// 22ca300f9SThorsten Schütt // 32ca300f9SThorsten Schütt // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42ca300f9SThorsten Schütt // See https://llvm.org/LICENSE.txt for license information. 52ca300f9SThorsten Schütt // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 62ca300f9SThorsten Schütt // 72ca300f9SThorsten Schütt //===----------------------------------------------------------------------===// 82ca300f9SThorsten Schütt // 92ca300f9SThorsten Schütt // This file implements CombinerHelper for G_ANYEXT, G_SEXT, G_TRUNC, and 102ca300f9SThorsten Schütt // G_ZEXT 112ca300f9SThorsten Schütt // 122ca300f9SThorsten Schütt //===----------------------------------------------------------------------===// 132ca300f9SThorsten Schütt #include "llvm/CodeGen/GlobalISel/CombinerHelper.h" 142ca300f9SThorsten Schütt #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" 152ca300f9SThorsten Schütt #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 162ca300f9SThorsten Schütt #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 172ca300f9SThorsten Schütt #include "llvm/CodeGen/GlobalISel/Utils.h" 182ca300f9SThorsten Schütt #include "llvm/CodeGen/LowLevelTypeUtils.h" 192ca300f9SThorsten Schütt #include "llvm/CodeGen/MachineOperand.h" 202ca300f9SThorsten Schütt #include "llvm/CodeGen/MachineRegisterInfo.h" 212ca300f9SThorsten Schütt #include "llvm/CodeGen/TargetOpcodes.h" 222ca300f9SThorsten Schütt #include "llvm/Support/Casting.h" 232ca300f9SThorsten Schütt 242ca300f9SThorsten Schütt #define DEBUG_TYPE "gi-combiner" 252ca300f9SThorsten Schütt 262ca300f9SThorsten Schütt using namespace llvm; 272ca300f9SThorsten Schütt 282ca300f9SThorsten Schütt bool CombinerHelper::matchSextOfTrunc(const MachineOperand &MO, 29*ee7ca0ddSPaul Bowen-Huggett BuildFnTy &MatchInfo) const { 302ca300f9SThorsten Schütt GSext *Sext = cast<GSext>(getDefIgnoringCopies(MO.getReg(), MRI)); 312ca300f9SThorsten Schütt GTrunc *Trunc = cast<GTrunc>(getDefIgnoringCopies(Sext->getSrcReg(), MRI)); 322ca300f9SThorsten Schütt 332ca300f9SThorsten Schütt Register Dst = Sext->getReg(0); 342ca300f9SThorsten Schütt Register Src = Trunc->getSrcReg(); 352ca300f9SThorsten Schütt 362ca300f9SThorsten Schütt LLT DstTy = MRI.getType(Dst); 372ca300f9SThorsten Schütt LLT SrcTy = MRI.getType(Src); 382ca300f9SThorsten Schütt 392ca300f9SThorsten Schütt if (DstTy == SrcTy) { 402ca300f9SThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { B.buildCopy(Dst, Src); }; 412ca300f9SThorsten Schütt return true; 422ca300f9SThorsten Schütt } 432ca300f9SThorsten Schütt 442ca300f9SThorsten Schütt if (DstTy.getScalarSizeInBits() < SrcTy.getScalarSizeInBits() && 452ca300f9SThorsten Schütt isLegalOrBeforeLegalizer({TargetOpcode::G_TRUNC, {DstTy, SrcTy}})) { 462ca300f9SThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { 472ca300f9SThorsten Schütt B.buildTrunc(Dst, Src, MachineInstr::MIFlag::NoSWrap); 482ca300f9SThorsten Schütt }; 492ca300f9SThorsten Schütt return true; 502ca300f9SThorsten Schütt } 512ca300f9SThorsten Schütt 522ca300f9SThorsten Schütt if (DstTy.getScalarSizeInBits() > SrcTy.getScalarSizeInBits() && 532ca300f9SThorsten Schütt isLegalOrBeforeLegalizer({TargetOpcode::G_SEXT, {DstTy, SrcTy}})) { 542ca300f9SThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { B.buildSExt(Dst, Src); }; 552ca300f9SThorsten Schütt return true; 562ca300f9SThorsten Schütt } 572ca300f9SThorsten Schütt 582ca300f9SThorsten Schütt return false; 592ca300f9SThorsten Schütt } 602ca300f9SThorsten Schütt 612ca300f9SThorsten Schütt bool CombinerHelper::matchZextOfTrunc(const MachineOperand &MO, 62*ee7ca0ddSPaul Bowen-Huggett BuildFnTy &MatchInfo) const { 632ca300f9SThorsten Schütt GZext *Zext = cast<GZext>(getDefIgnoringCopies(MO.getReg(), MRI)); 642ca300f9SThorsten Schütt GTrunc *Trunc = cast<GTrunc>(getDefIgnoringCopies(Zext->getSrcReg(), MRI)); 652ca300f9SThorsten Schütt 662ca300f9SThorsten Schütt Register Dst = Zext->getReg(0); 672ca300f9SThorsten Schütt Register Src = Trunc->getSrcReg(); 682ca300f9SThorsten Schütt 692ca300f9SThorsten Schütt LLT DstTy = MRI.getType(Dst); 702ca300f9SThorsten Schütt LLT SrcTy = MRI.getType(Src); 712ca300f9SThorsten Schütt 722ca300f9SThorsten Schütt if (DstTy == SrcTy) { 732ca300f9SThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { B.buildCopy(Dst, Src); }; 742ca300f9SThorsten Schütt return true; 752ca300f9SThorsten Schütt } 762ca300f9SThorsten Schütt 772ca300f9SThorsten Schütt if (DstTy.getScalarSizeInBits() < SrcTy.getScalarSizeInBits() && 782ca300f9SThorsten Schütt isLegalOrBeforeLegalizer({TargetOpcode::G_TRUNC, {DstTy, SrcTy}})) { 792ca300f9SThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { 802ca300f9SThorsten Schütt B.buildTrunc(Dst, Src, MachineInstr::MIFlag::NoUWrap); 812ca300f9SThorsten Schütt }; 822ca300f9SThorsten Schütt return true; 832ca300f9SThorsten Schütt } 842ca300f9SThorsten Schütt 852ca300f9SThorsten Schütt if (DstTy.getScalarSizeInBits() > SrcTy.getScalarSizeInBits() && 862ca300f9SThorsten Schütt isLegalOrBeforeLegalizer({TargetOpcode::G_ZEXT, {DstTy, SrcTy}})) { 872ca300f9SThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { 882ca300f9SThorsten Schütt B.buildZExt(Dst, Src, MachineInstr::MIFlag::NonNeg); 892ca300f9SThorsten Schütt }; 902ca300f9SThorsten Schütt return true; 912ca300f9SThorsten Schütt } 922ca300f9SThorsten Schütt 932ca300f9SThorsten Schütt return false; 942ca300f9SThorsten Schütt } 952ca300f9SThorsten Schütt 962ca300f9SThorsten Schütt bool CombinerHelper::matchNonNegZext(const MachineOperand &MO, 97*ee7ca0ddSPaul Bowen-Huggett BuildFnTy &MatchInfo) const { 982ca300f9SThorsten Schütt GZext *Zext = cast<GZext>(MRI.getVRegDef(MO.getReg())); 992ca300f9SThorsten Schütt 1002ca300f9SThorsten Schütt Register Dst = Zext->getReg(0); 1012ca300f9SThorsten Schütt Register Src = Zext->getSrcReg(); 1022ca300f9SThorsten Schütt 1032ca300f9SThorsten Schütt LLT DstTy = MRI.getType(Dst); 1042ca300f9SThorsten Schütt LLT SrcTy = MRI.getType(Src); 1052ca300f9SThorsten Schütt const auto &TLI = getTargetLowering(); 1062ca300f9SThorsten Schütt 1072ca300f9SThorsten Schütt // Convert zext nneg to sext if sext is the preferred form for the target. 1082ca300f9SThorsten Schütt if (isLegalOrBeforeLegalizer({TargetOpcode::G_SEXT, {DstTy, SrcTy}}) && 1092ca300f9SThorsten Schütt TLI.isSExtCheaperThanZExt(getMVTForLLT(SrcTy), getMVTForLLT(DstTy))) { 1102ca300f9SThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { B.buildSExt(Dst, Src); }; 1112ca300f9SThorsten Schütt return true; 1122ca300f9SThorsten Schütt } 1132ca300f9SThorsten Schütt 1142ca300f9SThorsten Schütt return false; 1152ca300f9SThorsten Schütt } 116bfcfb0fdSThorsten Schütt 117bfcfb0fdSThorsten Schütt bool CombinerHelper::matchTruncateOfExt(const MachineInstr &Root, 118bfcfb0fdSThorsten Schütt const MachineInstr &ExtMI, 119*ee7ca0ddSPaul Bowen-Huggett BuildFnTy &MatchInfo) const { 120bfcfb0fdSThorsten Schütt const GTrunc *Trunc = cast<GTrunc>(&Root); 121bfcfb0fdSThorsten Schütt const GExtOp *Ext = cast<GExtOp>(&ExtMI); 122bfcfb0fdSThorsten Schütt 123bfcfb0fdSThorsten Schütt if (!MRI.hasOneNonDBGUse(Ext->getReg(0))) 124bfcfb0fdSThorsten Schütt return false; 125bfcfb0fdSThorsten Schütt 126bfcfb0fdSThorsten Schütt Register Dst = Trunc->getReg(0); 127bfcfb0fdSThorsten Schütt Register Src = Ext->getSrcReg(); 128bfcfb0fdSThorsten Schütt LLT DstTy = MRI.getType(Dst); 129bfcfb0fdSThorsten Schütt LLT SrcTy = MRI.getType(Src); 130bfcfb0fdSThorsten Schütt 131bfcfb0fdSThorsten Schütt if (SrcTy == DstTy) { 132bfcfb0fdSThorsten Schütt // The source and the destination are equally sized. We need to copy. 133bfcfb0fdSThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { B.buildCopy(Dst, Src); }; 134bfcfb0fdSThorsten Schütt 135bfcfb0fdSThorsten Schütt return true; 136bfcfb0fdSThorsten Schütt } 137bfcfb0fdSThorsten Schütt 138bfcfb0fdSThorsten Schütt if (SrcTy.getScalarSizeInBits() < DstTy.getScalarSizeInBits()) { 139bfcfb0fdSThorsten Schütt // If the source is smaller than the destination, we need to extend. 140bfcfb0fdSThorsten Schütt 141bfcfb0fdSThorsten Schütt if (!isLegalOrBeforeLegalizer({Ext->getOpcode(), {DstTy, SrcTy}})) 142bfcfb0fdSThorsten Schütt return false; 143bfcfb0fdSThorsten Schütt 144bfcfb0fdSThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { 145bfcfb0fdSThorsten Schütt B.buildInstr(Ext->getOpcode(), {Dst}, {Src}); 146bfcfb0fdSThorsten Schütt }; 147bfcfb0fdSThorsten Schütt 148bfcfb0fdSThorsten Schütt return true; 149bfcfb0fdSThorsten Schütt } 150bfcfb0fdSThorsten Schütt 151bfcfb0fdSThorsten Schütt if (SrcTy.getScalarSizeInBits() > DstTy.getScalarSizeInBits()) { 152bfcfb0fdSThorsten Schütt // If the source is larger than the destination, then we need to truncate. 153bfcfb0fdSThorsten Schütt 154bfcfb0fdSThorsten Schütt if (!isLegalOrBeforeLegalizer({TargetOpcode::G_TRUNC, {DstTy, SrcTy}})) 155bfcfb0fdSThorsten Schütt return false; 156bfcfb0fdSThorsten Schütt 157bfcfb0fdSThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { B.buildTrunc(Dst, Src); }; 158bfcfb0fdSThorsten Schütt 159bfcfb0fdSThorsten Schütt return true; 160bfcfb0fdSThorsten Schütt } 161bfcfb0fdSThorsten Schütt 162bfcfb0fdSThorsten Schütt return false; 163bfcfb0fdSThorsten Schütt } 164db8c84fcSThorsten Schütt 165db8c84fcSThorsten Schütt bool CombinerHelper::isCastFree(unsigned Opcode, LLT ToTy, LLT FromTy) const { 166db8c84fcSThorsten Schütt const TargetLowering &TLI = getTargetLowering(); 167db8c84fcSThorsten Schütt LLVMContext &Ctx = getContext(); 168db8c84fcSThorsten Schütt 169db8c84fcSThorsten Schütt switch (Opcode) { 170db8c84fcSThorsten Schütt case TargetOpcode::G_ANYEXT: 171db8c84fcSThorsten Schütt case TargetOpcode::G_ZEXT: 1720d9fc174SCraig Topper return TLI.isZExtFree(FromTy, ToTy, Ctx); 173db8c84fcSThorsten Schütt case TargetOpcode::G_TRUNC: 1740d9fc174SCraig Topper return TLI.isTruncateFree(FromTy, ToTy, Ctx); 175db8c84fcSThorsten Schütt default: 176db8c84fcSThorsten Schütt return false; 177db8c84fcSThorsten Schütt } 178db8c84fcSThorsten Schütt } 179db8c84fcSThorsten Schütt 180db8c84fcSThorsten Schütt bool CombinerHelper::matchCastOfSelect(const MachineInstr &CastMI, 181db8c84fcSThorsten Schütt const MachineInstr &SelectMI, 182*ee7ca0ddSPaul Bowen-Huggett BuildFnTy &MatchInfo) const { 183db8c84fcSThorsten Schütt const GExtOrTruncOp *Cast = cast<GExtOrTruncOp>(&CastMI); 184db8c84fcSThorsten Schütt const GSelect *Select = cast<GSelect>(&SelectMI); 185db8c84fcSThorsten Schütt 186db8c84fcSThorsten Schütt if (!MRI.hasOneNonDBGUse(Select->getReg(0))) 187db8c84fcSThorsten Schütt return false; 188db8c84fcSThorsten Schütt 189db8c84fcSThorsten Schütt Register Dst = Cast->getReg(0); 190db8c84fcSThorsten Schütt LLT DstTy = MRI.getType(Dst); 191db8c84fcSThorsten Schütt LLT CondTy = MRI.getType(Select->getCondReg()); 192db8c84fcSThorsten Schütt Register TrueReg = Select->getTrueReg(); 193db8c84fcSThorsten Schütt Register FalseReg = Select->getFalseReg(); 194db8c84fcSThorsten Schütt LLT SrcTy = MRI.getType(TrueReg); 195db8c84fcSThorsten Schütt Register Cond = Select->getCondReg(); 196db8c84fcSThorsten Schütt 197db8c84fcSThorsten Schütt if (!isLegalOrBeforeLegalizer({TargetOpcode::G_SELECT, {DstTy, CondTy}})) 198db8c84fcSThorsten Schütt return false; 199db8c84fcSThorsten Schütt 200db8c84fcSThorsten Schütt if (!isCastFree(Cast->getOpcode(), DstTy, SrcTy)) 201db8c84fcSThorsten Schütt return false; 202db8c84fcSThorsten Schütt 203db8c84fcSThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { 204db8c84fcSThorsten Schütt auto True = B.buildInstr(Cast->getOpcode(), {DstTy}, {TrueReg}); 205db8c84fcSThorsten Schütt auto False = B.buildInstr(Cast->getOpcode(), {DstTy}, {FalseReg}); 206db8c84fcSThorsten Schütt B.buildSelect(Dst, Cond, True, False); 207db8c84fcSThorsten Schütt }; 208db8c84fcSThorsten Schütt 209db8c84fcSThorsten Schütt return true; 210db8c84fcSThorsten Schütt } 211710a552dSThorsten Schütt 212710a552dSThorsten Schütt bool CombinerHelper::matchExtOfExt(const MachineInstr &FirstMI, 213710a552dSThorsten Schütt const MachineInstr &SecondMI, 214*ee7ca0ddSPaul Bowen-Huggett BuildFnTy &MatchInfo) const { 215710a552dSThorsten Schütt const GExtOp *First = cast<GExtOp>(&FirstMI); 216710a552dSThorsten Schütt const GExtOp *Second = cast<GExtOp>(&SecondMI); 217710a552dSThorsten Schütt 218710a552dSThorsten Schütt Register Dst = First->getReg(0); 219710a552dSThorsten Schütt Register Src = Second->getSrcReg(); 220710a552dSThorsten Schütt LLT DstTy = MRI.getType(Dst); 221710a552dSThorsten Schütt LLT SrcTy = MRI.getType(Src); 222710a552dSThorsten Schütt 223710a552dSThorsten Schütt if (!MRI.hasOneNonDBGUse(Second->getReg(0))) 224710a552dSThorsten Schütt return false; 225710a552dSThorsten Schütt 226710a552dSThorsten Schütt // ext of ext -> later ext 227710a552dSThorsten Schütt if (First->getOpcode() == Second->getOpcode() && 228710a552dSThorsten Schütt isLegalOrBeforeLegalizer({Second->getOpcode(), {DstTy, SrcTy}})) { 229710a552dSThorsten Schütt if (Second->getOpcode() == TargetOpcode::G_ZEXT) { 230710a552dSThorsten Schütt MachineInstr::MIFlag Flag = MachineInstr::MIFlag::NoFlags; 231710a552dSThorsten Schütt if (Second->getFlag(MachineInstr::MIFlag::NonNeg)) 232710a552dSThorsten Schütt Flag = MachineInstr::MIFlag::NonNeg; 233710a552dSThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { B.buildZExt(Dst, Src, Flag); }; 234710a552dSThorsten Schütt return true; 235710a552dSThorsten Schütt } 236710a552dSThorsten Schütt // not zext -> no flags 237710a552dSThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { 238710a552dSThorsten Schütt B.buildInstr(Second->getOpcode(), {Dst}, {Src}); 239710a552dSThorsten Schütt }; 240710a552dSThorsten Schütt return true; 241710a552dSThorsten Schütt } 242710a552dSThorsten Schütt 243710a552dSThorsten Schütt // anyext of sext/zext -> sext/zext 244710a552dSThorsten Schütt // -> pick anyext as second ext, then ext of ext 245710a552dSThorsten Schütt if (First->getOpcode() == TargetOpcode::G_ANYEXT && 246710a552dSThorsten Schütt isLegalOrBeforeLegalizer({Second->getOpcode(), {DstTy, SrcTy}})) { 247710a552dSThorsten Schütt if (Second->getOpcode() == TargetOpcode::G_ZEXT) { 248710a552dSThorsten Schütt MachineInstr::MIFlag Flag = MachineInstr::MIFlag::NoFlags; 249710a552dSThorsten Schütt if (Second->getFlag(MachineInstr::MIFlag::NonNeg)) 250710a552dSThorsten Schütt Flag = MachineInstr::MIFlag::NonNeg; 251710a552dSThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { B.buildZExt(Dst, Src, Flag); }; 252710a552dSThorsten Schütt return true; 253710a552dSThorsten Schütt } 254710a552dSThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { B.buildSExt(Dst, Src); }; 255710a552dSThorsten Schütt return true; 256710a552dSThorsten Schütt } 257710a552dSThorsten Schütt 258710a552dSThorsten Schütt // sext/zext of anyext -> sext/zext 259710a552dSThorsten Schütt // -> pick anyext as first ext, then ext of ext 260710a552dSThorsten Schütt if (Second->getOpcode() == TargetOpcode::G_ANYEXT && 261710a552dSThorsten Schütt isLegalOrBeforeLegalizer({First->getOpcode(), {DstTy, SrcTy}})) { 262710a552dSThorsten Schütt if (First->getOpcode() == TargetOpcode::G_ZEXT) { 263710a552dSThorsten Schütt MachineInstr::MIFlag Flag = MachineInstr::MIFlag::NoFlags; 264710a552dSThorsten Schütt if (First->getFlag(MachineInstr::MIFlag::NonNeg)) 265710a552dSThorsten Schütt Flag = MachineInstr::MIFlag::NonNeg; 266710a552dSThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { B.buildZExt(Dst, Src, Flag); }; 267710a552dSThorsten Schütt return true; 268710a552dSThorsten Schütt } 269710a552dSThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { B.buildSExt(Dst, Src); }; 270710a552dSThorsten Schütt return true; 271710a552dSThorsten Schütt } 272710a552dSThorsten Schütt 273710a552dSThorsten Schütt return false; 274710a552dSThorsten Schütt } 2750b0ccd56SThorsten Schütt 2760b0ccd56SThorsten Schütt bool CombinerHelper::matchCastOfBuildVector(const MachineInstr &CastMI, 2770b0ccd56SThorsten Schütt const MachineInstr &BVMI, 278*ee7ca0ddSPaul Bowen-Huggett BuildFnTy &MatchInfo) const { 2790b0ccd56SThorsten Schütt const GExtOrTruncOp *Cast = cast<GExtOrTruncOp>(&CastMI); 2800b0ccd56SThorsten Schütt const GBuildVector *BV = cast<GBuildVector>(&BVMI); 2810b0ccd56SThorsten Schütt 2820b0ccd56SThorsten Schütt if (!MRI.hasOneNonDBGUse(BV->getReg(0))) 2830b0ccd56SThorsten Schütt return false; 2840b0ccd56SThorsten Schütt 2850b0ccd56SThorsten Schütt Register Dst = Cast->getReg(0); 2860b0ccd56SThorsten Schütt // The type of the new build vector. 2870b0ccd56SThorsten Schütt LLT DstTy = MRI.getType(Dst); 2880b0ccd56SThorsten Schütt // The scalar or element type of the new build vector. 2890b0ccd56SThorsten Schütt LLT ElemTy = DstTy.getScalarType(); 2900b0ccd56SThorsten Schütt // The scalar or element type of the old build vector. 2910b0ccd56SThorsten Schütt LLT InputElemTy = MRI.getType(BV->getReg(0)).getElementType(); 2920b0ccd56SThorsten Schütt 2930b0ccd56SThorsten Schütt // Check legality of new build vector, the scalar casts, and profitability of 2940b0ccd56SThorsten Schütt // the many casts. 2950b0ccd56SThorsten Schütt if (!isLegalOrBeforeLegalizer( 2960b0ccd56SThorsten Schütt {TargetOpcode::G_BUILD_VECTOR, {DstTy, ElemTy}}) || 2970b0ccd56SThorsten Schütt !isLegalOrBeforeLegalizer({Cast->getOpcode(), {ElemTy, InputElemTy}}) || 2980b0ccd56SThorsten Schütt !isCastFree(Cast->getOpcode(), ElemTy, InputElemTy)) 2990b0ccd56SThorsten Schütt return false; 3000b0ccd56SThorsten Schütt 3010b0ccd56SThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { 3020b0ccd56SThorsten Schütt SmallVector<Register> Casts; 3030b0ccd56SThorsten Schütt unsigned Elements = BV->getNumSources(); 3040b0ccd56SThorsten Schütt for (unsigned I = 0; I < Elements; ++I) { 3050b0ccd56SThorsten Schütt auto CastI = 3060b0ccd56SThorsten Schütt B.buildInstr(Cast->getOpcode(), {ElemTy}, {BV->getSourceReg(I)}); 3070b0ccd56SThorsten Schütt Casts.push_back(CastI.getReg(0)); 3080b0ccd56SThorsten Schütt } 3090b0ccd56SThorsten Schütt 3100b0ccd56SThorsten Schütt B.buildBuildVector(Dst, Casts); 3110b0ccd56SThorsten Schütt }; 3120b0ccd56SThorsten Schütt 3130b0ccd56SThorsten Schütt return true; 3140b0ccd56SThorsten Schütt } 315ba4bcce5SThorsten Schütt 316ba4bcce5SThorsten Schütt bool CombinerHelper::matchNarrowBinop(const MachineInstr &TruncMI, 317ba4bcce5SThorsten Schütt const MachineInstr &BinopMI, 318*ee7ca0ddSPaul Bowen-Huggett BuildFnTy &MatchInfo) const { 319ba4bcce5SThorsten Schütt const GTrunc *Trunc = cast<GTrunc>(&TruncMI); 320ba4bcce5SThorsten Schütt const GBinOp *BinOp = cast<GBinOp>(&BinopMI); 321ba4bcce5SThorsten Schütt 322ba4bcce5SThorsten Schütt if (!MRI.hasOneNonDBGUse(BinOp->getReg(0))) 323ba4bcce5SThorsten Schütt return false; 324ba4bcce5SThorsten Schütt 325ba4bcce5SThorsten Schütt Register Dst = Trunc->getReg(0); 326ba4bcce5SThorsten Schütt LLT DstTy = MRI.getType(Dst); 327ba4bcce5SThorsten Schütt 328ba4bcce5SThorsten Schütt // Is narrow binop legal? 329ba4bcce5SThorsten Schütt if (!isLegalOrBeforeLegalizer({BinOp->getOpcode(), {DstTy}})) 330ba4bcce5SThorsten Schütt return false; 331ba4bcce5SThorsten Schütt 332ba4bcce5SThorsten Schütt MatchInfo = [=](MachineIRBuilder &B) { 333ba4bcce5SThorsten Schütt auto LHS = B.buildTrunc(DstTy, BinOp->getLHSReg()); 334ba4bcce5SThorsten Schütt auto RHS = B.buildTrunc(DstTy, BinOp->getRHSReg()); 335ba4bcce5SThorsten Schütt B.buildInstr(BinOp->getOpcode(), {Dst}, {LHS, RHS}); 336ba4bcce5SThorsten Schütt }; 337ba4bcce5SThorsten Schütt 338ba4bcce5SThorsten Schütt return true; 339ba4bcce5SThorsten Schütt } 340ba4bcce5SThorsten Schütt 341ba4bcce5SThorsten Schütt bool CombinerHelper::matchCastOfInteger(const MachineInstr &CastMI, 342*ee7ca0ddSPaul Bowen-Huggett APInt &MatchInfo) const { 343ba4bcce5SThorsten Schütt const GExtOrTruncOp *Cast = cast<GExtOrTruncOp>(&CastMI); 344ba4bcce5SThorsten Schütt 345ba4bcce5SThorsten Schütt APInt Input = getIConstantFromReg(Cast->getSrcReg(), MRI); 346ba4bcce5SThorsten Schütt 347ba4bcce5SThorsten Schütt LLT DstTy = MRI.getType(Cast->getReg(0)); 348ba4bcce5SThorsten Schütt 349ba4bcce5SThorsten Schütt if (!isConstantLegalOrBeforeLegalizer(DstTy)) 350ba4bcce5SThorsten Schütt return false; 351ba4bcce5SThorsten Schütt 352ba4bcce5SThorsten Schütt switch (Cast->getOpcode()) { 353ba4bcce5SThorsten Schütt case TargetOpcode::G_TRUNC: { 354ba4bcce5SThorsten Schütt MatchInfo = Input.trunc(DstTy.getScalarSizeInBits()); 355ba4bcce5SThorsten Schütt return true; 356ba4bcce5SThorsten Schütt } 357ba4bcce5SThorsten Schütt default: 358ba4bcce5SThorsten Schütt return false; 359ba4bcce5SThorsten Schütt } 360ba4bcce5SThorsten Schütt } 361