Skip to content
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

[OpenCL] compile clang block crash #53436

Closed
haonanya opened this issue Jan 27, 2022 · 8 comments
Closed

[OpenCL] compile clang block crash #53436

haonanya opened this issue Jan 27, 2022 · 8 comments

Comments

@haonanya
Copy link

haonanya commented Jan 27, 2022

[haonanya@shliclel311 33566]$ ../ocl-clang-110/build/bin/clang++ -cc1 -emit-llvm -triple spir-unknown-unknown -finclude-default-header -cl-std=CL3.0  -cl-ext=+__opencl_c_device_enqueue block.cl
clang++: /export/users/haonanya/ocl-clang-110/llvm/include/llvm/Support/Casting.h:269: typename llvm::cast_retty<X, Y*>::ret_type llvm::cast(Y*) [with X = clang::BlockExpr; Y = const clang::Expr; typename llvm::cast_retty<X, Y*>::ret_type = const clang::BlockExpr*]: Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: ../ocl-clang-110/build/bin/clang++ -cc1 -emit-llvm -triple spir-unknown-unknown -finclude-default-header -cl-std=CL3.0 -cl-ext=+__opencl_c_device_enqueue block.cl
1.      <eof> parser at end of file
2.      block.cl:1:13: LLVM IR generation of declaration 'relaunch_kernel'
3.      block.cl:1:13: Generating code for declaration 'relaunch_kernel'
 #0 0x0000000003837ed6 llvm::sys::PrintStackTrace(llvm::raw_ostream&) /export/users/haonanya/ocl-clang-110/llvm/lib/Support/Unix/Signals.inc:564:22
 #1 0x0000000003837f69 PrintStackTraceSignalHandler(void*) /export/users/haonanya/ocl-clang-110/llvm/lib/Support/Unix/Signals.inc:625:1
 #2 0x0000000003835ffb llvm::sys::RunSignalHandlers() /export/users/haonanya/ocl-clang-110/llvm/lib/Support/Signals.cpp:68:20
 #3 0x0000000003837919 SignalHandler(int) /export/users/haonanya/ocl-clang-110/llvm/lib/Support/Unix/Signals.inc:406:1
 #4 0x00007f8a6ae49d80 __restore_rt (/lib64/libpthread.so.0+0x12d80)
 #5 0x00007f8a698e593f raise (/lib64/libc.so.6+0x3793f)
 #6 0x00007f8a698cfc95 abort (/lib64/libc.so.6+0x21c95)
 #7 0x00007f8a698cfb69 _nl_load_domain.cold.0 (/lib64/libc.so.6+0x21b69)
 #8 0x00007f8a698dddf6 (/lib64/libc.so.6+0x2fdf6)
 #9 0x0000000004007381 llvm::cast_retty<clang::BlockExpr, clang::Expr const*>::ret_type llvm::cast<clang::BlockExpr, clang::Expr const>(clang::Expr const*) /export/users/haonanya/ocl-clang-110/llvm/include/llvm/Support/Casting.h:269:3
#10 0x000000000411311b getBlockExpr(clang::Expr const*) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CGOpenCLRuntime.cpp:140:1
#11 0x0000000004113363 clang::CodeGen::CGOpenCLRuntime::emitOpenCLEnqueuedBlock(clang::CodeGen::CodeGenFunction&, clang::Expr const*) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CGOpenCLRuntime.cpp:166:40
#12 0x0000000003ec8eb3 clang::CodeGen::CodeGenFunction::EmitBuiltinExpr(clang::GlobalDecl, unsigned int, clang::CallExpr const*, clang::CodeGen::ReturnValueSlot) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CGBuiltin.cpp:4134:36
#13 0x000000000403cdfa clang::CodeGen::CodeGenFunction::EmitCallExpr(clang::CallExpr const*, clang::CodeGen::ReturnValueSlot) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CGExpr.cpp:4760:42
#14 0x0000000004070a48 (anonymous namespace)::ScalarExprEmitter::VisitCallExpr(clang::CallExpr const*) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CGExprScalar.cpp:581:34
#15 0x0000000004088c36 clang::StmtVisitorBase<std::add_pointer, (anonymous namespace)::ScalarExprEmitter, llvm::Value*>::Visit(clang::Stmt*) /export/users/haonanya/ocl-clang-110/build/tools/clang/include/clang/AST/StmtNodes.inc:813:1
#16 0x000000000406fcd0 (anonymous namespace)::ScalarExprEmitter::Visit(clang::Expr*) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CGExprScalar.cpp:412:57
#17 0x00000000040862b2 clang::CodeGen::CodeGenFunction::EmitScalarExpr(clang::Expr const*, bool) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CGExprScalar.cpp:4701:35
#18 0x0000000004022d80 clang::CodeGen::CodeGenFunction::EmitAnyExpr(clang::Expr const*, clang::CodeGen::AggValueSlot, bool) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CGExpr.cpp:211:55
#19 0x0000000004022d09 clang::CodeGen::CodeGenFunction::EmitIgnoredExpr(clang::Expr const*) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CGExpr.cpp:196:63
#20 0x0000000003c1b661 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CGStmt.cpp:118:56
#21 0x0000000003c1c72e clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CGStmt.cpp:418:3
#22 0x0000000003cae388 clang::CodeGen::CodeGenFunction::EmitFunctionBody(clang::Stmt const*) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CodeGenFunction.cpp:1147:36
#23 0x0000000003caef50 clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CodeGenFunction.cpp:1312:21
#24 0x0000000003cd58c5 clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, llvm::GlobalValue*) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CodeGenModule.cpp:4528:3
#25 0x0000000003cced15 clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CodeGenModule.cpp:2890:47
#26 0x0000000003ccddd0 clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CodeGenModule.cpp:2643:5
#27 0x0000000003cd954a clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) (.localalias.1) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CodeGenModule.cpp:5342:37
#28 0x0000000004c3bcc6 (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/ModuleBuilder.cpp:169:7
#29 0x0000000004c35b69 clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CodeGenAction.cpp:216:7
#30 0x000000000649a89c clang::ParseAST(clang::Sema&, bool, bool) /export/users/haonanya/ocl-clang-110/clang/lib/Parse/ParseAST.cpp:162:20
#31 0x000000000437a91d clang::ASTFrontendAction::ExecuteAction() /export/users/haonanya/ocl-clang-110/clang/lib/Frontend/FrontendAction.cpp:1057:11
#32 0x0000000004c33cb1 clang::CodeGenAction::ExecuteAction() /export/users/haonanya/ocl-clang-110/clang/lib/CodeGen/CodeGenAction.cpp:1185:1
#33 0x000000000437a285 clang::FrontendAction::Execute() /export/users/haonanya/ocl-clang-110/clang/lib/Frontend/FrontendAction.cpp:954:38
#34 0x00000000043138c8 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) /export/users/haonanya/ocl-clang-110/clang/lib/Frontend/CompilerInstance.cpp:984:42
#35 0x00000000044f22e8 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) /export/users/haonanya/ocl-clang-110/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:278:38
#36 0x00000000021052da cc1_main(llvm::ArrayRef<char const*>, char const*, void*) /export/users/haonanya/ocl-clang-110/clang/tools/driver/cc1_main.cpp:240:40
#37 0x00000000020fb31b ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) /export/users/haonanya/ocl-clang-110/clang/tools/driver/driver.cpp:330:20
#38 0x00000000020fba1c main /export/users/haonanya/ocl-clang-110/clang/tools/driver/driver.cpp:407:26
#39 0x00007f8a698d1813 __libc_start_main (/lib64/libc.so.6+0x23813)
#40 0x00000000020f9bae _start (../ocl-clang-110/build/bin/clang+++0x20f9bae)
Aborted (core dumped)

block.cl.txt

@haonanya haonanya changed the title compile clang block crash [OpenCL] compile clang block crash Jan 27, 2022
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 27, 2022

@llvm/issue-subscribers-opencl

@llvmbot
Copy link
Collaborator

llvmbot commented Jan 27, 2022

@llvm/issue-subscribers-clang-codegen

@AnastasiaStulova
Copy link
Contributor

The blocks functionality has been fixed in https://reviews.llvm.org/rGa5de66c4c50b5dec085ffbcd2afefd47f3f18d7f. But it is unlikely you will be able to use enqueue_kernel until we finalize the following https://reviews.llvm.org/D118605 which should hopefully be committed soon.

@haonanya
Copy link
Author

The issue still exists with latest clang.

@AnastasiaStulova
Copy link
Contributor

FYI the source appears to be invalid however regardless compiler should not fail.

if I replace line 12 with

void (^run_blk)(void) = ^ {remaining == 10 ? solve_10_blk() : solve_single_blk();};

which I think is close to the original intent of this example? I am getting the diagnostics:

<source>:12:48: error: cannot refer to a block inside block

Because nested blocks seem to be disallowed. See in Compiler Explorer: https://godbolt.org/z/xoePrEMeh.

@sudden6
Copy link

sudden6 commented Mar 17, 2022

@AnastasiaStulova To clarify the original intent, I was trying to dynamically create a reference (as in C++ referenc) to the block in run_blk, not nesting the blocks. This was to make coding easier, see the original snippet:

void (^run_blk)(void) = (remaining == 10 ? solve_10_blk :
                                (remaining == 9 ? solve_9_blk :
                                (remaining == 8 ? solve_8_blk :
                                (remaining == 7 ? solve_7_blk :
                                (remaining == 6 ? solve_6_blk :
                                (remaining == 5 ? solve_5_blk :
                                (remaining == 4 ? solve_4_blk :
                                (remaining == 3 ? solve_3_blk :
                                (remaining == 2 ? solve_final_blk : solve_single_blk)))))))));
        uint local_size = min((uint)WORKGROUP_SIZE, (uint)get_kernel_work_group_size(run_blk));

        // launch kernel
        // must wait after this one finishes, because of write to 'workspace_sizes'
        err = enqueue_kernel(q, CLK_ENQUEUE_FLAGS_WAIT_KERNEL,
                            ndrange_1D(launch_cnt/applied_factor, local_size),
                            0,
                            NULL,
                            &launched_kernels_evt[launched_kernels_cnt],
                            run_blk);

Where I then use the dynamically resolved run_blk in enqueue_kernel(...) and get_kernel_work_group_size(run_blk) without having to duplicate the function calls using a switch structure. This approach worked for the AMD OpenCL compiler, but only for the AMD Polaris chips.

Now that I see your comment about this not being allowed in OpenCL I have re-read the docs and https://www.khronos.org/registry/OpenCL/sdk/2.0/docs/man/xhtml/blocks.html seems to confirm your statement. Seems I have to rewrite this piece as switch statement. This being invalid probably also explains why I had such problems getting this to run on other OpenCL implementations. Still no idea why it works on the AMD OpenCL compiler though.

Nevertheless, I shouldn't be able to crash the compiler even with my invalid code and it should produce the correct error message.

sudden6 added a commit to sudden6/m-queens that referenced this issue Mar 20, 2022
Dynamically assigning a block reference using the ?: operator is not
allowed according to: https://www.khronos.org/registry/OpenCL/specs/2.2/
html/OpenCL_C.html#restrictions-1

This buggy code made compilers crash in bad ways, see: https://
github.com/llvm/llvm-project/issues/53436
@sudden6
Copy link

sudden6 commented Mar 20, 2022

The linked commit now fixes the code to not violate the OpenCL block rules. Can anyone confirm it's valid OpenCL C?

@AnastasiaStulova
Copy link
Contributor

Ok, this seems to make sense since you are now using the exact block statically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants