From d256a9df2efb32b9ace0de391b0948367376fb80 Mon Sep 17 00:00:00 2001 From: "Maksimova, Viktoria" Date: Wed, 9 Nov 2022 04:04:39 -0800 Subject: [PATCH 1/8] Workaround --- lib/SPIRV/SPIRVReader.cpp | 83 ++++++++++++++++++++++++++++++++------- 1 file changed, 68 insertions(+), 15 deletions(-) diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 9024e1db4c..998949908a 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -2138,11 +2138,37 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F, Index.insert(Index.begin(), getInt32(M, 0)); auto IsInbound = AC->isInBounds(); Value *V = nullptr; + if (Use *SingleUse = Base->getSingleUndroppableUse()) { + if (auto *GI = dyn_cast(SingleUse->getUser())) { + if (GI->getPointerOperandType() == Base->getType()) { + if (Use *SingleUseGI = GI->getSingleUndroppableUse()) { + if (auto *II = dyn_cast(SingleUseGI->getUser())) { + if (II->getIntrinsicID() == Intrinsic::ptr_annotation) { + if (Use *SingleUseII = II->getSingleUndroppableUse()) { + if (auto II2 = + dyn_cast(SingleUseII->getUser())) { + if (II2->getIntrinsicID() == Intrinsic::ptr_annotation) + V = II2; + } + } + } + if (!V) + V = II; + } + } + if (!V) + V = GI; + } + } + } + if (BB) { - auto GEP = - GetElementPtrInst::Create(BaseTy, Base, Index, BV->getName(), BB); - GEP->setIsInBounds(IsInbound); - V = GEP; + if (!V) { + auto GEP = + GetElementPtrInst::Create(BaseTy, Base, Index, BV->getName(), BB); + GEP->setIsInBounds(IsInbound); + V = GEP; + } } else { V = ConstantExpr::getGetElementPtr(BaseTy, dyn_cast(Base), Index, IsInbound); @@ -3520,20 +3546,47 @@ void SPIRVToLLVM::transIntelFPGADecorations(SPIRVValue *BV, Value *V) { for (auto AnnotStr : AnnotStrVec) { auto *GS = Builder.CreateGlobalStringPtr(AnnotStr); - auto *GEP = cast( - Builder.CreateConstInBoundsGEP2_32(AllocatedTy, AL, 0, I)); - - Type *IntTy = GEP->getResultElementType()->isIntegerTy() - ? GEP->getType() - : Int8PtrTyPrivate; - + GetElementPtrInst *GEP = nullptr; + IntrinsicInst *PtrAnn = nullptr; + if (Use *SingleUse = V->getSingleUndroppableUse()) { + if (auto *GI = dyn_cast(SingleUse->getUser())) { + if (GI->getPointerOperandType() == V->getType()) { + if (Use *SingleUseGI = GI->getSingleUndroppableUse()) { + if (auto *II = + dyn_cast(SingleUseGI->getUser())) + if (II->getIntrinsicID() == Intrinsic::ptr_annotation) + PtrAnn = II; + } + if (!GEP) + GEP = GI; + } + } + } + if (!GEP) + GEP = cast( + Builder.CreateConstInBoundsGEP2_32(AllocatedTy, AL, 0, I)); + + Type *IntTy = nullptr; + llvm::Value *PtrAnnotationValue = nullptr; + if (PtrAnn) { + IntTy = PtrAnn->getType()->getPointerElementType()->isIntegerTy() + ? PtrAnn->getType() + : Int8PtrTyPrivate; + PtrAnnotationValue = + Builder.CreateBitCast(PtrAnn, IntTy, PtrAnn->getName()); + } else { + IntTy = GEP->getResultElementType()->isIntegerTy() + ? GEP->getType() + : Int8PtrTyPrivate; + PtrAnnotationValue = + Builder.CreateBitCast(GEP, IntTy, GEP->getName()); + } auto AnnotationFn = llvm::Intrinsic::getDeclaration( M, Intrinsic::ptr_annotation, IntTy); - llvm::Value *Args[] = { - Builder.CreateBitCast(GEP, IntTy, GEP->getName()), - Builder.CreateBitCast(GS, Int8PtrTyPrivate), UndefInt8Ptr, - UndefInt32, UndefInt8Ptr}; + llvm::Value *Args[] = {PtrAnnotationValue, + Builder.CreateBitCast(GS, Int8PtrTyPrivate), + UndefInt8Ptr, UndefInt32, UndefInt8Ptr}; Builder.CreateCall(AnnotationFn, Args); } } From ab20f75b4e69e885fe7cbe1f3d3b9462c219df32 Mon Sep 17 00:00:00 2001 From: "Maksimova, Viktoria" Date: Wed, 16 Nov 2022 03:33:34 -0800 Subject: [PATCH 2/8] Rework to reuse gep/ptr ann --- lib/SPIRV/SPIRVReader.cpp | 76 +++++++++---------- lib/SPIRV/SPIRVReader.h | 4 + test/transcoding/multiple_user_semantic.ll | 11 ++- .../multiple_user_semantic_nonopaque.ll | 5 +- 4 files changed, 51 insertions(+), 45 deletions(-) diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 998949908a..8df7fe6439 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -2138,27 +2138,22 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F, Index.insert(Index.begin(), getInt32(M, 0)); auto IsInbound = AC->isInBounds(); Value *V = nullptr; - if (Use *SingleUse = Base->getSingleUndroppableUse()) { - if (auto *GI = dyn_cast(SingleUse->getUser())) { - if (GI->getPointerOperandType() == Base->getType()) { - if (Use *SingleUseGI = GI->getSingleUndroppableUse()) { - if (auto *II = dyn_cast(SingleUseGI->getUser())) { - if (II->getIntrinsicID() == Intrinsic::ptr_annotation) { - if (Use *SingleUseII = II->getSingleUndroppableUse()) { - if (auto II2 = - dyn_cast(SingleUseII->getUser())) { - if (II2->getIntrinsicID() == Intrinsic::ptr_annotation) - V = II2; - } - } - } - if (!V) - V = II; - } + + if (GEPOrUseMap.count(BaseTy)) { + auto Element = GEPOrUseMap[BaseTy]; + auto Idx = AC->getIndices(); + + if (Element.first.size() == Idx.size()) { + bool IsEqual = true; + for (size_t I = 0; I < Idx.size(); I++) { + SPIRVWord Index = static_cast(getTranslatedValue(Idx[I]))->getZExtValue(); + if (Index != Element.first[I]) { + IsEqual = false; + break; } - if (!V) - V = GI; } + if (IsEqual) + V = Element.second; } } @@ -3547,31 +3542,30 @@ void SPIRVToLLVM::transIntelFPGADecorations(SPIRVValue *BV, Value *V) { auto *GS = Builder.CreateGlobalStringPtr(AnnotStr); GetElementPtrInst *GEP = nullptr; - IntrinsicInst *PtrAnn = nullptr; - if (Use *SingleUse = V->getSingleUndroppableUse()) { - if (auto *GI = dyn_cast(SingleUse->getUser())) { - if (GI->getPointerOperandType() == V->getType()) { - if (Use *SingleUseGI = GI->getSingleUndroppableUse()) { - if (auto *II = - dyn_cast(SingleUseGI->getUser())) - if (II->getIntrinsicID() == Intrinsic::ptr_annotation) - PtrAnn = II; - } - if (!GEP) - GEP = GI; - } + Instruction *PtrAnn = nullptr; + llvm::Value *PtrAnnotationValue = nullptr; + + if (GEPOrUseMap.count(AllocatedTy)) { + auto Element = GEPOrUseMap[AllocatedTy]; + std::vector vec = {0, I}; + + if (Element.first == vec) { + PtrAnn = Element.second; + } else { + GEP = cast( + Builder.CreateConstInBoundsGEP2_32(AllocatedTy, AL, 0, I)); + GEPOrUseMap[AllocatedTy] = std::make_pair(vec, GEP); } - } - if (!GEP) + } else { GEP = cast( Builder.CreateConstInBoundsGEP2_32(AllocatedTy, AL, 0, I)); + std::vector vec{0, I}; + GEPOrUseMap[AllocatedTy] = std::make_pair(vec, GEP); + } Type *IntTy = nullptr; - llvm::Value *PtrAnnotationValue = nullptr; if (PtrAnn) { - IntTy = PtrAnn->getType()->getPointerElementType()->isIntegerTy() - ? PtrAnn->getType() - : Int8PtrTyPrivate; + IntTy = PtrAnn->getType(); PtrAnnotationValue = Builder.CreateBitCast(PtrAnn, IntTy, PtrAnn->getName()); } else { @@ -3587,7 +3581,11 @@ void SPIRVToLLVM::transIntelFPGADecorations(SPIRVValue *BV, Value *V) { llvm::Value *Args[] = {PtrAnnotationValue, Builder.CreateBitCast(GS, Int8PtrTyPrivate), UndefInt8Ptr, UndefInt32, UndefInt8Ptr}; - Builder.CreateCall(AnnotationFn, Args); + auto PtrAnnotationCall = Builder.CreateCall(AnnotationFn, Args); + auto Element = GEPOrUseMap[AllocatedTy]; + if (Element.first == std::vector{0,I}) { + GEPOrUseMap[AllocatedTy] = std::make_pair(std::vector{0,I} ,PtrAnnotationCall); + } } } } diff --git a/lib/SPIRV/SPIRVReader.h b/lib/SPIRV/SPIRVReader.h index b461ee43a6..9cc79ea411 100644 --- a/lib/SPIRV/SPIRVReader.h +++ b/lib/SPIRV/SPIRVReader.h @@ -155,6 +155,8 @@ class SPIRVToLLVM : private BuiltinCallHelper { typedef std::map SPIRVToLLVMLoopMetadataMap; + typedef std::unordered_map, Instruction *>> TypeToGEPOrUseMap; + private: Module *M; LLVMContext *Context; @@ -186,6 +188,8 @@ class SPIRVToLLVM : private BuiltinCallHelper { SPIRVToLLVMMDAliasInstMap MDAliasScopeMap; SPIRVToLLVMMDAliasInstMap MDAliasListMap; + TypeToGEPOrUseMap GEPOrUseMap; + Type *mapType(SPIRVType *BT, Type *T); // If a value is mapped twice, the existing mapped value is a placeholder, diff --git a/test/transcoding/multiple_user_semantic.ll b/test/transcoding/multiple_user_semantic.ll index e1f2bfeba1..ef9296c2c7 100644 --- a/test/transcoding/multiple_user_semantic.ll +++ b/test/transcoding/multiple_user_semantic.ll @@ -23,14 +23,19 @@ ; CHECK-LLVM: @[[StrB:[0-9_.]+]] = {{.*}}"var_annotation_b\00" ; CHECK-LLVM: %[[#StructMember:]] = alloca %class.Sample, align 4 ; CHECK-LLVM: %[[#GEP1:]] = getelementptr inbounds %class.Sample, %class.Sample* %[[#StructMember]], i32 0, i32 0 -; CHECK-LLVM: call i32* @llvm.ptr.annotation.p0i32(i32* %[[#GEP1:]], i8* getelementptr inbounds ([19 x i8], [19 x i8]* @[[StrStructA]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) -; CHECK-LLVM: %[[#GEP2:]] = getelementptr inbounds %class.Sample, %class.Sample* %[[#StructMember]], i32 0, i32 0 -; CHECK-LLVM: call i32* @llvm.ptr.annotation.p0i32(i32* %[[#GEP2]], i8* getelementptr inbounds ([19 x i8], [19 x i8]* @[[StrStructB]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) +; CHECK-LLVM: %[[#PtrAnn1:]] = call i32* @llvm.ptr.annotation.p0i32(i32* %[[#GEP1:]], i8* getelementptr inbounds ([19 x i8], [19 x i8]* @[[StrStructA]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) +; CHECK-LLVM: %[[#PtrAnn2:]] = call i32* @llvm.ptr.annotation.p0i32(i32* %[[#PtrAnn1]], i8* getelementptr inbounds ([19 x i8], [19 x i8]* @[[StrStructB]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) ; CHECK-LLVM: [[#Var:]] = alloca i32, align 4 ; CHECK-LLVM: [[#Bitcast1:]] = bitcast i32* %[[#Var]] to i8* ; CHECK-LLVM: call void @llvm.var.annotation(i8* %[[#Bitcast1]], i8* getelementptr inbounds ([17 x i8], [17 x i8]* @[[StrA]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) ; CHECK-LLVM: [[#Bitcast2:]] = bitcast i32* %[[#Var]] to i8* ; CHECK-LLVM: call void @llvm.var.annotation(i8* %[[#Bitcast2]], i8* getelementptr inbounds ([17 x i8], [17 x i8]* @[[StrB]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) +; CHECK-LLVM: [[#Bitcast3:]] = bitcast i32* %[[#PtrAnn2]] to i8* +; CHECK-LLVM: [[#Bitcast4:]] = bitcast i8* %[[#Bitcast3]] to i32* +; CHECK-LLVM: [[#Load1:]] = load i32, i32* %[[#Bitcast4]], align 4 +; CHECK-LLVM: call spir_func void @_Z3fooi(i32 %[[#Load1]]) +; CHECK-LLVM: [[#Load2:]] = load i32, i32* %[[#Var]], align 4 +; CHECK-LLVM: call spir_func void @_Z3fooi(i32 %[[#Load2]]) source_filename = "llvm-link" diff --git a/test/transcoding/multiple_user_semantic_nonopaque.ll b/test/transcoding/multiple_user_semantic_nonopaque.ll index c423ee798d..c53e02ee91 100644 --- a/test/transcoding/multiple_user_semantic_nonopaque.ll +++ b/test/transcoding/multiple_user_semantic_nonopaque.ll @@ -28,9 +28,8 @@ ; CHECK-LLVM: call void @llvm.var.annotation(i8* %[[#Bitcast2]], i8* getelementptr inbounds ([17 x i8], [17 x i8]* @[[StrB]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) ; CHECK-LLVM: %[[#StructMember:]] = alloca %class.Sample, align 4 ; CHECK-LLVM: %[[#GEP1:]] = getelementptr inbounds %class.Sample, %class.Sample* %[[#StructMember]], i32 0, i32 0 -; CHECK-LLVM: call i32* @llvm.ptr.annotation.p0i32(i32* %[[#GEP1:]], i8* getelementptr inbounds ([19 x i8], [19 x i8]* @[[StrStructA]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) -; CHECK-LLVM: %[[#GEP2:]] = getelementptr inbounds %class.Sample, %class.Sample* %[[#StructMember]], i32 0, i32 0 -; CHECK-LLVM: call i32* @llvm.ptr.annotation.p0i32(i32* %[[#GEP2]], i8* getelementptr inbounds ([19 x i8], [19 x i8]* @[[StrStructB]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) +; CHECK-LLVM: %[[#PtrAnn:]] = call i32* @llvm.ptr.annotation.p0i32(i32* %[[#GEP1:]], i8* getelementptr inbounds ([19 x i8], [19 x i8]* @[[StrStructA]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) +; CHECK-LLVM: call i32* @llvm.ptr.annotation.p0i32(i32* %[[#PtrAnn]], i8* getelementptr inbounds ([19 x i8], [19 x i8]* @[[StrStructB]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) source_filename = "llvm-link" From cb01ece94c2c39c5f14ac85c6bb5fa1d4a646015 Mon Sep 17 00:00:00 2001 From: "Maksimova, Viktoria" Date: Thu, 17 Nov 2022 10:00:59 -0800 Subject: [PATCH 3/8] Rework the map --- lib/SPIRV/SPIRVReader.cpp | 53 +++++++++++++++++++++------------------ lib/SPIRV/SPIRVReader.h | 6 ++++- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 8df7fe6439..f3565e9538 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -2139,21 +2139,27 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F, auto IsInbound = AC->isInBounds(); Value *V = nullptr; - if (GEPOrUseMap.count(BaseTy)) { - auto Element = GEPOrUseMap[BaseTy]; + if (GEPOrUseMap.count(Base)) { + auto Element = GEPOrUseMap[Base]; auto Idx = AC->getIndices(); + int a = Element.size(); + int b = GEPOrUseMap.size(); - if (Element.first.size() == Idx.size()) { + // In transIntelFPGADecorations we generated GEPs only for the fields of + // structure, meaning that GEP to `0` accesses the Structure itself, and + // the second `Id` is a Key in the map. + if (Idx.size() == 2) { bool IsEqual = true; - for (size_t I = 0; I < Idx.size(); I++) { - SPIRVWord Index = static_cast(getTranslatedValue(Idx[I]))->getZExtValue(); - if (Index != Element.first[I]) { - IsEqual = false; - break; - } - } + if (static_cast(getTranslatedValue(Idx[0])) + ->getZExtValue() != 0) + IsEqual = false; + if (!Element.count( + static_cast(getTranslatedValue(Idx[1])) + ->getZExtValue())) + IsEqual = false; if (IsEqual) - V = Element.second; + V = Element[static_cast(getTranslatedValue(Idx[1])) + ->getZExtValue()]; } } @@ -2165,7 +2171,8 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F, V = GEP; } } else { - V = ConstantExpr::getGetElementPtr(BaseTy, dyn_cast(Base), + if (!V) + V = ConstantExpr::getGetElementPtr(BaseTy, dyn_cast(Base), Index, IsInbound); } return mapValue(BV, V); @@ -3545,22 +3552,21 @@ void SPIRVToLLVM::transIntelFPGADecorations(SPIRVValue *BV, Value *V) { Instruction *PtrAnn = nullptr; llvm::Value *PtrAnnotationValue = nullptr; - if (GEPOrUseMap.count(AllocatedTy)) { - auto Element = GEPOrUseMap[AllocatedTy]; - std::vector vec = {0, I}; - - if (Element.first == vec) { - PtrAnn = Element.second; + if (GEPOrUseMap.count(AL)) { + auto Element = GEPOrUseMap[AL]; + int a = Element.size(); + int b = GEPOrUseMap.size(); + if (Element.count(I)) { + PtrAnn = Element[I]; } else { GEP = cast( Builder.CreateConstInBoundsGEP2_32(AllocatedTy, AL, 0, I)); - GEPOrUseMap[AllocatedTy] = std::make_pair(vec, GEP); + Element.emplace(I, GEP); } } else { GEP = cast( Builder.CreateConstInBoundsGEP2_32(AllocatedTy, AL, 0, I)); - std::vector vec{0, I}; - GEPOrUseMap[AllocatedTy] = std::make_pair(vec, GEP); + GEPOrUseMap[AL].emplace(I, GEP); } Type *IntTy = nullptr; @@ -3582,10 +3588,7 @@ void SPIRVToLLVM::transIntelFPGADecorations(SPIRVValue *BV, Value *V) { Builder.CreateBitCast(GS, Int8PtrTyPrivate), UndefInt8Ptr, UndefInt32, UndefInt8Ptr}; auto PtrAnnotationCall = Builder.CreateCall(AnnotationFn, Args); - auto Element = GEPOrUseMap[AllocatedTy]; - if (Element.first == std::vector{0,I}) { - GEPOrUseMap[AllocatedTy] = std::make_pair(std::vector{0,I} ,PtrAnnotationCall); - } + GEPOrUseMap[AL][I] = PtrAnnotationCall; } } } diff --git a/lib/SPIRV/SPIRVReader.h b/lib/SPIRV/SPIRVReader.h index 9cc79ea411..0b8b5eec4a 100644 --- a/lib/SPIRV/SPIRVReader.h +++ b/lib/SPIRV/SPIRVReader.h @@ -155,7 +155,11 @@ class SPIRVToLLVM : private BuiltinCallHelper { typedef std::map SPIRVToLLVMLoopMetadataMap; - typedef std::unordered_map, Instruction *>> TypeToGEPOrUseMap; + // Store all the allocations to Struct Types that are further + // accessed inside GetElementPtr instruction or in ptr.annotation intrinsics. + // For every structure we save the accessed structure field index and the + // last corresponding translated LLVM instruction. + typedef std::unordered_map > TypeToGEPOrUseMap; private: Module *M; From a41b99e798412e3e53e39434adef01ba4c9cee73 Mon Sep 17 00:00:00 2001 From: "Maksimova, Viktoria" Date: Wed, 7 Dec 2022 07:34:36 -0800 Subject: [PATCH 4/8] Added new test --- .../multiple_user_semantic_on_struct.ll | 190 ++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 test/transcoding/multiple_user_semantic_on_struct.ll diff --git a/test/transcoding/multiple_user_semantic_on_struct.ll b/test/transcoding/multiple_user_semantic_on_struct.ll new file mode 100644 index 0000000000..a74ec93884 --- /dev/null +++ b/test/transcoding/multiple_user_semantic_on_struct.ll @@ -0,0 +1,190 @@ +; This test is intended to check that we are actually using the +; ptr.annotation intrinsic call results during the reverse translation. + +; Source (https://godbolt.org/z/qzhsKfPeq): +; class B { +; public: +; int Val [[clang::annotate("ClassB")]]; +; }; +; class A { +; public: +; int Val [[clang::annotate("ClassA")]]; +; int MultiDec [[clang::annotate("Dec1"), clang::annotate("Dec2"), clang::annotate("Dec3")]]; +; [[clang::annotate("ClassAfieldB")]]class B b; +; }; +; void foo(int); +; int main() { +; A a; +; B b; +; A c; +; foo(a.Val); // ClassA +; foo(c.Val); // Obj2ClassA +; foo(a.MultiDec); // ClassAMultiDec +; foo(a.b.Val); // ClassAFieldB +; foo(b.Val); // ClassB +; return 0; +; } + + +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv %t.bc -spirv-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV + +; RUN: llvm-spirv %t.bc -o %t.spv +; RUN: llvm-spirv -r %t.spv -o %t.rev.bc +; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM + +; Check that even when FPGA memory extensions are enabled - yet we have +; UserSemantic decoration be generated +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_fpga_memory_accesses,+SPV_INTEL_fpga_memory_attributes -spirv-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV + +; CHECK-SPIRV: Name [[#ClassA:]] "class.A" +; CHECK-SPIRV: Name [[#ClassB:]] "class.B" +; CHECK-SPIRV: MemberDecorate [[#ClassA]] 0 UserSemantic "ClassA" +; CHECK-SPIRV: MemberDecorate [[#ClassA]] 0 UserSemantic "ClassA" +; CHECK-SPIRV: MemberDecorate [[#ClassA]] 1 UserSemantic "Dec1" +; CHECK-SPIRV: MemberDecorate [[#ClassA]] 1 UserSemantic "Dec2" +; CHECK-SPIRV: MemberDecorate [[#ClassA]] 1 UserSemantic "Dec3" +; CHECK-SPIRV: MemberDecorate [[#ClassA]] 2 UserSemantic "ClassAfieldB" +; CHECK-SPIRV: MemberDecorate [[#ClassB]] 0 UserSemantic "ClassB" +; CHECK-SPIRV: MemberDecorate [[#ClassB]] 0 UserSemantic "ClassB" + +; CHECK-LLVM: @[[#StrStructA:]] = {{.*}}"ClassA\00" +; CHECK-LLVM: @[[#StrStructA2:]] = {{.*}}"ClassA\00" +; CHECK-LLVM: @[[#Dec1:]] = {{.*}}"Dec1\00" +; CHECK-LLVM: @[[#Dec2:]] = {{.*}}"Dec2\00" +; CHECK-LLVM: @[[#Dec3:]] = {{.*}}"Dec3\00" +; CHECK-LLVM: @[[#StrAfieldB:]] = {{.*}}"ClassAfieldB\00" +; CHECK-LLVM: @[[#StrStructB:]] = {{.*}}"ClassB\00" +; CHECK-LLVM: @[[#StrStructB2:]] = {{.*}}"ClassB\00" +; CHECK-LLVM: @[[#StrObj2StructA:]] = {{.*}}"ClassA\00" +; CHECK-LLVM: @[[#StrObj2StructA2:]] = {{.*}}"ClassA\00" + +; CHECK-LLVM: %[[#ObjClassA:]] = alloca %class.A, align 4 +; CHECK-LLVM: %[[#GepClassAVal:]] = getelementptr inbounds %class.A, %class.A* %[[#ObjClassA]], i32 0, i32 0 +; CHECK-LLVM: %[[#PtrAnnClassAVal:]] = call i32* @llvm.ptr.annotation.p0i32(i32* %[[#GepClassAVal]], i8* getelementptr inbounds ([7 x i8], [7 x i8]* @[[#StrStructA]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) +; CHECK-LLVM: %[[#PtrAnn2ClassAVal:]] = call i32* @llvm.ptr.annotation.p0i32(i32* %[[#PtrAnnClassAVal]], i8* getelementptr inbounds ([7 x i8], [7 x i8]* @[[#StrStructA2]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) + +; CHECK-LLVM: %[[#GepMultiDec:]] = getelementptr inbounds %class.A, %class.A* %[[#ObjClassA]], i32 0, i32 1 +; CHECK-LLVM: %[[#PtrAnnMultiDec:]] = call i32* @llvm.ptr.annotation.p0i32(i32* %[[#GepMultiDec]], i8* getelementptr inbounds ([5 x i8], [5 x i8]* @[[#Dec1]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) +; CHECK-LLVM: %[[#PtrAnn2MultiDec:]] = call i32* @llvm.ptr.annotation.p0i32(i32* %[[#PtrAnnMultiDec]], i8* getelementptr inbounds ([5 x i8], [5 x i8]* @[[#Dec2]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) +; CHECK-LLVM: %[[#PtrAnn3MultiDec:]] = call i32* @llvm.ptr.annotation.p0i32(i32* %[[#PtrAnn2MultiDec]], i8* getelementptr inbounds ([5 x i8], [5 x i8]* @[[#Dec3]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) + +; CHECK-LLVM: %[[#GepClassAFieldB:]] = getelementptr inbounds %class.A, %class.A* %[[#ObjClassA]], i32 0, i32 2 +; CHECK-LLVM: %[[#CastClassAFieldB:]] = bitcast %class.B* %[[#GepClassAFieldB]] to i8* +; CHECK-LLVM: %[[#PtrAnnClassAFieldB:]] = call i8* @llvm.ptr.annotation.p0i8(i8* %[[#CastClassAFieldB]], i8* getelementptr inbounds ([13 x i8], [13 x i8]* @[[#StrAfieldB]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) + +; CHECK-LLVM: %[[#ObjClassB:]] = alloca %class.B, align 4 +; CHECK-LLVM: %[[#GEPClassB:]] = getelementptr inbounds %class.B, %class.B* %[[#ObjClassB]], i32 0, i32 0 +; CHECK-LLVM: %[[#PtrAnnClassB:]] = call i32* @llvm.ptr.annotation.p0i32(i32* %[[#GEPClassB]], i8* getelementptr inbounds ([7 x i8], [7 x i8]* @[[#StrStructB]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) +; CHECK-LLVM: %[[#PtrAnn2ClassB:]] = call i32* @llvm.ptr.annotation.p0i32(i32* %[[#PtrAnnClassB]], i8* getelementptr inbounds ([7 x i8], [7 x i8]* @[[#StrStructB2]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) + +; CHECK-LLVM: %[[#Obj2ClassA:]] = alloca %class.A, align 4 +; CHECK-LLVM: %[[#GepObj2ClassA:]] = getelementptr inbounds %class.A, %class.A* %[[#Obj2ClassA]], i32 0, i32 0 +; CHECK-LLVM: %[[#PtrAnnObj2ClassA:]] = call i32* @llvm.ptr.annotation.p0i32(i32* %[[#GepObj2ClassA]], i8* getelementptr inbounds ([7 x i8], [7 x i8]* @[[#StrObj2StructA]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) +; CHECK-LLVM: %[[#PtrAnn2Obj2ClassA:]] = call i32* @llvm.ptr.annotation.p0i32(i32* %[[#PtrAnnObj2ClassA]], i8* getelementptr inbounds ([7 x i8], [7 x i8]* @[[#StrObj2StructA2]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) + + +; CHECK-LLVM: %[[#CastClassAVal:]] = bitcast i32* %[[#PtrAnn2ClassAVal]] to i8* +; CHECK-LLVM: %[[#LoadClassAVal:]] = bitcast i8* %[[#CastClassAVal]] to i32* +; CHECK-LLVM: %[[#CallClassA:]] = load i32, i32* %[[#LoadClassAVal]], align 4 +; CHECK-LLVM: call spir_func void @_Z3fooi(i32 %[[#CallClassA]]) + +; CHECK-LLVM: %[[#CastObj2ClassA:]] = bitcast i32* %[[#PtrAnn2Obj2ClassA]] to i8* +; CHECK-LLVM: %[[#LoadObj2ClassA:]] = bitcast i8* %[[#CastObj2ClassA]] to i32* +; CHECK-LLVM: %[[#CallObj2ClassA:]] = load i32, i32* %[[#LoadObj2ClassA]], align 4 +; CHECK-LLVM: call spir_func void @_Z3fooi(i32 %[[#CallObj2ClassA]]) + +; CHECK-LLVM: %[[#CastMultiDec:]] = bitcast i32* %[[#PtrAnn3MultiDec]] to i8* +; CHECK-LLVM: %[[#CastMultiDec1:]] = bitcast i8* %[[#CastMultiDec]] to i32* +; CHECK-LLVM: %[[#CastMultiDec2:]] = bitcast i32* %[[#CastMultiDec1]] to i8* +; CHECK-LLVM: %[[#CastMultiDec3:]] = bitcast i8* %[[#CastMultiDec2]] to i32* +; CHECK-LLVM: %[[#CastMultiDec4:]] = bitcast i32* %[[#CastMultiDec3]] to i8* +; CHECK-LLVM: %[[#LoadMultiDec:]] = bitcast i8* %[[#CastMultiDec4]] to i32* +; CHECK-LLVM: %[[#CallClassAMultiDec:]] = load i32, i32* %[[#LoadMultiDec]], align 4 +; CHECK-LLVM: call spir_func void @_Z3fooi(i32 %[[#CallClassAMultiDec]]) + +; CHECK-LLVM: %[[#CastClassAFieldB:]] = bitcast i8* %[[#PtrAnnClassAFieldB]] to i8* +; CHECK-LLVM: %[[#Cast2ClassAFieldB:]] = bitcast i8* %[[#CastClassAFieldB]] to %class.B* +; CHECK-LLVM: %[[#GEPClassB:]] = getelementptr inbounds %class.B, %class.B* %[[#Cast2ClassAFieldB]], i32 0, i32 0 +; CHECK-LLVM: %[[#CastClassB:]] = bitcast i32* %[[#GEPClassB]] to i8* +; CHECK-LLVM: %[[#Cast2ClassB:]] = bitcast i8* %[[#CastClassB]] to i32* +; CHECK-LLVM: %[[#CallClassAFieldB:]] = load i32, i32* %[[#Cast2ClassB]], align 4 +; CHECK-LLVM: call spir_func void @_Z3fooi(i32 %[[#CallClassAFieldB]]) + +; CHECK-LLVM: %[[#CastClassB:]] = bitcast i32* %[[#PtrAnn2ClassB]] to i8* +; CHECK-LLVM: %[[#Cast2ClassB:]] = bitcast i8* %[[#CastClassB]] to i32* +; CHECK-LLVM: %[[#CallClassB:]] = load i32, i32* %[[#Cast2ClassB]], align 4 +; CHECK-LLVM: call spir_func void @_Z3fooi(i32 %[[#CallClassB]]) + +target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" +target triple = "spir64" + +%class.A = type { i32, i32, %class.B } +%class.B = type { i32 } + +@.str = private unnamed_addr constant [7 x i8] c"ClassA\00", section "llvm.metadata" +@.str.1 = private unnamed_addr constant [17 x i8] c"/app/example.cpp\00", section "llvm.metadata" +@.str.2 = private unnamed_addr constant [5 x i8] c"Dec1\00", section "llvm.metadata" +@.str.3 = private unnamed_addr constant [5 x i8] c"Dec2\00", section "llvm.metadata" +@.str.4 = private unnamed_addr constant [5 x i8] c"Dec3\00", section "llvm.metadata" +@.str.5 = private unnamed_addr constant [13 x i8] c"ClassAfieldB\00", section "llvm.metadata" +@.str.6 = private unnamed_addr constant [7 x i8] c"ClassB\00", section "llvm.metadata" + +define dso_local noundef i32 @main() #0 { + %1 = alloca i32, align 4 + %2 = alloca %class.A, align 4 + %3 = alloca %class.B, align 4 + %4 = alloca %class.A, align 4 + store i32 0, i32* %1, align 4 + %5 = getelementptr inbounds %class.A, %class.A* %2, i32 0, i32 0 + %6 = bitcast i32* %5 to i8* + %7 = call i8* @llvm.ptr.annotation.p0i8(i8* %6, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i32 12, i8* null) + %8 = bitcast i8* %7 to i32* + %9 = load i32, i32* %8, align 4 + call void @_Z3fooi(i32 noundef %9) + %10 = getelementptr inbounds %class.A, %class.A* %4, i32 0, i32 0 + %11 = bitcast i32* %10 to i8* + %12 = call i8* @llvm.ptr.annotation.p0i8(i8* %11, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i32 12, i8* null) + %13 = bitcast i8* %12 to i32* + %14 = load i32, i32* %13, align 4 + call void @_Z3fooi(i32 noundef %14) + %15 = getelementptr inbounds %class.A, %class.A* %2, i32 0, i32 1 + %16 = bitcast i32* %15 to i8* + %17 = call i8* @llvm.ptr.annotation.p0i8(i8* %16, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.2, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i32 13, i8* null) + %18 = bitcast i8* %17 to i32* + %19 = bitcast i32* %18 to i8* + %20 = call i8* @llvm.ptr.annotation.p0i8(i8* %19, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.3, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i32 13, i8* null) + %21 = bitcast i8* %20 to i32* + %22 = bitcast i32* %21 to i8* + %23 = call i8* @llvm.ptr.annotation.p0i8(i8* %22, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.4, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i32 13, i8* null) + %24 = bitcast i8* %23 to i32* + %25 = load i32, i32* %24, align 4 + call void @_Z3fooi(i32 noundef %25) + %26 = getelementptr inbounds %class.A, %class.A* %2, i32 0, i32 2 + %27 = bitcast %class.B* %26 to i8* + %28 = call i8* @llvm.ptr.annotation.p0i8(i8* %27, i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.5, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i32 14, i8* null) + %29 = bitcast i8* %28 to %class.B* + %30 = getelementptr inbounds %class.B, %class.B* %29, i32 0, i32 0 + %31 = bitcast i32* %30 to i8* + %32 = call i8* @llvm.ptr.annotation.p0i8(i8* %31, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.6, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i32 6, i8* null) + %33 = bitcast i8* %32 to i32* + %34 = load i32, i32* %33, align 4 + call void @_Z3fooi(i32 noundef %34) + %35 = getelementptr inbounds %class.B, %class.B* %3, i32 0, i32 0 + %36 = bitcast i32* %35 to i8* + %37 = call i8* @llvm.ptr.annotation.p0i8(i8* %36, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.6, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i32 6, i8* null) + %38 = bitcast i8* %37 to i32* + %39 = load i32, i32* %38, align 4 + call void @_Z3fooi(i32 noundef %39) + ret i32 0 +} + +declare void @_Z3fooi(i32 noundef) #2 + +declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32, i8*) #3 + +attributes #0 = { mustprogress noinline norecurse optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } +attributes #2 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } \ No newline at end of file From 40bb2a92ce750934cfd7190f0cb483204557f385 Mon Sep 17 00:00:00 2001 From: "Maksimova, Viktoria" Date: Wed, 7 Dec 2022 09:04:13 -0800 Subject: [PATCH 5/8] Rework --- lib/SPIRV/SPIRVReader.cpp | 83 +++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 48 deletions(-) diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index f3565e9538..f63a7270fa 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -2140,39 +2140,34 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F, Value *V = nullptr; if (GEPOrUseMap.count(Base)) { - auto Element = GEPOrUseMap[Base]; + auto IdxToInstMap = GEPOrUseMap[Base]; auto Idx = AC->getIndices(); - int a = Element.size(); - int b = GEPOrUseMap.size(); // In transIntelFPGADecorations we generated GEPs only for the fields of // structure, meaning that GEP to `0` accesses the Structure itself, and // the second `Id` is a Key in the map. if (Idx.size() == 2) { - bool IsEqual = true; - if (static_cast(getTranslatedValue(Idx[0])) - ->getZExtValue() != 0) - IsEqual = false; - if (!Element.count( - static_cast(getTranslatedValue(Idx[1])) - ->getZExtValue())) - IsEqual = false; - if (IsEqual) - V = Element[static_cast(getTranslatedValue(Idx[1])) - ->getZExtValue()]; + unsigned Idx1 = static_cast(getTranslatedValue(Idx[0])) + ->getZExtValue(); + if (Idx1 == 0) { + unsigned Idx2 = static_cast(getTranslatedValue(Idx[1])) + ->getZExtValue(); + + // If we already have the instruction in a map, use it. + if (IdxToInstMap.count(Idx2)) + return mapValue(BV, IdxToInstMap[Idx2]); + } } } if (BB) { - if (!V) { - auto GEP = - GetElementPtrInst::Create(BaseTy, Base, Index, BV->getName(), BB); - GEP->setIsInBounds(IsInbound); - V = GEP; - } + auto GEP = + GetElementPtrInst::Create(BaseTy, Base, Index, BV->getName(), BB); + GEP->setIsInBounds(IsInbound); + V = GEP; + } else { - if (!V) - V = ConstantExpr::getGetElementPtr(BaseTy, dyn_cast(Base), + V = ConstantExpr::getGetElementPtr(BaseTy, dyn_cast(Base), Index, IsInbound); } return mapValue(BV, V); @@ -3548,45 +3543,37 @@ void SPIRVToLLVM::transIntelFPGADecorations(SPIRVValue *BV, Value *V) { for (auto AnnotStr : AnnotStrVec) { auto *GS = Builder.CreateGlobalStringPtr(AnnotStr); - GetElementPtrInst *GEP = nullptr; - Instruction *PtrAnn = nullptr; - llvm::Value *PtrAnnotationValue = nullptr; + Instruction *PtrAnnFirstArg = nullptr; if (GEPOrUseMap.count(AL)) { - auto Element = GEPOrUseMap[AL]; - int a = Element.size(); - int b = GEPOrUseMap.size(); - if (Element.count(I)) { - PtrAnn = Element[I]; - } else { - GEP = cast( - Builder.CreateConstInBoundsGEP2_32(AllocatedTy, AL, 0, I)); - Element.emplace(I, GEP); + auto IdxToInstMap = GEPOrUseMap[AL]; + if (IdxToInstMap.count(I)) { + PtrAnnFirstArg = IdxToInstMap[I]; } - } else { - GEP = cast( - Builder.CreateConstInBoundsGEP2_32(AllocatedTy, AL, 0, I)); - GEPOrUseMap[AL].emplace(I, GEP); } Type *IntTy = nullptr; - if (PtrAnn) { - IntTy = PtrAnn->getType(); - PtrAnnotationValue = - Builder.CreateBitCast(PtrAnn, IntTy, PtrAnn->getName()); - } else { + + if (!PtrAnnFirstArg) { + GetElementPtrInst* GEP = cast( + Builder.CreateConstInBoundsGEP2_32(AllocatedTy, AL, 0, I)); + IntTy = GEP->getResultElementType()->isIntegerTy() ? GEP->getType() : Int8PtrTyPrivate; - PtrAnnotationValue = - Builder.CreateBitCast(GEP, IntTy, GEP->getName()); + PtrAnnFirstArg = GEP; + } else { + IntTy = PtrAnnFirstArg->getType(); } + auto AnnotationFn = llvm::Intrinsic::getDeclaration( M, Intrinsic::ptr_annotation, IntTy); - llvm::Value *Args[] = {PtrAnnotationValue, - Builder.CreateBitCast(GS, Int8PtrTyPrivate), - UndefInt8Ptr, UndefInt32, UndefInt8Ptr}; + llvm::Value *Args[] = { + Builder.CreateBitCast(PtrAnnFirstArg, IntTy, + PtrAnnFirstArg->getName()), + Builder.CreateBitCast(GS, Int8PtrTyPrivate), UndefInt8Ptr, + UndefInt32, UndefInt8Ptr}; auto PtrAnnotationCall = Builder.CreateCall(AnnotationFn, Args); GEPOrUseMap[AL][I] = PtrAnnotationCall; } From f482fca9dcc35b92ae5d44964d6f6652014cfde0 Mon Sep 17 00:00:00 2001 From: "Maksimova, Viktoria" Date: Wed, 7 Dec 2022 09:14:36 -0800 Subject: [PATCH 6/8] Fix clang-tidy and format errors --- lib/SPIRV/SPIRVReader.cpp | 6 +++--- lib/SPIRV/SPIRVReader.h | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index f63a7270fa..289ce14108 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -3555,9 +3555,9 @@ void SPIRVToLLVM::transIntelFPGADecorations(SPIRVValue *BV, Value *V) { Type *IntTy = nullptr; if (!PtrAnnFirstArg) { - GetElementPtrInst* GEP = cast( + GetElementPtrInst *GEP = cast( Builder.CreateConstInBoundsGEP2_32(AllocatedTy, AL, 0, I)); - + IntTy = GEP->getResultElementType()->isIntegerTy() ? GEP->getType() : Int8PtrTyPrivate; @@ -3574,7 +3574,7 @@ void SPIRVToLLVM::transIntelFPGADecorations(SPIRVValue *BV, Value *V) { PtrAnnFirstArg->getName()), Builder.CreateBitCast(GS, Int8PtrTyPrivate), UndefInt8Ptr, UndefInt32, UndefInt8Ptr}; - auto PtrAnnotationCall = Builder.CreateCall(AnnotationFn, Args); + auto *PtrAnnotationCall = Builder.CreateCall(AnnotationFn, Args); GEPOrUseMap[AL][I] = PtrAnnotationCall; } } diff --git a/lib/SPIRV/SPIRVReader.h b/lib/SPIRV/SPIRVReader.h index 0b8b5eec4a..b899593ecd 100644 --- a/lib/SPIRV/SPIRVReader.h +++ b/lib/SPIRV/SPIRVReader.h @@ -159,7 +159,9 @@ class SPIRVToLLVM : private BuiltinCallHelper { // accessed inside GetElementPtr instruction or in ptr.annotation intrinsics. // For every structure we save the accessed structure field index and the // last corresponding translated LLVM instruction. - typedef std::unordered_map > TypeToGEPOrUseMap; + typedef std::unordered_map> + TypeToGEPOrUseMap; private: Module *M; From fc2e28bf1ea2e916702bbaddf7d04ee73d1cb2c6 Mon Sep 17 00:00:00 2001 From: "Maksimova, Viktoria" Date: Wed, 28 Dec 2022 07:40:09 -0800 Subject: [PATCH 7/8] Update test to check opaque pointers instead --- .../multiple_user_semantic_on_struct.ll | 140 ++++++++---------- 1 file changed, 60 insertions(+), 80 deletions(-) diff --git a/test/transcoding/multiple_user_semantic_on_struct.ll b/test/transcoding/multiple_user_semantic_on_struct.ll index 7119496697..ccc9aab3cb 100644 --- a/test/transcoding/multiple_user_semantic_on_struct.ll +++ b/test/transcoding/multiple_user_semantic_on_struct.ll @@ -61,60 +61,56 @@ ; CHECK-LLVM: @[[#StrObj2StructA2:]] = {{.*}}"ClassA\00" ; CHECK-LLVM: %[[#ObjClassA:]] = alloca %class.A, align 4 -; CHECK-LLVM: %[[#GepClassAVal:]] = getelementptr inbounds %class.A, %class.A* %[[#ObjClassA]], i32 0, i32 0 -; CHECK-LLVM: %[[#PtrAnnClassAVal:]] = call i32* @llvm.ptr.annotation.p0i32.p0i8(i32* %[[#GepClassAVal]], i8* getelementptr inbounds ([7 x i8], [7 x i8]* @[[#StrStructA]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) -; CHECK-LLVM: %[[#PtrAnn2ClassAVal:]] = call i32* @llvm.ptr.annotation.p0i32.p0i8(i32* %[[#PtrAnnClassAVal]], i8* getelementptr inbounds ([7 x i8], [7 x i8]* @[[#StrStructA2]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) +; CHECK-LLVM: %[[#GepClassAVal:]] = getelementptr inbounds %class.A, ptr %[[#ObjClassA]], i32 0, i32 0 +; CHECK-LLVM: %[[#PtrAnnClassAVal:]] = call ptr @llvm.ptr.annotation.p0.p0(ptr %[[#GepClassAVal]], ptr @[[#StrStructA]], ptr undef, i32 undef, ptr undef) +; CHECK-LLVM: %[[#PtrAnn2ClassAVal:]] = call ptr @llvm.ptr.annotation.p0.p0(ptr %[[#PtrAnnClassAVal]], ptr @[[#StrStructA2]], ptr undef, i32 undef, ptr undef) -; CHECK-LLVM: %[[#GepMultiDec:]] = getelementptr inbounds %class.A, %class.A* %[[#ObjClassA]], i32 0, i32 1 -; CHECK-LLVM: %[[#PtrAnnMultiDec:]] = call i32* @llvm.ptr.annotation.p0i32.p0i8(i32* %[[#GepMultiDec]], i8* getelementptr inbounds ([5 x i8], [5 x i8]* @[[#Dec1]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) -; CHECK-LLVM: %[[#PtrAnn2MultiDec:]] = call i32* @llvm.ptr.annotation.p0i32.p0i8(i32* %[[#PtrAnnMultiDec]], i8* getelementptr inbounds ([5 x i8], [5 x i8]* @[[#Dec2]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) -; CHECK-LLVM: %[[#PtrAnn3MultiDec:]] = call i32* @llvm.ptr.annotation.p0i32.p0i8(i32* %[[#PtrAnn2MultiDec]], i8* getelementptr inbounds ([5 x i8], [5 x i8]* @[[#Dec3]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) +; CHECK-LLVM: %[[#GepMultiDec:]] = getelementptr inbounds %class.A, ptr %[[#ObjClassA]], i32 0, i32 1 +; CHECK-LLVM: %[[#PtrAnnMultiDec:]] = call ptr @llvm.ptr.annotation.p0.p0(ptr %[[#GepMultiDec]], ptr @[[#Dec1]], ptr undef, i32 undef, ptr undef) +; CHECK-LLVM: %[[#PtrAnn2MultiDec:]] = call ptr @llvm.ptr.annotation.p0.p0(ptr %[[#PtrAnnMultiDec]], ptr @[[#Dec2]], ptr undef, i32 undef, ptr undef) +; CHECK-LLVM: %[[#PtrAnn3MultiDec:]] = call ptr @llvm.ptr.annotation.p0.p0(ptr %[[#PtrAnn2MultiDec]], ptr @[[#Dec3]], ptr undef, i32 undef, ptr undef) -; CHECK-LLVM: %[[#GepClassAFieldB:]] = getelementptr inbounds %class.A, %class.A* %[[#ObjClassA]], i32 0, i32 2 -; CHECK-LLVM: %[[#CastClassAFieldB:]] = bitcast %class.B* %[[#GepClassAFieldB]] to i8* -; CHECK-LLVM: %[[#PtrAnnClassAFieldB:]] = call i8* @llvm.ptr.annotation.p0i8.p0i8(i8* %[[#CastClassAFieldB]], i8* getelementptr inbounds ([13 x i8], [13 x i8]* @[[#StrAfieldB]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) +; CHECK-LLVM: %[[#GepClassAFieldB:]] = getelementptr inbounds %class.A, ptr %[[#ObjClassA]], i32 0, i32 2 +; CHECK-LLVM: %[[#CastClassAFieldB:]] = bitcast ptr %[[#GepClassAFieldB]] to ptr +; CHECK-LLVM: %[[#PtrAnnClassAFieldB:]] = call ptr @llvm.ptr.annotation.p0.p0(ptr %[[#CastClassAFieldB]], ptr @[[#StrAfieldB]], ptr undef, i32 undef, ptr undef) ; CHECK-LLVM: %[[#ObjClassB:]] = alloca %class.B, align 4 -; CHECK-LLVM: %[[#GEPClassB:]] = getelementptr inbounds %class.B, %class.B* %[[#ObjClassB]], i32 0, i32 0 -; CHECK-LLVM: %[[#PtrAnnClassB:]] = call i32* @llvm.ptr.annotation.p0i32.p0i8(i32* %[[#GEPClassB]], i8* getelementptr inbounds ([7 x i8], [7 x i8]* @[[#StrStructB]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) -; CHECK-LLVM: %[[#PtrAnn2ClassB:]] = call i32* @llvm.ptr.annotation.p0i32.p0i8(i32* %[[#PtrAnnClassB]], i8* getelementptr inbounds ([7 x i8], [7 x i8]* @[[#StrStructB2]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) +; CHECK-LLVM: %[[#GEPClassB:]] = getelementptr inbounds %class.B, ptr %[[#ObjClassB]], i32 0, i32 0 +; CHECK-LLVM: %[[#PtrAnnClassB:]] = call ptr @llvm.ptr.annotation.p0.p0(ptr %[[#GEPClassB]], ptr @[[#StrStructB]], ptr undef, i32 undef, ptr undef) +; CHECK-LLVM: %[[#PtrAnn2ClassB:]] = call ptr @llvm.ptr.annotation.p0.p0(ptr %[[#PtrAnnClassB]], ptr @[[#StrStructB2]], ptr undef, i32 undef, ptr undef) ; CHECK-LLVM: %[[#Obj2ClassA:]] = alloca %class.A, align 4 -; CHECK-LLVM: %[[#GepObj2ClassA:]] = getelementptr inbounds %class.A, %class.A* %[[#Obj2ClassA]], i32 0, i32 0 -; CHECK-LLVM: %[[#PtrAnnObj2ClassA:]] = call i32* @llvm.ptr.annotation.p0i32.p0i8(i32* %[[#GepObj2ClassA]], i8* getelementptr inbounds ([7 x i8], [7 x i8]* @[[#StrObj2StructA]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) -; CHECK-LLVM: %[[#PtrAnn2Obj2ClassA:]] = call i32* @llvm.ptr.annotation.p0i32.p0i8(i32* %[[#PtrAnnObj2ClassA]], i8* getelementptr inbounds ([7 x i8], [7 x i8]* @[[#StrObj2StructA2]], i32 0, i32 0), i8* undef, i32 undef, i8* undef) +; CHECK-LLVM: %[[#GepObj2ClassA:]] = getelementptr inbounds %class.A, ptr %[[#Obj2ClassA]], i32 0, i32 0 +; CHECK-LLVM: %[[#PtrAnnObj2ClassA:]] = call ptr @llvm.ptr.annotation.p0.p0(ptr %[[#GepObj2ClassA]], ptr @[[#StrObj2StructA]], ptr undef, i32 undef, ptr undef) +; CHECK-LLVM: %[[#PtrAnn2Obj2ClassA:]] = call ptr @llvm.ptr.annotation.p0.p0(ptr %[[#PtrAnnObj2ClassA]], ptr @[[#StrObj2StructA2]], ptr undef, i32 undef, ptr undef) -; CHECK-LLVM: %[[#CastClassAVal:]] = bitcast i32* %[[#PtrAnn2ClassAVal]] to i8* -; CHECK-LLVM: %[[#LoadClassAVal:]] = bitcast i8* %[[#CastClassAVal]] to i32* -; CHECK-LLVM: %[[#CallClassA:]] = load i32, i32* %[[#LoadClassAVal]], align 4 +; CHECK-LLVM: %[[#CastClassAVal:]] = bitcast ptr %[[#PtrAnn2ClassAVal]] to ptr +; CHECK-LLVM: %[[#LoadClassAVal:]] = bitcast ptr %[[#CastClassAVal]] to ptr +; CHECK-LLVM: %[[#CallClassA:]] = load i32, ptr %[[#LoadClassAVal]], align 4 ; CHECK-LLVM: call spir_func void @_Z3fooi(i32 %[[#CallClassA]]) -; CHECK-LLVM: %[[#CastObj2ClassA:]] = bitcast i32* %[[#PtrAnn2Obj2ClassA]] to i8* -; CHECK-LLVM: %[[#LoadObj2ClassA:]] = bitcast i8* %[[#CastObj2ClassA]] to i32* -; CHECK-LLVM: %[[#CallObj2ClassA:]] = load i32, i32* %[[#LoadObj2ClassA]], align 4 +; CHECK-LLVM: %[[#CastObj2ClassA:]] = bitcast ptr %[[#PtrAnn2Obj2ClassA]] to ptr +; CHECK-LLVM: %[[#LoadObj2ClassA:]] = bitcast ptr %[[#CastObj2ClassA]] to ptr +; CHECK-LLVM: %[[#CallObj2ClassA:]] = load i32, ptr %[[#LoadObj2ClassA]], align 4 ; CHECK-LLVM: call spir_func void @_Z3fooi(i32 %[[#CallObj2ClassA]]) -; CHECK-LLVM: %[[#CastMultiDec:]] = bitcast i32* %[[#PtrAnn3MultiDec]] to i8* -; CHECK-LLVM: %[[#CastMultiDec1:]] = bitcast i8* %[[#CastMultiDec]] to i32* -; CHECK-LLVM: %[[#CastMultiDec2:]] = bitcast i32* %[[#CastMultiDec1]] to i8* -; CHECK-LLVM: %[[#CastMultiDec3:]] = bitcast i8* %[[#CastMultiDec2]] to i32* -; CHECK-LLVM: %[[#CastMultiDec4:]] = bitcast i32* %[[#CastMultiDec3]] to i8* -; CHECK-LLVM: %[[#LoadMultiDec:]] = bitcast i8* %[[#CastMultiDec4]] to i32* -; CHECK-LLVM: %[[#CallClassAMultiDec:]] = load i32, i32* %[[#LoadMultiDec]], align 4 +; CHECK-LLVM: %[[#CastMultiDec:]] = bitcast ptr %[[#PtrAnn3MultiDec]] to ptr +; CHECK-LLVM: %[[#LoadMultiDec:]] = bitcast ptr %[[#CastMultiDec]] to ptr +; CHECK-LLVM: %[[#CallClassAMultiDec:]] = load i32, ptr %[[#LoadMultiDec]], align 4 ; CHECK-LLVM: call spir_func void @_Z3fooi(i32 %[[#CallClassAMultiDec]]) -; CHECK-LLVM: %[[#CastClassAFieldB:]] = bitcast i8* %[[#PtrAnnClassAFieldB]] to i8* -; CHECK-LLVM: %[[#Cast2ClassAFieldB:]] = bitcast i8* %[[#CastClassAFieldB]] to %class.B* -; CHECK-LLVM: %[[#GEPClassB:]] = getelementptr inbounds %class.B, %class.B* %[[#Cast2ClassAFieldB]], i32 0, i32 0 -; CHECK-LLVM: %[[#CastClassB:]] = bitcast i32* %[[#GEPClassB]] to i8* -; CHECK-LLVM: %[[#Cast2ClassB:]] = bitcast i8* %[[#CastClassB]] to i32* -; CHECK-LLVM: %[[#CallClassAFieldB:]] = load i32, i32* %[[#Cast2ClassB]], align 4 +; CHECK-LLVM: %[[#CastClassAFieldB:]] = bitcast ptr %[[#PtrAnnClassAFieldB]] to ptr +; CHECK-LLVM: %[[#Cast2ClassAFieldB:]] = bitcast ptr %[[#CastClassAFieldB]] to ptr +; CHECK-LLVM: %[[#GEPClassB:]] = getelementptr inbounds %class.B, ptr %[[#Cast2ClassAFieldB]], i32 0, i32 0 +; CHECK-LLVM: %[[#CastClassB:]] = bitcast ptr %[[#GEPClassB]] to ptr +; CHECK-LLVM: %[[#Cast2ClassB:]] = bitcast ptr %[[#CastClassB]] to ptr +; CHECK-LLVM: %[[#CallClassAFieldB:]] = load i32, ptr %[[#Cast2ClassB]], align 4 ; CHECK-LLVM: call spir_func void @_Z3fooi(i32 %[[#CallClassAFieldB]]) -; CHECK-LLVM: %[[#CastClassB:]] = bitcast i32* %[[#PtrAnn2ClassB]] to i8* -; CHECK-LLVM: %[[#Cast2ClassB:]] = bitcast i8* %[[#CastClassB]] to i32* -; CHECK-LLVM: %[[#CallClassB:]] = load i32, i32* %[[#Cast2ClassB]], align 4 +; CHECK-LLVM: %[[#CastClassB:]] = bitcast ptr %[[#PtrAnn2ClassB]] to ptr +; CHECK-LLVM: %[[#Cast2ClassB:]] = bitcast ptr %[[#CastClassB]] to ptr +; CHECK-LLVM: %[[#CallClassB:]] = load i32, ptr %[[#Cast2ClassB]], align 4 ; CHECK-LLVM: call spir_func void @_Z3fooi(i32 %[[#CallClassB]]) target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" @@ -136,53 +132,37 @@ define dso_local noundef i32 @main() #0 { %2 = alloca %class.A, align 4 %3 = alloca %class.B, align 4 %4 = alloca %class.A, align 4 - store i32 0, i32* %1, align 4 - %5 = getelementptr inbounds %class.A, %class.A* %2, i32 0, i32 0 - %6 = bitcast i32* %5 to i8* - %7 = call i8* @llvm.ptr.annotation.p0i8(i8* %6, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i32 12, i8* null) - %8 = bitcast i8* %7 to i32* - %9 = load i32, i32* %8, align 4 - call void @_Z3fooi(i32 noundef %9) - %10 = getelementptr inbounds %class.A, %class.A* %4, i32 0, i32 0 - %11 = bitcast i32* %10 to i8* - %12 = call i8* @llvm.ptr.annotation.p0i8(i8* %11, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i32 12, i8* null) - %13 = bitcast i8* %12 to i32* - %14 = load i32, i32* %13, align 4 - call void @_Z3fooi(i32 noundef %14) - %15 = getelementptr inbounds %class.A, %class.A* %2, i32 0, i32 1 - %16 = bitcast i32* %15 to i8* - %17 = call i8* @llvm.ptr.annotation.p0i8(i8* %16, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.2, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i32 13, i8* null) - %18 = bitcast i8* %17 to i32* - %19 = bitcast i32* %18 to i8* - %20 = call i8* @llvm.ptr.annotation.p0i8(i8* %19, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.3, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i32 13, i8* null) - %21 = bitcast i8* %20 to i32* - %22 = bitcast i32* %21 to i8* - %23 = call i8* @llvm.ptr.annotation.p0i8(i8* %22, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.4, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i32 13, i8* null) - %24 = bitcast i8* %23 to i32* - %25 = load i32, i32* %24, align 4 - call void @_Z3fooi(i32 noundef %25) - %26 = getelementptr inbounds %class.A, %class.A* %2, i32 0, i32 2 - %27 = bitcast %class.B* %26 to i8* - %28 = call i8* @llvm.ptr.annotation.p0i8(i8* %27, i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.5, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i32 14, i8* null) - %29 = bitcast i8* %28 to %class.B* - %30 = getelementptr inbounds %class.B, %class.B* %29, i32 0, i32 0 - %31 = bitcast i32* %30 to i8* - %32 = call i8* @llvm.ptr.annotation.p0i8(i8* %31, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.6, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i32 6, i8* null) - %33 = bitcast i8* %32 to i32* - %34 = load i32, i32* %33, align 4 - call void @_Z3fooi(i32 noundef %34) - %35 = getelementptr inbounds %class.B, %class.B* %3, i32 0, i32 0 - %36 = bitcast i32* %35 to i8* - %37 = call i8* @llvm.ptr.annotation.p0i8(i8* %36, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.6, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i32 0, i32 0), i32 6, i8* null) - %38 = bitcast i8* %37 to i32* - %39 = load i32, i32* %38, align 4 - call void @_Z3fooi(i32 noundef %39) + store i32 0, ptr %1, align 4 + %5 = getelementptr inbounds %class.A, ptr %2, i32 0, i32 0 + %6 = call ptr @llvm.ptr.annotation.p0.p0(ptr %5, ptr @.str, ptr @.str.1, i32 11, ptr null) + %7 = load i32, ptr %6, align 4 + call void @_Z3fooi(i32 noundef %7) + %8 = getelementptr inbounds %class.A, ptr %4, i32 0, i32 0 + %9 = call ptr @llvm.ptr.annotation.p0.p0(ptr %8, ptr @.str, ptr @.str.1, i32 11, ptr null) + %10 = load i32, ptr %9, align 4 + call void @_Z3fooi(i32 noundef %10) + %11 = getelementptr inbounds %class.A, ptr %2, i32 0, i32 1 + %12 = call ptr @llvm.ptr.annotation.p0.p0(ptr %11, ptr @.str.2, ptr @.str.1, i32 12, ptr null) + %13 = call ptr @llvm.ptr.annotation.p0.p0(ptr %12, ptr @.str.3, ptr @.str.1, i32 12, ptr null) + %14 = call ptr @llvm.ptr.annotation.p0.p0(ptr %13, ptr @.str.4, ptr @.str.1, i32 12, ptr null) + %15 = load i32, ptr %14, align 4 + call void @_Z3fooi(i32 noundef %15) + %16 = getelementptr inbounds %class.A, ptr %2, i32 0, i32 2 + %17 = call ptr @llvm.ptr.annotation.p0.p0(ptr %16, ptr @.str.5, ptr @.str.1, i32 13, ptr null) + %18 = getelementptr inbounds %class.B, ptr %17, i32 0, i32 0 + %19 = call ptr @llvm.ptr.annotation.p0.p0(ptr %18, ptr @.str.6, ptr @.str.1, i32 5, ptr null) + %20 = load i32, ptr %19, align 4 + call void @_Z3fooi(i32 noundef %20) + %21 = getelementptr inbounds %class.B, ptr %3, i32 0, i32 0 + %22 = call ptr @llvm.ptr.annotation.p0.p0(ptr %21, ptr @.str.6, ptr @.str.1, i32 5, ptr null) + %23 = load i32, ptr %22, align 4 + call void @_Z3fooi(i32 noundef %23) ret i32 0 } declare void @_Z3fooi(i32 noundef) #2 -declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32, i8*) #3 +declare ptr @llvm.ptr.annotation.p0.p0(ptr, ptr, ptr, i32, ptr) #3 attributes #0 = { mustprogress noinline norecurse optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } From 51d44d20951ca50df274801c9f8baac662e119ef Mon Sep 17 00:00:00 2001 From: "Maksimova, Viktoria" Date: Wed, 28 Dec 2022 09:45:22 -0800 Subject: [PATCH 8/8] Fix suggestions --- test/transcoding/multiple_user_semantic_on_struct.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/transcoding/multiple_user_semantic_on_struct.ll b/test/transcoding/multiple_user_semantic_on_struct.ll index ccc9aab3cb..04dcbe624c 100644 --- a/test/transcoding/multiple_user_semantic_on_struct.ll +++ b/test/transcoding/multiple_user_semantic_on_struct.ll @@ -167,4 +167,4 @@ declare ptr @llvm.ptr.annotation.p0.p0(ptr, ptr, ptr, i32, ptr) #3 attributes #0 = { mustprogress noinline norecurse optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } attributes #2 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #3 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } \ No newline at end of file +attributes #3 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }