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
21 changes: 16 additions & 5 deletions lib/SPIRV/SPIRVReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4593,14 +4593,25 @@ bool SPIRVToLLVM::translate() {
DbgTran->transDebugInst(EI);
}

// Populate the feature predicate map before translating any variables,
// because variable translation can recursively trigger function translation
// (e.g. via __clang_gpu_used_external), which may reference spec constants
// that depend on the predicate map.
if (M->getTargetTriple().isAMDGCN()) {
for (unsigned I = 0, E = BM->getNumVariables(); I != E; ++I) {
auto *BV = BM->getVariable(I);
if (BV->getStorageClass() != StorageClassFunction &&
BV->getName() == "llvm.amdgcn.feature.predicate.ids") {
addFeaturePredicateMap(BV->getInitializer());
break;
}
}
}

for (unsigned I = 0, E = BM->getNumVariables(); I != E; ++I) {
auto *BV = BM->getVariable(I);
if (BV->getStorageClass() != StorageClassFunction) {
// The feature predicate map is just a helper, we never emit it.
if (M->getTargetTriple().isAMDGCN() &&
BV->getName() == "llvm.amdgcn.feature.predicate.ids")
addFeaturePredicateMap(BV->getInitializer());
else
if (BV->getName() != "llvm.amdgcn.feature.predicate.ids")
transValue(BV, nullptr, nullptr);
}
transGlobalCtorDtors(BV);
Expand Down
99 changes: 99 additions & 0 deletions test/SpecConstants/feature-predicate-variable-order.spvasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
; Test that feature predicate spec constants resolve correctly when a variable
; whose initializer references a kernel (e.g. __clang_gpu_used_external from
; multi-TU linking) appears before llvm.amdgcn.feature.predicate.ids.

; RUN: llvm-spirv -to-binary -o %t.spv %s
; RUN: spirv-val %t.spv
; RUN: llvm-spirv -r --spirv-target-env=CL2.0 %t.spv -o %t.bc
; RUN: llvm-dis %t.bc -o - | FileCheck %s

; CHECK-LABEL: define {{.*}} @kernel
; CHECK-NOT: br i1 false
; CHECK: call void @real_barrier
; CHECK-NOT: call {{.*}}barrier_missing

119734787 67072 65535 50 0
2 Capability Addresses
2 Capability Linkage
2 Capability Kernel
2 Capability Int8
2 Capability Int64
2 Capability FunctionPointersINTEL
5 ExtInstImport 1 "OpenCL.std"
3 MemoryModel 2 2
8 Extension "SPV_INTEL_function_pointers"
9 Name 10 "__clang_gpu_used_external"
11 Name 20 "llvm.amdgcn.feature.predicate.ids"
4 Name 30 "kernel"
6 Name 40 "barrier_missing"
6 Name 41 "real_barrier"

4 Decorate 25 SpecId 0
11 Decorate 10 LinkageAttributes "__clang_gpu_used_external" Export
3 Decorate 10 Constant
13 Decorate 20 LinkageAttributes "llvm.amdgcn.feature.predicate.ids" Export
3 Decorate 20 Constant
6 Decorate 30 LinkageAttributes "kernel" Export

4 TypeInt 2 64 0
4 TypeInt 4 8 0
2 TypeVoid 5
3 TypeFunction 6 5
2 TypeBool 7
; Function pointer type: pointer to function type in CodeSectionINTEL (5605)
4 TypePointer 14 5605 6
; CrossWorkgroup pointer to function type (for the bitcast target)
4 TypePointer 17 5 6
5 Constant 2 8 7 0
4 Constant 4 42 104
4 Constant 4 43 97
4 Constant 4 44 115
4 Constant 4 45 46
4 Constant 4 46 32
4 Constant 4 47 48
4 Constant 4 48 0

; ConstantFunctionPointerINTEL wraps function 30 into a constant
4 ConstantFunctionPointerINTEL 14 29 30
; Bitcast the function pointer constant to CrossWorkgroup pointer
5 SpecConstantOp 17 15 124 29

4 TypeInt 3 32 0
4 Constant 3 49 1
4 TypeArray 9 4 8
4 TypeArray 11 17 49
4 TypePointer 12 5 9
4 TypePointer 13 5 11

; __clang_gpu_used_external BEFORE predicate map — this ordering triggers the bug
4 SpecConstantComposite 11 16 15
5 Variable 13 10 5 16

; Predicate map: "has. 0\0"
10 ConstantComposite 9 19 42 43 44 45 46 47 48
5 Variable 12 20 5 19

3 SpecConstantFalse 7 25

5 Function 5 40 0 6
2 Label 35
1 Return
1 FunctionEnd

5 Function 5 41 0 6
2 Label 36
1 Return
1 FunctionEnd

5 Function 5 30 0 6
2 Label 31
4 BranchConditional 25 32 33
2 Label 32
4 FunctionCall 5 37 41
2 Branch 34
2 Label 33
4 FunctionCall 5 38 40
2 Branch 34
2 Label 34
1 Return
1 FunctionEnd
Loading