Skip to content

Commit

Permalink
[AMDGPU] Runtime metadata fixes:
Browse files Browse the repository at this point in the history
  - Verify that runtime metadata is actually valid runtime metadata when assembling, otherwise we could accept the following when assembling, but ocl runtime will reject it:
    .amdgpu_runtime_metadata
    { amd.MDVersion: [ 2, 1 ], amd.RandomUnknownKey, amd.IsaInfo: ...
  - Make IsaInfo optional, and always emit it.

Differential Revision: https://reviews.llvm.org/D30349


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296324 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
kzhuravl committed Feb 27, 2017
1 parent f54e7aa commit 9995ddd
Show file tree
Hide file tree
Showing 10 changed files with 270 additions and 74 deletions.
23 changes: 14 additions & 9 deletions lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -789,20 +789,20 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
: MCTargetAsmParser(Options, STI), MII(MII), Parser(_Parser) {
MCAsmParserExtension::Initialize(Parser);

if (getSTI().getFeatureBits().none()) {
if (getFeatureBits().none()) {
// Set default features.
copySTI().ToggleFeature("SOUTHERN_ISLANDS");
}

setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));

{
// TODO: make those pre-defined variables read-only.
// Currently there is none suitable machinery in the core llvm-mc for this.
// MCSymbol::isRedefinable is intended for another purpose, and
// AsmParser::parseDirectiveSet() cannot be specialized for specific target.
AMDGPU::IsaInfo::IsaVersion ISA =
AMDGPU::IsaInfo::getIsaVersion(getSTI().getFeatureBits());
AMDGPU::IsaInfo::getIsaVersion(getFeatureBits());
MCContext &Ctx = getContext();
MCSymbol *Sym =
Ctx.getOrCreateSymbol(Twine(".option.machine_version_major"));
Expand All @@ -828,7 +828,7 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
}

bool hasInv2PiInlineImm() const {
return getSTI().getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
}

bool hasSGPR102_SGPR103() const {
Expand All @@ -850,6 +850,10 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
return &MII;
}

const FeatureBitset &getFeatureBits() const {
return getSTI().getFeatureBits();
}

void setForcedEncodingSize(unsigned Size) { ForcedEncodingSize = Size; }
void setForcedDPP(bool ForceDPP_) { ForcedDPP = ForceDPP_; }
void setForcedSDWA(bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
Expand Down Expand Up @@ -1870,7 +1874,7 @@ bool AMDGPUAsmParser::ParseDirectiveHSACodeObjectISA() {
// targeted GPU.
if (getLexer().is(AsmToken::EndOfStatement)) {
AMDGPU::IsaInfo::IsaVersion ISA =
AMDGPU::IsaInfo::getIsaVersion(getSTI().getFeatureBits());
AMDGPU::IsaInfo::getIsaVersion(getFeatureBits());
getTargetStreamer().EmitDirectiveHSACodeObjectISA(ISA.Major, ISA.Minor,
ISA.Stepping,
"AMD", "AMDGPU");
Expand Down Expand Up @@ -1947,7 +1951,8 @@ bool AMDGPUAsmParser::ParseDirectiveRuntimeMetadata() {

MS.flush();

getTargetStreamer().EmitRuntimeMetadata(Metadata);
if (getTargetStreamer().EmitRuntimeMetadata(getFeatureBits(), Metadata))
return Error(getParser().getTok().getLoc(), "invalid runtime metadata");

return false;
}
Expand All @@ -1965,7 +1970,7 @@ bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef ID,

bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
amd_kernel_code_t Header;
AMDGPU::initDefaultAMDKernelCodeT(Header, getSTI().getFeatureBits());
AMDGPU::initDefaultAMDKernelCodeT(Header, getFeatureBits());

while (true) {
// Lex EndOfStatement. This is in a while loop, because lexing a comment
Expand Down Expand Up @@ -2459,7 +2464,7 @@ bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
Parser.Lex();

AMDGPU::IsaInfo::IsaVersion ISA =
AMDGPU::IsaInfo::getIsaVersion(getSTI().getFeatureBits());
AMDGPU::IsaInfo::getIsaVersion(getFeatureBits());
if (CntName == "vmcnt")
IntVal = encodeVmcnt(ISA, IntVal, CntVal);
else if (CntName == "expcnt")
Expand All @@ -2475,7 +2480,7 @@ bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
OperandMatchResultTy
AMDGPUAsmParser::parseSWaitCntOps(OperandVector &Operands) {
AMDGPU::IsaInfo::IsaVersion ISA =
AMDGPU::IsaInfo::getIsaVersion(getSTI().getFeatureBits());
AMDGPU::IsaInfo::getIsaVersion(getFeatureBits());
int64_t Waitcnt = getWaitcntBitMask(ISA);
SMLoc S = Parser.getTok().getLoc();

Expand Down
45 changes: 31 additions & 14 deletions lib/Target/AMDGPU/MCTargetDesc/AMDGPURuntimeMD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <vector>

using namespace llvm;
using namespace llvm::AMDGPU::IsaInfo;
using namespace ::AMDGPU::RuntimeMD;

static cl::opt<bool>
Expand Down Expand Up @@ -88,7 +89,7 @@ template <> struct MappingTraits<Kernel::Metadata> {
INVALID_KERNEL_INDEX);
YamlIO.mapOptional(KeyName::NoPartialWorkGroups, K.NoPartialWorkGroups,
uint8_t(0));
YamlIO.mapRequired(KeyName::Args, K.Args);
YamlIO.mapOptional(KeyName::Args, K.Args);
}
static const bool flow = true;
};
Expand Down Expand Up @@ -116,7 +117,7 @@ template <> struct MappingTraits<IsaInfo::Metadata> {
template <> struct MappingTraits<Program::Metadata> {
static void mapping(IO &YamlIO, Program::Metadata &Prog) {
YamlIO.mapRequired(KeyName::MDVersion, Prog.MDVersionSeq);
YamlIO.mapRequired(KeyName::IsaInfo, Prog.IsaInfo);
YamlIO.mapOptional(KeyName::IsaInfo, Prog.IsaInfo);
YamlIO.mapOptional(KeyName::PrintfInfo, Prog.PrintfInfo);
YamlIO.mapOptional(KeyName::Kernels, Prog.Kernels);
}
Expand Down Expand Up @@ -375,6 +376,20 @@ static Kernel::Metadata getRuntimeMDForKernel(const Function &F) {
return Kernel;
}

static void getIsaInfo(const FeatureBitset &Features, IsaInfo::Metadata &IIM) {
IIM.WavefrontSize = getWavefrontSize(Features);
IIM.LocalMemorySize = getLocalMemorySize(Features);
IIM.EUsPerCU = getEUsPerCU(Features);
IIM.MaxWavesPerEU = getMaxWavesPerEU(Features);
IIM.MaxFlatWorkGroupSize = getMaxFlatWorkGroupSize(Features);
IIM.SGPRAllocGranule = getSGPRAllocGranule(Features);
IIM.TotalNumSGPRs = getTotalNumSGPRs(Features);
IIM.AddressableNumSGPRs = getAddressableNumSGPRs(Features);
IIM.VGPRAllocGranule = getVGPRAllocGranule(Features);
IIM.TotalNumVGPRs = getTotalNumVGPRs(Features);
IIM.AddressableNumVGPRs = getAddressableNumVGPRs(Features);
}

Program::Metadata::Metadata(const std::string &YAML) {
yaml::Input Input(YAML);
Input >> *this;
Expand Down Expand Up @@ -411,18 +426,7 @@ std::string llvm::getRuntimeMDYAMLString(const FeatureBitset &Features,
Prog.MDVersionSeq.push_back(MDVersion);
Prog.MDVersionSeq.push_back(MDRevision);

IsaInfo::Metadata &IIM = Prog.IsaInfo;
IIM.WavefrontSize = AMDGPU::IsaInfo::getWavefrontSize(Features);
IIM.LocalMemorySize = AMDGPU::IsaInfo::getLocalMemorySize(Features);
IIM.EUsPerCU = AMDGPU::IsaInfo::getEUsPerCU(Features);
IIM.MaxWavesPerEU = AMDGPU::IsaInfo::getMaxWavesPerEU(Features);
IIM.MaxFlatWorkGroupSize = AMDGPU::IsaInfo::getMaxFlatWorkGroupSize(Features);
IIM.SGPRAllocGranule = AMDGPU::IsaInfo::getSGPRAllocGranule(Features);
IIM.TotalNumSGPRs = AMDGPU::IsaInfo::getTotalNumSGPRs(Features);
IIM.AddressableNumSGPRs = AMDGPU::IsaInfo::getAddressableNumSGPRs(Features);
IIM.VGPRAllocGranule = AMDGPU::IsaInfo::getVGPRAllocGranule(Features);
IIM.TotalNumVGPRs = AMDGPU::IsaInfo::getTotalNumVGPRs(Features);
IIM.AddressableNumVGPRs = AMDGPU::IsaInfo::getAddressableNumVGPRs(Features);
getIsaInfo(Features, Prog.IsaInfo);

// Set PrintfInfo.
if (auto MD = M.getNamedMetadata("llvm.printf.fmts")) {
Expand Down Expand Up @@ -451,3 +455,16 @@ std::string llvm::getRuntimeMDYAMLString(const FeatureBitset &Features,

return YAML;
}

ErrorOr<std::string> llvm::getRuntimeMDYAMLString(const FeatureBitset &Features,
StringRef YAML) {
Program::Metadata Prog;
yaml::Input Input(YAML);
Input >> Prog;

getIsaInfo(Features, Prog.IsaInfo);

if (Input.error())
return Input.error();
return Prog.toYAML();
}
7 changes: 6 additions & 1 deletion lib/Target/AMDGPU/MCTargetDesc/AMDGPURuntimeMD.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,20 @@
#ifndef LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPURUNTIMEMD_H
#define LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPURUNTIMEMD_H

#include "llvm/Support/ErrorOr.h"
#include <string>

namespace llvm {
class FeatureBitset;
class Module;

// Get runtime metadata as YAML string.
/// \returns Runtime metadata as YAML string.
std::string getRuntimeMDYAMLString(const FeatureBitset &Features,
const Module &M);

/// \returns \p YAML if \p YAML is valid runtime metadata, error otherwise.
ErrorOr<std::string> getRuntimeMDYAMLString(const FeatureBitset &Features,
StringRef YAML);

}
#endif
24 changes: 19 additions & 5 deletions lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,17 @@ void AMDGPUTargetAsmStreamer::EmitRuntimeMetadata(const FeatureBitset &Features,
OS << "\n\t.end_amdgpu_runtime_metadata\n";
}

void AMDGPUTargetAsmStreamer::EmitRuntimeMetadata(StringRef Metadata) {
bool AMDGPUTargetAsmStreamer::EmitRuntimeMetadata(const FeatureBitset &Features,
StringRef Metadata) {
auto VerifiedMetadata = getRuntimeMDYAMLString(Features, Metadata);
if (!VerifiedMetadata)
return true;

OS << "\t.amdgpu_runtime_metadata";
OS << Metadata;
OS << VerifiedMetadata.get();
OS << "\t.end_amdgpu_runtime_metadata\n";

return false;
}

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -216,7 +223,12 @@ void AMDGPUTargetELFStreamer::EmitAMDGPUHsaProgramScopeGlobal(
Symbol->setBinding(ELF::STB_GLOBAL);
}

void AMDGPUTargetELFStreamer::EmitRuntimeMetadata(StringRef Metadata) {
bool AMDGPUTargetELFStreamer::EmitRuntimeMetadata(const FeatureBitset &Features,
StringRef Metadata) {
auto VerifiedMetadata = getRuntimeMDYAMLString(Features, Metadata);
if (!VerifiedMetadata)
return true;

// Create two labels to mark the beginning and end of the desc field
// and a MCExpr to calculate the size of the desc field.
auto &Context = getContext();
Expand All @@ -231,13 +243,15 @@ void AMDGPUTargetELFStreamer::EmitRuntimeMetadata(StringRef Metadata) {
PT_NOTE::NT_AMDGPU_HSA_RUNTIME_METADATA,
[&](MCELFStreamer &OS) {
OS.EmitLabel(DescBegin);
OS.EmitBytes(Metadata);
OS.EmitBytes(VerifiedMetadata.get());
OS.EmitLabel(DescEnd);
}
);

return false;
}

void AMDGPUTargetELFStreamer::EmitRuntimeMetadata(const FeatureBitset &Features,
const Module &M) {
EmitRuntimeMetadata(getRuntimeMDYAMLString(Features, M));
EmitRuntimeMetadata(Features, getRuntimeMDYAMLString(Features, M));
}
12 changes: 9 additions & 3 deletions lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ class AMDGPUTargetStreamer : public MCTargetStreamer {
virtual void EmitRuntimeMetadata(const FeatureBitset &Features,
const Module &M) = 0;

virtual void EmitRuntimeMetadata(StringRef Metadata) = 0;
/// \returns False on success, true on failure.
virtual bool EmitRuntimeMetadata(const FeatureBitset &Features,
StringRef Metadata) = 0;
};

class AMDGPUTargetAsmStreamer : public AMDGPUTargetStreamer {
Expand All @@ -75,7 +77,9 @@ class AMDGPUTargetAsmStreamer : public AMDGPUTargetStreamer {
void EmitRuntimeMetadata(const FeatureBitset &Features,
const Module &M) override;

void EmitRuntimeMetadata(StringRef Metadata) override;
/// \returns False on success, true on failure.
bool EmitRuntimeMetadata(const FeatureBitset &Features,
StringRef Metadata) override;
};

class AMDGPUTargetELFStreamer : public AMDGPUTargetStreamer {
Expand Down Expand Up @@ -107,7 +111,9 @@ class AMDGPUTargetELFStreamer : public AMDGPUTargetStreamer {
void EmitRuntimeMetadata(const FeatureBitset &Features,
const Module &M) override;

void EmitRuntimeMetadata(StringRef Metadata) override;
/// \returns False on success, true on failure.
bool EmitRuntimeMetadata(const FeatureBitset &Features,
StringRef Metadata) override;
};

}
Expand Down
14 changes: 7 additions & 7 deletions test/MC/AMDGPU/hsa.s
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@
.end_amdgpu_runtime_metadata

// ASM: .amdgpu_runtime_metadata
// ASM: {
// ASM: amd.MDVersion: [ 2, 0 ]
// ASM: amd.Kernels: [
// ASM: { amd.KernelName: amd_kernel_code_t_test_all },
// ASM: { amd.KernelName: amd_kernel_code_t_minimal }
// ASM: ]
// ASM: }
// ASM: {
// ASM: amd.MDVersion: [ 2, 0 ]
// ASM: amd.IsaInfo: { amd.IsaInfoWavefrontSize: 64, amd.IsaInfoLocalMemorySize: 65536, amd.IsaInfoEUsPerCU: 4, amd.IsaInfoMaxWavesPerEU: 10, amd.IsaInfoMaxFlatWorkGroupSize: 2048, amd.IsaInfoSGPRAllocGranule: 8, amd.IsaInfoTotalNumSGPRs: 512, amd.IsaInfoAddressableNumSGPRs: 104, amd.IsaInfoVGPRAllocGranule: 4, amd.IsaInfoTotalNumVGPRs: 256, amd.IsaInfoAddressableNumVGPRs: 256 },
// ASM: amd.Kernels:
// ASM: - { amd.KernelName: amd_kernel_code_t_test_all }
// ASM: - { amd.KernelName: amd_kernel_code_t_minimal }
// ASM: }
// ASM: .end_amdgpu_runtime_metadata

.amdgpu_hsa_kernel amd_kernel_code_t_test_all
Expand Down
35 changes: 0 additions & 35 deletions test/MC/AMDGPU/metadata.s

This file was deleted.

39 changes: 39 additions & 0 deletions test/MC/AMDGPU/runtime-metadata-1.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// RUN: llvm-mc -triple=amdgcn-amd-amdhsa -mcpu=gfx700 -show-encoding %s | FileCheck %s --check-prefix=GCN --check-prefix=GFX700
// RUN: llvm-mc -triple=amdgcn-amd-amdhsa -mcpu=gfx800 -show-encoding %s | FileCheck %s --check-prefix=GCN --check-prefix=GFX800
// RUN: llvm-mc -triple=amdgcn-amd-amdhsa -mcpu=gfx900 -show-encoding %s | FileCheck %s --check-prefix=GCN --check-prefix=GFX900

.amdgpu_runtime_metadata
{ amd.MDVersion: [ 2, 1 ], amd.PrintfInfo: [ '1:1:4:%d\n', '2:1:8:%g\n' ], amd.Kernels:
- { amd.KernelName: test_char, amd.Language: OpenCL C, amd.LanguageVersion: [ 2, 0 ], amd.Args:
- { amd.ArgSize: 1, amd.ArgAlign: 1, amd.ArgKind: 0, amd.ArgValueType: 1, amd.ArgTypeName: char, amd.ArgAccQual: 0 }
- { amd.ArgSize: 8, amd.ArgAlign: 8, amd.ArgKind: 7, amd.ArgValueType: 9 }
- { amd.ArgSize: 8, amd.ArgAlign: 8, amd.ArgKind: 8, amd.ArgValueType: 9 }
- { amd.ArgSize: 8, amd.ArgAlign: 8, amd.ArgKind: 9, amd.ArgValueType: 9 }
- { amd.ArgSize: 8, amd.ArgAlign: 8, amd.ArgKind: 11, amd.ArgValueType: 1, amd.ArgAddrQual: 1 } }
- { amd.KernelName: test_ushort2, amd.Language: OpenCL C, amd.LanguageVersion: [ 2, 0 ], amd.Args:
- { amd.ArgSize: 4, amd.ArgAlign: 4, amd.ArgKind: 0, amd.ArgValueType: 4, amd.ArgTypeName: ushort2, amd.ArgAccQual: 0 }
- { amd.ArgSize: 8, amd.ArgAlign: 8, amd.ArgKind: 7, amd.ArgValueType: 9 }
- { amd.ArgSize: 8, amd.ArgAlign: 8, amd.ArgKind: 8, amd.ArgValueType: 9 }
- { amd.ArgSize: 8, amd.ArgAlign: 8, amd.ArgKind: 9, amd.ArgValueType: 9 }
- { amd.ArgSize: 8, amd.ArgAlign: 8, amd.ArgKind: 11, amd.ArgValueType: 1, amd.ArgAddrQual: 1 } }
}
.end_amdgpu_runtime_metadata

// GFX700: { amd.MDVersion: [ 2, 1 ], amd.IsaInfo: { amd.IsaInfoWavefrontSize: 64, amd.IsaInfoLocalMemorySize: 65536, amd.IsaInfoEUsPerCU: 4, amd.IsaInfoMaxWavesPerEU: 10, amd.IsaInfoMaxFlatWorkGroupSize: 2048, amd.IsaInfoSGPRAllocGranule: 8, amd.IsaInfoTotalNumSGPRs: 512, amd.IsaInfoAddressableNumSGPRs: 104, amd.IsaInfoVGPRAllocGranule: 4, amd.IsaInfoTotalNumVGPRs: 256, amd.IsaInfoAddressableNumVGPRs: 256 }, amd.PrintfInfo: [ '1:1:4:%d\n', '2:1:8:%g\n' ], amd.Kernels:

// GFX800: { amd.MDVersion: [ 2, 1 ], amd.IsaInfo: { amd.IsaInfoWavefrontSize: 64, amd.IsaInfoLocalMemorySize: 65536, amd.IsaInfoEUsPerCU: 4, amd.IsaInfoMaxWavesPerEU: 10, amd.IsaInfoMaxFlatWorkGroupSize: 2048, amd.IsaInfoSGPRAllocGranule: 16, amd.IsaInfoTotalNumSGPRs: 800, amd.IsaInfoAddressableNumSGPRs: 96, amd.IsaInfoVGPRAllocGranule: 4, amd.IsaInfoTotalNumVGPRs: 256, amd.IsaInfoAddressableNumVGPRs: 256 }, amd.PrintfInfo: [ '1:1:4:%d\n', '2:1:8:%g\n' ], amd.Kernels:

// GFX900: { amd.MDVersion: [ 2, 1 ], amd.IsaInfo: { amd.IsaInfoWavefrontSize: 64, amd.IsaInfoLocalMemorySize: 65536, amd.IsaInfoEUsPerCU: 4, amd.IsaInfoMaxWavesPerEU: 10, amd.IsaInfoMaxFlatWorkGroupSize: 2048, amd.IsaInfoSGPRAllocGranule: 16, amd.IsaInfoTotalNumSGPRs: 800, amd.IsaInfoAddressableNumSGPRs: 102, amd.IsaInfoVGPRAllocGranule: 4, amd.IsaInfoTotalNumVGPRs: 256, amd.IsaInfoAddressableNumVGPRs: 256 }, amd.PrintfInfo: [ '1:1:4:%d\n', '2:1:8:%g\n' ], amd.Kernels:

// GCN: - { amd.KernelName: test_char, amd.Language: OpenCL C, amd.LanguageVersion: [ 2, 0 ], amd.Args:
// GCN-NEXT: - { amd.ArgSize: 1, amd.ArgAlign: 1, amd.ArgKind: 0, amd.ArgValueType: 1, amd.ArgTypeName: char, amd.ArgAccQual: 0 }
// GCN-NEXT: - { amd.ArgSize: 8, amd.ArgAlign: 8, amd.ArgKind: 7, amd.ArgValueType: 9 }
// GCN-NEXT: - { amd.ArgSize: 8, amd.ArgAlign: 8, amd.ArgKind: 8, amd.ArgValueType: 9 }
// GCN-NEXT: - { amd.ArgSize: 8, amd.ArgAlign: 8, amd.ArgKind: 9, amd.ArgValueType: 9 }
// GCN-NEXT: - { amd.ArgSize: 8, amd.ArgAlign: 8, amd.ArgKind: 11, amd.ArgValueType: 1, amd.ArgAddrQual: 1 } }
// GCN-NEXT: - { amd.KernelName: test_ushort2, amd.Language: OpenCL C, amd.LanguageVersion: [ 2, 0 ], amd.Args:
// GCN-NEXT: - { amd.ArgSize: 4, amd.ArgAlign: 4, amd.ArgKind: 0, amd.ArgValueType: 4, amd.ArgTypeName: ushort2, amd.ArgAccQual: 0 }
// GCN-NEXT: - { amd.ArgSize: 8, amd.ArgAlign: 8, amd.ArgKind: 7, amd.ArgValueType: 9 }
// GCN-NEXT: - { amd.ArgSize: 8, amd.ArgAlign: 8, amd.ArgKind: 8, amd.ArgValueType: 9 }
// GCN-NEXT: - { amd.ArgSize: 8, amd.ArgAlign: 8, amd.ArgKind: 9, amd.ArgValueType: 9 }
// GCN-NEXT: - { amd.ArgSize: 8, amd.ArgAlign: 8, amd.ArgKind: 11, amd.ArgValueType: 1, amd.ArgAddrQual: 1 } } }
Loading

0 comments on commit 9995ddd

Please sign in to comment.