| //===- SPIRVISelLowering.cpp - SPIR-V DAG Lowering Impl ---------*- C++ -*-===// |
| // |
| // 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 |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file implements the SPIRVTargetLowering class. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "SPIRVISelLowering.h" |
| #include "SPIRV.h" |
| #include "llvm/IR/IntrinsicsSPIRV.h" |
| |
| #define DEBUG_TYPE "spirv-lower" |
| |
| using namespace llvm; |
| |
| unsigned SPIRVTargetLowering::getNumRegistersForCallingConv( |
| LLVMContext &Context, CallingConv::ID CC, EVT VT) const { |
| // This code avoids CallLowering fail inside getVectorTypeBreakdown |
| // on v3i1 arguments. Maybe we need to return 1 for all types. |
| // TODO: remove it once this case is supported by the default implementation. |
| if (VT.isVector() && VT.getVectorNumElements() == 3 && |
| (VT.getVectorElementType() == MVT::i1 || |
| VT.getVectorElementType() == MVT::i8)) |
| return 1; |
| return getNumRegisters(Context, VT); |
| } |
| |
| MVT SPIRVTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context, |
| CallingConv::ID CC, |
| EVT VT) const { |
| // This code avoids CallLowering fail inside getVectorTypeBreakdown |
| // on v3i1 arguments. Maybe we need to return i32 for all types. |
| // TODO: remove it once this case is supported by the default implementation. |
| if (VT.isVector() && VT.getVectorNumElements() == 3) { |
| if (VT.getVectorElementType() == MVT::i1) |
| return MVT::v4i1; |
| else if (VT.getVectorElementType() == MVT::i8) |
| return MVT::v4i8; |
| } |
| return getRegisterType(Context, VT); |
| } |
| |
| bool SPIRVTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info, |
| const CallInst &I, |
| MachineFunction &MF, |
| unsigned Intrinsic) const { |
| unsigned AlignIdx = 3; |
| switch (Intrinsic) { |
| case Intrinsic::spv_load: |
| AlignIdx = 2; |
| LLVM_FALLTHROUGH; |
| case Intrinsic::spv_store: { |
| if (I.getNumOperands() >= AlignIdx + 1) { |
| auto *AlignOp = cast<ConstantInt>(I.getOperand(AlignIdx)); |
| Info.align = Align(AlignOp->getZExtValue()); |
| } |
| Info.flags = static_cast<MachineMemOperand::Flags>( |
| cast<ConstantInt>(I.getOperand(AlignIdx - 1))->getZExtValue()); |
| Info.memVT = MVT::i64; |
| // TODO: take into account opaque pointers (don't use getElementType). |
| // MVT::getVT(PtrTy->getElementType()); |
| return true; |
| break; |
| } |
| default: |
| break; |
| } |
| return false; |
| } |