I’ve been developing an optimization pass that uses the address space attribute (__attribute__((address_space(200))) to indicate different kinds of pointers to be treated differently (I’m making them be pointers to a “global” address space as in UPC). However, I’ve hit a snag in the frontend code generator: if I try to make a method call on a pointer with a custom address space, the frontend chokes because it can’t bitcast between different address spaces, and methods are functions that take a pointer to “this” which is assumed to be in addrspace(0):> Assertion failed: (castIsValid(op, S, Ty) && "Invalid cast!"), function Create, file ../lib/IR/Instructions.cpp, line 2352. > 0 clang-3.4 0x00000001039527f8 llvm::sys::PrintStackTrace(__sFILE*) + 40 > 1 clang-3.4 0x0000000103952c54 SignalHandler(int) + 388 > 2 libsystem_platform.dylib 0x00007fff802395aa _sigtramp + 26 > 3 libsystem_platform.dylib 000000000000000000 _sigtramp + 2145151600 > 4 clang-3.4 0x0000000103952ab6 abort + 22 > 5 clang-3.4 0x0000000103952a91 __assert_rtn + 81 > 6 clang-3.4 0x000000010385f8bf llvm::CastInst::Create(llvm::Instruction::CastOps, llvm::Value*, llvm::Type*, llvm::Twine const&, llvm::Instruction*) + 687 > 7 clang-3.4 0x00000001030a4d1c llvm::IRBuilder<true, llvm::ConstantFolder, llvm::IRBuilderDefaultInserter<true> >::CreateCast(llvm::Instruction::CastOps, llvm::Value*, llvm::Type*, llvm::Twine const&) + 76 > 8 clang-3.4 0x0000000103bbeac3 clang::CodeGen::CodeGenFunction::EmitCall(clang::CodeGen::CGFunctionInfo const&, llvm::Value*, clang::CodeGen::ReturnValueSlot, clang::CodeGen::CallArgList const&, clang::Decl const*, llvm::Instruction**) + 3075 > 9 clang-3.4 0x0000000103c11c02 clang::CodeGen::CodeGenFunction::EmitCXXMemberCall(clang::CXXMethodDecl const*, clang::SourceLocation, llvm::Value*, clang::CodeGen::ReturnValueSlot, llvm::Value*, llvm::Value*, clang::QualType, clang::ConstExprIterator, clang::ConstExprIterator) + 738I know it is not actually expected to be correct behavior to use other addrspace pointers in place of addrspace(0) pointers. My transformation passes change these calls, but I don’t get a chance to make the change because the frontend chokes first. My questions are: 1. Is there a more graceful way that these bitcasts could be handled? Code to load/store from alternate address spaces is allowed to be generated, it just segfaults when run. Can the same behavior be allowed without breaking things for method calls to these pointers? I can imagine simply adding code to detect if the address space is wrong and applying an addrspace cast to get around it. 2. Is there a way to create methods that can be called with pointers to different address spaces? It seems there is no way to declare these in C++ using GNU attributes, and addrspace() seems to not be supported by C++11 attribute syntax, which could possibly express this. Thanks, -Brandon -- Brandon Holt Grad student @ University of Washington http://homes.cs.washington.edu/~bholt -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140120/447dd03c/attachment.html>
On 01/20/2014 02:51 PM, Brandon Holt wrote:> I've been developing an optimization pass that uses the address space > attribute (__attribute__((address_space(200))) to indicate different > kinds of pointers to be treated differently (I'm making them be > pointers to a "global" address space as in UPC). > > However, I've hit a snag in the frontend code generator: if I try to > make a method call on a pointer with a custom address space, the > frontend chokes because it can't bitcast between different address > spaces, and methods are functions that take a pointer to "this" which > is assumed to be in addrspace(0): > >> Assertion failed: (castIsValid(op, S, Ty) && "Invalid cast!"), >> function Create, file ../lib/IR/Instructions.cpp, line 2352. >> 0 clang-3.4 0x00000001039527f8 >> llvm::sys::PrintStackTrace(__sFILE*) + 40 >> 1 clang-3.4 0x0000000103952c54 SignalHandler(int) + 388 >> 2 libsystem_platform.dylib 0x00007fff802395aa _sigtramp + 26 >> 3 libsystem_platform.dylib 000000000000000000 _sigtramp + 2145151600 >> 4 clang-3.4 0x0000000103952ab6 abort + 22 >> 5 clang-3.4 0x0000000103952a91 __assert_rtn + 81 >> 6 clang-3.4 0x000000010385f8bf >> llvm::CastInst::Create(llvm::Instruction::CastOps, llvm::Value*, >> llvm::Type*, llvm::Twine const&, llvm::Instruction*) + 687 >> 7 clang-3.4 0x00000001030a4d1c llvm::IRBuilder<true, >> llvm::ConstantFolder, llvm::IRBuilderDefaultInserter<true> >> >::CreateCast(llvm::Instruction::CastOps, llvm::Value*, llvm::Type*, >> llvm::Twine const&) + 76 >> 8 clang-3.4 0x0000000103bbeac3 >> clang::CodeGen::CodeGenFunction::EmitCall(clang::CodeGen::CGFunctionInfo >> const&, llvm::Value*, clang::CodeGen::ReturnValueSlot, >> clang::CodeGen::CallArgList const&, clang::Decl const*, >> llvm::Instruction**) + 3075 >> 9 clang-3.4 0x0000000103c11c02 >> clang::CodeGen::CodeGenFunction::EmitCXXMemberCall(clang::CXXMethodDecl >> const*, clang::SourceLocation, llvm::Value*, >> clang::CodeGen::ReturnValueSlot, llvm::Value*, llvm::Value*, >> clang::QualType, clang::ConstExprIterator, clang::ConstExprIterator) >> + 738 > > I know it is not actually expected to be correct behavior to use other > addrspace pointers in place of addrspace(0) pointers. My > transformation passes change these calls, but I don't get a chance to > make the change because the frontend chokes first. > > My questions are: > 1. Is there a more graceful way that these bitcasts could be handled? > Code to load/store from alternate address spaces is allowed to be > generated, it just segfaults when run. Can the same behavior be > allowed without breaking things for method calls to these pointers? I > can imagine simply adding code to detect if the address space is wrong > and applying an addrspace cast to get around it.Since 3.4 you need to use the addrspacecast instruction to cast between address spaces. It's possible there are still some places left that haven't been fixed yet to use it instead of creating bitcasts.> > 2. Is there a way to create methods that can be called with pointers > to different address spaces? It seems there is no way to declare these > in C++ using GNU attributes, and addrspace() seems to not be supported > by C++11 attribute syntax, which could possibly express this.You can use __attribute__((address_space(N))> > Thanks, > -Brandon > > -- > Brandon Holt > Grad student @ University of Washington > http://homes.cs.washington.edu/~bholt > <http://homes.cs.washington.edu/%7Ebholt> > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140120/4e1b7e43/attachment.html>
Thank you for the prompt response, Matt. On Jan 20, 2014, at 3:03 PM, Matt Arsenault <Matthew.Arsenault at amd.com> wrote:> Since 3.4 you need to use the addrspacecast instruction to cast between address spaces. It's possible there are still some places left that haven't been fixed yet to use it instead of creating bit casts.Are you saying you think this is a bug and it should in fact be generating an addrspacecast? I will be looking into making this change, and if it would be accepted as a bug fix, I’d be happy to submit it.>> 2. Is there a way to create methods that can be called with pointers to different address spaces? It seems there is no way to declare these in C++ using GNU attributes, and addrspace() seems to not be supported by C++11 attribute syntax, which could possibly express this. > You can use __attribute__((address_space(N))I have already been using that syntax to annotate pointer declarations. However I don’t think it can be applied to methods the way I was thinking. At least it doesn’t actually change them: struct Foo { long x; __attribute__((address_space(7))) void bar(long y) { printf("%ld %ld\n", x, y); } }; Generates this declaration still: define linkonce_odr void @_ZN3Foo3barEl(%struct.Foo* %this, i64 %y) ssp uwtable align 2 Though I think desired behavior would be: define linkonce_odr void @_ZN3Foo3barEl(%struct.Foo addrspace(7)* %this, i64 %y) ssp uwtable align 2 (actually I think it’s more tricky because the address_space attribute could be applying to the return type. I’d think the correct way to specify the attribute on “this” would be to put it where “const” goes, after the parentheses) -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140120/d644c0b0/attachment.html>