1//===- NVPTXUtilities.cpp - Utility Functions -----------------------------===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains miscellaneous utility functions
10//
11//===----------------------------------------------------------------------===//
12
13#include "NVPTXUtilities.h"
14#include "NVPTX.h"
15#include "NVPTXTargetMachine.h"
16#include "NVVMProperties.h"
17#include "llvm/IR/DataLayout.h"
18#include "llvm/IR/Function.h"
19#include "llvm/Support/Alignment.h"
20#include "llvm/Support/CommandLine.h"
21#include <algorithm>
22
23namespace llvm {
24
25static cl::opt<bool> ForceMinByValParamAlign(
26 "nvptx-force-min-byval-param-align", cl::Hidden,
27 cl::desc("NVPTX Specific: force 4-byte minimal alignment for byval"
28 " params of device functions."),
29 cl::init(Val: false));
30
31Function *getMaybeBitcastedCallee(const CallBase *CB) {
32 return dyn_cast<Function>(Val: CB->getCalledOperand()->stripPointerCasts());
33}
34
35Align getFunctionParamOptimizedAlign(const Function *F, Type *ArgTy,
36 const DataLayout &DL) {
37 // Capping the alignment to 128 bytes as that is the maximum alignment
38 // supported by PTX.
39 const Align ABITypeAlign = std::min(a: Align(128), b: DL.getABITypeAlign(Ty: ArgTy));
40
41 // If a function has linkage different from internal or private, we
42 // must use default ABI alignment as external users rely on it. Same
43 // for a function that may be called from a function pointer.
44 if (!F || !F->hasLocalLinkage() ||
45 F->hasAddressTaken(/*Users=*/nullptr,
46 /*IgnoreCallbackUses=*/false,
47 /*IgnoreAssumeLikeCalls=*/true,
48 /*IgnoreLLVMUsed=*/IngoreLLVMUsed: true))
49 return ABITypeAlign;
50
51 assert(!isKernelFunction(*F) && "Expect kernels to have non-local linkage");
52 return std::max(a: Align(16), b: ABITypeAlign);
53}
54
55Align getFunctionArgumentAlignment(const Function *F, Type *Ty, unsigned Idx,
56 const DataLayout &DL) {
57 return getAlign(F: *F, Index: Idx).value_or(u: getFunctionParamOptimizedAlign(F, ArgTy: Ty, DL));
58}
59
60Align getFunctionByValParamAlign(const Function *F, Type *ArgTy,
61 Align InitialAlign, const DataLayout &DL) {
62 Align ArgAlign = InitialAlign;
63 if (F)
64 ArgAlign = std::max(a: ArgAlign, b: getFunctionParamOptimizedAlign(F, ArgTy, DL));
65
66 // Old ptx versions have a bug. When PTX code takes address of
67 // byval parameter with alignment < 4, ptxas generates code to
68 // spill argument into memory. Alas on sm_50+ ptxas generates
69 // SASS code that fails with misaligned access. To work around
70 // the problem, make sure that we align byval parameters by at
71 // least 4. This bug seems to be fixed at least starting from
72 // ptxas > 9.0.
73 // TODO: remove this after verifying the bug is not reproduced
74 // on non-deprecated ptxas versions.
75 if (ForceMinByValParamAlign)
76 ArgAlign = std::max(a: ArgAlign, b: Align(4));
77
78 return ArgAlign;
79}
80
81bool shouldEmitPTXNoReturn(const Value *V, const TargetMachine &TM) {
82 const auto &ST =
83 *static_cast<const NVPTXTargetMachine &>(TM).getSubtargetImpl();
84 if (!ST.hasNoReturn())
85 return false;
86
87 assert((isa<Function>(V) || isa<CallInst>(V)) &&
88 "Expect either a call instruction or a function");
89
90 if (const CallInst *CallI = dyn_cast<CallInst>(Val: V))
91 return CallI->doesNotReturn() &&
92 CallI->getFunctionType()->getReturnType()->isVoidTy();
93
94 const Function *F = cast<Function>(Val: V);
95 return F->doesNotReturn() &&
96 F->getFunctionType()->getReturnType()->isVoidTy() &&
97 !isKernelFunction(F: *F);
98}
99
100} // namespace llvm
101