Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,14 @@ if(LLVM_SPIRV_BUILD_EXTERNAL)
endif()
endif()

# AMD customization begin: Disable SPIR-V backend for AMD's fork
is_llvm_target_library("SPIRV" spirv_present_result INCLUDED_TARGETS)
if(spirv_present_result)
message(STATUS "Found SPIR-V Backend, but it is currently disabled for AMD's fork.")
# set(SPIRV_BACKEND_FOUND TRUE)
# add_compile_definitions(LLVM_SPIRV_BACKEND_TARGET_PRESENT)
endif()
# AMD customization end

set(LLVM_SPIRV_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include)

Expand Down
83 changes: 82 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,88 @@ dependencies on anything but superficial semantics).

### Differences vs Upstream

- TBA
All AMD-specific code is marked with `// AMD customization begin:` and
`// AMD customization end` comments in the source files.
Comment on lines +22 to +23

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
All AMD-specific code is marked with `// AMD customization begin:` and
`// AMD customization end` comments in the source files.
All AMD-specific code is marked with `// AMD customization begin:` and
`// AMD customization end` comments in the source files. Other appropriate comment markers should be used in different file types.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or something along these lines.


#### Build System Changes

| File | Description |
|------|-------------|
| `CMakeLists.txt` | Disable SPIR-V backend for AMD's fork |
| `lib/SPIRV/CMakeLists.txt` | Rename library to `LLVMSPIRVAMDLib` |
| `tools/llvm-spirv/CMakeLists.txt` | Rename tool to `amd-llvm-spirv`, use `SPIRVAMDLib` |
| `test/CMakeLists.txt` | Update target names for AMD |
| `test/lit.cfg.py` | Use `amd-llvm-spirv` tool name and `LLVMSPIRVAMDLib` library |

#### New Extensions

| Extension | Description |
|-----------|-------------|
| `SPV_NV_shader_atomic_fp16_vector` | FP16 vector atomic support |
| `SPV_AMD_weak_linkage` | Weak linkage support for AMDGPU |

#### Weak Linkage Support

| File | Description |
|------|-------------|
| `lib/SPIRV/libSPIRV/spirv_internal.hpp` | Define `LinkageTypeWeak` |
| `lib/SPIRV/libSPIRV/SPIRVDecorate.h` | Extension requirement for weak linkage |
| `lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h` | Validate weak linkage type |
| `lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h` | Name mapping for weak linkage |

#### DIOp-based DIExpression Support (Debug Info)

| File | Description |
|------|-------------|
| `lib/SPIRV/libSPIRV/SPIRV.debug.h` | DIOp operations, expression opcodes, operand counts |
| `lib/SPIRV/LLVMToSPIRVDbgTran.cpp` | DIOp operand translation, expression translation |
| `lib/SPIRV/LLVMToSPIRVDbgTran.h` | `transDIOpOperand` template declaration |
| `lib/SPIRV/SPIRVToLLVMDbgTran.cpp` | DIOp translation, expression poisoning |
| `lib/SPIRV/SPIRVToLLVMDbgTran.h` | `transDIOpOperand`, `tryTransDIOpDIExpression` declarations |

#### AMDGPU Target Support (SPIRVReader.cpp)

| Category | Description |
|----------|-------------|
| Address Space Mapping | SPIR-V to AMDGPU address space mapping functions |
| Calling Convention | Use `AMDGPU_KERNEL`/`C` instead of `SPIR_KERNEL`/`SPIR_FUNC` |
| Type Handling | Zero-sized arrays, pointer type relaxation |
| Intrinsics | OpenCL intrinsics to LLVM intrinsics translation |
| Module Setup | AMDGCN target triple, data layout, COV flags |
| Variable Handling | Workgroup variables, externally initialized globals |
| Attribute Handling | ByVal→ByRef, Captures, kernel attributes |

#### AMDGPU Target Support (SPIRVWriter.cpp)

| Category | Description |
|----------|-------------|
| Generator Version | Use `UINT16_MAX` for AMD to identify AMDGPU binaries |
| Zero-sized Arrays | Use `UINT64_MAX` sentinel |
| Variadic Functions | Support vararg functions |
| Atomics | UIncWrap/UDecWrap handling |
| Validation | Relax address space cast checks |

#### Atomic Operations (SPIRVToOCL20.cpp)

| Feature | Description |
|---------|-------------|
| Memory Scope | Map OpenCL scope to AMDGPU sync scope |
| Atomics | Translate SPIR-V atomics to LLVM atomic instructions |
| Fences | Translate memory barrier to LLVM fence |
| CmpXchg | Native LLVM atomicrmw/cmpxchg generation |

#### Other Customizations

| File | Description |
|------|-------------|
| `lib/SPIRV/libSPIRV/SPIRVInstruction.h` | Type validation relaxation for untyped pointers |
| `lib/SPIRV/OCLUtil.h` | AMDGCN↔SPIR-V address space mapping functions |
| `lib/SPIRV/OCLUtil.cpp` | Scope naming, atomic inc/dec wrap ops |
| `lib/SPIRV/SPIRVInternal.h` | Captures attribute mapping |
| `lib/SPIRV/SPIRVUtil.cpp` | C calling convention for AMDGPU |
| `lib/SPIRV/SPIRVToOCL.cpp` | Skip cast mutation for AMD |
| `lib/SPIRV/OCLToSPIRV.cpp` | Barrier argument validation |
| `lib/SPIRV/SPIRVLowerLLVMIntrinsic.cpp` | Extension name changes (INTEL->ALTERA) |

## Directory Structure

Expand Down
2 changes: 2 additions & 0 deletions include/LLVMSPIRVExtensions.inc
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,7 @@ EXT(SPV_INTEL_sigmoid)
EXT(SPV_INTEL_float4)
EXT(SPV_INTEL_fp_conversions)
EXT(SPV_KHR_float_controls2)
// AMD customization begin: AMD-specific extensions
EXT(SPV_NV_shader_atomic_fp16_vector)
EXT(SPV_AMD_weak_linkage)
// AMD customization end
2 changes: 2 additions & 0 deletions lib/SPIRV/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ if(SPIRV_BACKEND_FOUND)
list(APPEND SPIRVLIB_LINK_COMPONENTS "SPIRVCodeGen")
endif()

# AMD customization begin: Rename library to LLVMSPIRVAMDLib
add_llvm_library(LLVMSPIRVAMDLib
${SRC_LIST}
LINK_COMPONENTS
Expand All @@ -69,6 +70,7 @@ add_llvm_library(LLVMSPIRVAMDLib
)

target_include_directories(LLVMSPIRVAMDLib
# AMD customization end
PRIVATE
${LLVM_INCLUDE_DIRS}
${LLVM_SPIRV_INCLUDE_DIRS}
Expand Down
6 changes: 6 additions & 0 deletions lib/SPIRV/LLVMToSPIRVDbgTran.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1221,13 +1221,15 @@ LLVMToSPIRVDbgTran::transDbgGlobalVariable(const DIGlobalVariable *GV) {
// DIExpression is non-empty
GVE->getExpression()->getNumElements()) {
if (Ops[VariableIdx] != getDebugInfoNoneId()) {
// AMD customization begin: DIOp-based global variable expression handling
#ifdef SPIRV_HAS_DIOP_DIEXPRESSION
if (GVE->getExpression()->holdsNewElements()) {
Ops.resize(MaxOperandCount, getDebugInfoNoneId());
Ops[DIOpBasedExprIdx] =
transDbgExpression(GVE->getExpression())->getId();
}
#endif
// AMD customization end
break;
}
// Repurpose VariableIdx operand to hold the initial value held in the
Expand Down Expand Up @@ -1613,6 +1615,7 @@ LLVMToSPIRVDbgTran::transDbgLocalVariable(const DILocalVariable *Var) {

// DWARF Operations and expressions

// AMD customization begin: DIOp-based DIExpression operand translation
template <>
void LLVMToSPIRVDbgTran::transDIOpOperand(SPIRVWordVec &Vec, unsigned Idx,
llvm::Type *Ty) {
Expand All @@ -1632,10 +1635,12 @@ void LLVMToSPIRVDbgTran::transDIOpOperand(SPIRVWordVec &Vec, unsigned Idx,
llvm::ConstantData *Data) {
Vec[Idx] = SPIRVWriter->transConstant(Data)->getId();
}
// AMD customization end

SPIRVEntry *LLVMToSPIRVDbgTran::transDbgExpression(const DIExpression *Expr) {
SPIRVWordVec Operations;

// AMD customization begin: DIOp-based DIExpression translation
#ifdef SPIRV_HAS_DIOP_DIEXPRESSION
if (auto NewElems = Expr->getNewElementsRef()) {
if (!(BM->allowExtraDIExpressions() ||
Expand Down Expand Up @@ -1690,6 +1695,7 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgExpression(const DIExpression *Expr) {
return BM->addDebugInfo(SPIRVDebug::Expression, getVoidTy(), Operations);
}
#endif
// AMD customization end

for (unsigned I = 0, N = Expr->getNumElements(); I < N; ++I) {
using namespace SPIRVDebug::Operand::Operation;
Expand Down
2 changes: 2 additions & 0 deletions lib/SPIRV/LLVMToSPIRVDbgTran.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,10 @@ class LLVMToSPIRVDbgTran {
// DWARF expressions
SPIRVEntry *transDbgExpression(const DIExpression *Expr);

// AMD customization begin: DIOp-based DIExpression support
template <class OperandTy>
void transDIOpOperand(SPIRVWordVec &Vec, unsigned Idx, OperandTy Operand);
// AMD customization end

// Imported declarations and modules
SPIRVEntry *transDbgImportedEntry(const DIImportedEntity *IE);
Expand Down
2 changes: 2 additions & 0 deletions lib/SPIRV/OCLToSPIRV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,10 +403,12 @@ void OCLToSPIRVBase::visitCallInst(CallInst &CI) {
if (DemangledName == kOCLBuiltinName::WorkGroupBarrier ||
DemangledName == kOCLBuiltinName::Barrier ||
DemangledName == kOCLBuiltinName::SubGroupBarrier) {
// AMD customization begin: barrier argument validation for AMD
if (F->arg_size() != 1 && F->arg_size() != 2 &&
F->getParent()->getTargetTriple().getVendor()
== Triple::VendorType::AMD)
return; // Somebody used the name.
// AMD customization end
visitCallBarrier(&CI);
return;
}
Expand Down
4 changes: 4 additions & 0 deletions lib/SPIRV/OCLUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,15 @@ template <> void SPIRVMap<OCLScopeKind, Scope>::init() {
add(OCLMS_sub_group, ScopeSubgroup);
}

// AMD customization begin: scope name change ("work_item" -> "singlethread")
template <> void SPIRVMap<std::string, Scope>::init() {
add("singlethread", ScopeInvocation);
add("workgroup", ScopeWorkgroup);
add("device", ScopeDevice);
add("all_svm_devices", ScopeCrossDevice);
add("subgroup", ScopeSubgroup);
}
// AMD customization end

template <> void SPIRVMap<std::string, SPIRVGroupOperationKind>::init() {
add("reduce", GroupOperationReduce);
Expand Down Expand Up @@ -658,8 +660,10 @@ template <> void LLVMSPIRVAtomicRmwOpCodeMap::init() {
add(llvm::AtomicRMWInst::FAdd, OpAtomicFAddEXT);
add(llvm::AtomicRMWInst::FMin, OpAtomicFMinEXT);
add(llvm::AtomicRMWInst::FMax, OpAtomicFMaxEXT);
// AMD customization begin: atomic inc/dec wrap operation mapping
add(llvm::AtomicRMWInst::UIncWrap, OpAtomicIIncrement);
add(llvm::AtomicRMWInst::UDecWrap, OpAtomicIDecrement);
// AMD customization end
}

} // namespace SPIRV
Expand Down
4 changes: 4 additions & 0 deletions lib/SPIRV/OCLUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ inline OCLMemOrderKind mapSPIRVMemOrderToOCL(unsigned Sema) {
return OCLMemOrderMap::rmap(extractSPIRVMemOrderSemantic(Sema));
}

// AMD customization begin: map AMDGCN address space to SPIR-V address space
inline unsigned int mapAMDGCNAddrSpaceToSPIRV(unsigned int AS) {
switch (AS) {
case 0:
Expand All @@ -517,7 +518,9 @@ inline unsigned int mapAMDGCNAddrSpaceToSPIRV(unsigned int AS) {
return UINT_MAX;
}
}
// AMD customization end

// AMD customization begin: map SPIR-V storage class to AMDGPU address space
inline SPIRAddressSpace mapSPIRVAddrSpaceToAMDGPU(SPIRVStorageClassKind SPVAS) {
switch (SPVAS) {
case StorageClassCrossWorkgroup:
Expand All @@ -536,6 +539,7 @@ inline SPIRAddressSpace mapSPIRVAddrSpaceToAMDGPU(SPIRVStorageClassKind SPVAS) {
return static_cast<SPIRAddressSpace>(UINT_MAX);
}
}
// AMD customization end

bool isPipeOrAddressSpaceCastBI(const StringRef MangledName);
bool isEnqueueKernelBI(const StringRef MangledName);
Expand Down
2 changes: 2 additions & 0 deletions lib/SPIRV/SPIRVInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,9 @@ inline void SPIRVMap<Attribute::AttrKind, SPIRVFuncParamAttrKind>::init() {
add(Attribute::ByVal, FunctionParameterAttributeByVal);
add(Attribute::StructRet, FunctionParameterAttributeSret);
add(Attribute::NoAlias, FunctionParameterAttributeNoAlias);
// AMD customization begin: Captures attribute mapping
add(Attribute::Captures, FunctionParameterAttributeNoCapture);
// AMD customization end
add(Attribute::ReadOnly, FunctionParameterAttributeNoWrite);
add(Attribute::ReadNone, FunctionParameterAttributeNoReadWrite);
}
Expand Down
2 changes: 2 additions & 0 deletions lib/SPIRV/SPIRVLowerLLVMIntrinsic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ typedef struct {
#define NO_REQUIRED_EXTENSION ExtensionID::Last
#define NO_FORBIDDEN_EXTENSION ExtensionID::Last

// AMD customization begin: extension name changes (SPV_INTEL_arbitrary_precision_integers -> SPV_ALTERA_arbitrary_precision_integers)
const std::map<const StringRef, const LLVMIntrinsicMapValueType> LLVMIntrinsicMapEntries = {
// LLVM Intrinsic Name Required Extension Forbidden Extension Module with
// emulation function
Expand Down Expand Up @@ -121,6 +122,7 @@ const std::map<const StringRef, const LLVMIntrinsicMapValueType> LLVMIntrinsicMa
{ "llvm.sadd.with.overflow.i32", {NO_REQUIRED_EXTENSION, NO_FORBIDDEN_EXTENSION, LLVMSaddWithOverflow}},
{ "llvm.sadd.with.overflow.i64", {NO_REQUIRED_EXTENSION, NO_FORBIDDEN_EXTENSION, LLVMSaddWithOverflow}},
};
// AMD customization end
// clang-format on

} // namespace
Expand Down
Loading
Loading