//===-- SPIRVCombinerHelper.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "SPIRVCombinerHelper.h" #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h" #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" #include "llvm/IR/IntrinsicsSPIRV.h" #include "llvm/Target/TargetMachine.h" using namespace llvm; using namespace MIPatternMatch; SPIRVCombinerHelper::SPIRVCombinerHelper( GISelChangeObserver &Observer, MachineIRBuilder &B, bool IsPreLegalize, GISelValueTracking *VT, MachineDominatorTree *MDT, const LegalizerInfo *LI, const SPIRVSubtarget &STI) : CombinerHelper(Observer, B, IsPreLegalize, VT, MDT, LI), STI(STI) {} /// This match is part of a combine that /// rewrites length(X - Y) to distance(X, Y) /// (f32 (g_intrinsic length /// (g_fsub (vXf32 X) (vXf32 Y)))) /// -> /// (f32 (g_intrinsic distance /// (vXf32 X) (vXf32 Y))) /// bool SPIRVCombinerHelper::matchLengthToDistance(MachineInstr &MI) const { if (MI.getOpcode() != TargetOpcode::G_INTRINSIC || cast(MI).getIntrinsicID() != Intrinsic::spv_length) return false; // First operand of MI is `G_INTRINSIC` so start at operand 2. Register SubReg = MI.getOperand(2).getReg(); MachineInstr *SubInstr = MRI.getVRegDef(SubReg); if (SubInstr->getOpcode() != TargetOpcode::G_FSUB) return false; return true; } void SPIRVCombinerHelper::applySPIRVDistance(MachineInstr &MI) const { // Extract the operands for X and Y from the match criteria. Register SubDestReg = MI.getOperand(2).getReg(); MachineInstr *SubInstr = MRI.getVRegDef(SubDestReg); Register SubOperand1 = SubInstr->getOperand(1).getReg(); Register SubOperand2 = SubInstr->getOperand(2).getReg(); Register ResultReg = MI.getOperand(0).getReg(); Builder.setInstrAndDebugLoc(MI); Builder.buildIntrinsic(Intrinsic::spv_distance, ResultReg) .addUse(SubOperand1) .addUse(SubOperand2); MI.eraseFromParent(); }