-
Notifications
You must be signed in to change notification settings - Fork 247
[SPV->LLVM] Fix global c/dtors type if SPV is from opaque type LLVM #2280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1331,6 +1331,39 @@ void SPIRVToLLVM::transFunctionPointerCallArgumentAttributes( | |
| } | ||
| } | ||
|
|
||
| /// When spirv is generated from LLVM IR with opapque pointer enabled and then | ||
| /// the spirv is translated to LLVM IR with typed pointer, function pointer is | ||
| /// casted to i8* type in \p Ty and \p Initializer, which causes error in LLVM | ||
| /// IR verifier. E.g. | ||
| /// [1 x %0][%0 { i32 1, i8* bitcast (void ()* @ctor to i8*), i8* null }] | ||
| /// This function removes the cast so that LLVM IR is valid. | ||
|
||
| static void postProcGlobalCtorDtorTypeInit(Type *&Ty, Constant *&Initializer) { | ||
|
||
| auto *InitArr = cast<ConstantArray>(Initializer); | ||
| unsigned NumEltsInArr = InitArr->getType()->getNumElements(); | ||
| assert(NumEltsInArr && "array is empty"); | ||
| auto *CS = cast<ConstantStruct>(InitArr->getAggregateElement(0u)); | ||
| assert(CS->getType()->getNumElements() == 3 && "expect 3 elements in struct"); | ||
|
||
| auto *Elt1 = CS->getAggregateElement(1); | ||
| if (!isa<ConstantExpr>(Elt1)) | ||
| return; | ||
| auto *StTy = CS->getType(); | ||
| auto *NewStTy = StructType::create(Ty->getContext(), | ||
| {StTy->getElementType(0), | ||
| Elt1->stripPointerCasts()->getType(), | ||
| StTy->getElementType(2)}, | ||
| StTy->getName(), StTy->isPacked()); | ||
| Ty = ArrayType::get(NewStTy, NumEltsInArr); | ||
| SmallVector<Constant *, 4> ArrElts; | ||
| for (unsigned I = 0; I < NumEltsInArr; ++I) { | ||
| auto *CS = cast<ConstantStruct>(InitArr->getAggregateElement(I)); | ||
| ArrElts.push_back(ConstantStruct::get( | ||
| NewStTy, {CS->getAggregateElement(0u), | ||
| CS->getAggregateElement(1)->stripPointerCasts(), | ||
| CS->getAggregateElement(2)})); | ||
| } | ||
| Initializer = ConstantArray::get(cast<ArrayType>(Ty), ArrElts); | ||
| } | ||
|
|
||
| /// For instructions, this function assumes they are created in order | ||
| /// and appended to the given basic block. An instruction may use a | ||
| /// instruction from another BB which has not been translated. Such | ||
|
|
@@ -1556,20 +1589,28 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F, | |
| SPIRVBuiltinVariableKind BVKind; | ||
| if (BVar->isBuiltin(&BVKind)) | ||
| BV->setName(prefixSPIRVName(SPIRVBuiltInNameMap::map(BVKind))); | ||
| bool IsCtorOrDtor = (BV->getName() == "llvm.global_ctors" || | ||
| BV->getName() == "llvm.global_dtors"); | ||
| if (Init && IsCtorOrDtor) { | ||
| Initializer = dyn_cast<Constant>(transValue(Init, F, BB, false)); | ||
| postProcGlobalCtorDtorTypeInit(Ty, Initializer); | ||
|
||
| } | ||
|
||
| auto LVar = new GlobalVariable(*M, Ty, IsConst, LinkageTy, | ||
| /*Initializer=*/nullptr, BV->getName(), 0, | ||
| GlobalVariable::NotThreadLocal, AddrSpace); | ||
| auto Res = mapValue(BV, LVar); | ||
| if (Init) | ||
| Initializer = dyn_cast<Constant>(transValue(Init, F, BB, false)); | ||
| else if (LinkageTy == GlobalValue::CommonLinkage) | ||
| if (Init) { | ||
| if (!IsCtorOrDtor) | ||
| Initializer = dyn_cast<Constant>(transValue(Init, F, BB, false)); | ||
| } else if (LinkageTy == GlobalValue::CommonLinkage) { | ||
| // In LLVM, variables with common linkage type must be initialized to 0. | ||
| Initializer = Constant::getNullValue(Ty); | ||
| else if (BS == SPIRVStorageClassKind::StorageClassWorkgroup) | ||
| } else if (BS == SPIRVStorageClassKind::StorageClassWorkgroup) { | ||
| Initializer = dyn_cast<Constant>(UndefValue::get(Ty)); | ||
| else if ((LinkageTy != GlobalValue::ExternalLinkage) && | ||
| (BS == SPIRVStorageClassKind::StorageClassCrossWorkgroup)) | ||
| } else if ((LinkageTy != GlobalValue::ExternalLinkage) && | ||
| (BS == SPIRVStorageClassKind::StorageClassCrossWorkgroup)) { | ||
| Initializer = Constant::getNullValue(Ty); | ||
| } | ||
|
|
||
| LVar->setUnnamedAddr((IsConst && Ty->isArrayTy() && | ||
| Ty->getArrayElementType()->isIntegerTy(8)) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| 119734787 65792 393230 22 0 | ||
| 2 Capability Addresses | ||
| 2 Capability Linkage | ||
| 2 Capability Kernel | ||
| 2 Capability Int64 | ||
| 2 Capability Int8 | ||
| 2 Capability FunctionPointersINTEL | ||
| 8 Extension "SPV_INTEL_function_pointers" | ||
| 5 ExtInstImport 1 "OpenCL.std" | ||
| 3 MemoryModel 2 2 | ||
| 3 Source 0 0 | ||
| 7 Name 14 "asan.module_ctor" | ||
| 7 Name 15 "asan.module_ctor" | ||
| 7 Name 20 "llvm.global_ctors" | ||
|
|
||
| 9 Decorate 20 LinkageAttributes "llvm.global_ctors" Export | ||
| 4 TypeInt 3 32 0 | ||
| 4 TypeInt 4 8 0 | ||
| 4 TypeInt 6 64 0 | ||
| 5 Constant 6 7 1 0 | ||
| 4 Constant 3 10 1 | ||
| 4 TypePointer 5 7 4 | ||
| 5 TypeStruct 2 3 5 5 | ||
|
|
||
| 4 TypeArray 8 2 7 | ||
| 4 TypePointer 9 7 8 | ||
| 2 TypeVoid 11 | ||
| 3 TypeFunction 12 11 | ||
| 4 TypePointer 13 7 12 | ||
| 4 ConstantFunctionPointerINTEL 13 15 14 | ||
| 5 SpecConstantOp 5 16 124 15 | ||
| 3 ConstantNull 5 17 | ||
| 6 ConstantComposite 2 18 10 16 17 | ||
|
|
||
| 4 ConstantComposite 8 19 18 | ||
|
|
||
| 5 Variable 9 20 7 19 | ||
|
|
||
|
|
||
|
|
||
| 5 Function 11 14 0 12 | ||
|
|
||
| 2 Label 21 | ||
| 1 Return | ||
|
|
||
| 1 FunctionEnd | ||
|
|
||
| ; RUN: llvm-spirv %s --to-binary -o %t.spv | ||
| ; RUN: llvm-spirv -r %t.spv -o %t.bc | ||
| ; RUN: llvm-dis %t.bc -o %t.ll | ||
| ; RUN: FileCheck --input-file=%t.ll %s --check-prefix=CHECK-LLVM | ||
|
|
||
| ; CHECK-LLVM: [[TY:%.*]] = type { i32, void ()*, i8* } | ||
| ; CHECK-LLVM: @llvm.global_ctors = appending global [1 x [[TY]]] [[[TY]] { i32 1, void ()* @asan.module_ctor, i8* null }] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: opaque
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done