This is an archive of the discontinued LLVM Phabricator instance.

[Matrix] Implement C-style explicit type conversions for matrix types
ClosedPublic

Authored by SaurabhJha on Mar 21 2021, 9:43 AM.

Details

Summary

[Matrix] Implement explicit type conversions for MatrixType.
Bugzilla ticket is here: https://bugs.llvm.org/show_bug.cgi?id=47141

Diff Detail

Event Timeline

SaurabhJha created this revision.Mar 21 2021, 9:43 AM
SaurabhJha requested review of this revision.Mar 21 2021, 9:43 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 21 2021, 9:43 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
fhahn requested changes to this revision.Mar 21 2021, 2:40 PM
fhahn added reviewers: rjmccall, rsmith, erichkeane.

Thanks for the patch! I think this also needs changes in code-gen & code-gen tests.

clang/include/clang/Sema/Sema.h
11715

nit: casting beween

11717

nit: should be a full sentence and also go in the previous row?

This revision now requires changes to proceed.Mar 21 2021, 2:40 PM

Thanks for the patch! I think this also needs changes in code-gen & code-gen tests.

Hey @fhahn I searched but could not find the relevant code-gen and code-gen tests I need to fix. Can you please point me to where vectors casts are handled in code gen? I could probably use that for matrices.

fhahn added a comment.Mar 22 2021, 2:41 PM

Thanks for the patch! I think this also needs changes in code-gen & code-gen tests.

Thanks for the patch! I think this also needs changes in code-gen & code-gen tests.

Hey @fhahn I searched but could not find the relevant code-gen and code-gen tests I need to fix. Can you please point me to where vectors casts are handled in code gen? I could probably use that for matrices.

I think you probably need to add new files for the tests, e.g. matrix-type-casts.cpp & matrix-type-casts.c and then just add tests for various valid cast combinations. Is that enough to get you started? You can look at some of the existing matrix codegen tests for inspiration for the run-line & CHECK lines.

I think you probably need to add new files for the tests, e.g. matrix-type-casts.cpp & matrix-type-casts.c and then just add tests for various valid cast combinations. Is that enough to get you started? You can look at some of the existing matrix codegen tests for inspiration for the run-line & CHECK lines.

Oh yes, missed the obvious thing I could have done, Cheers!

Hey @fhahn ,

I realise, as you pointed out before, that we need to do some changes in CodeGen too. I think its going to be more involved so before starting on that, it would be great if you can confirm whether I am on the right path. I will describe what I did, what happened, and what I inferred from that.

I ran this simple cast.

typedef char cx4x4 __attribute__((matrix_type(4, 4)));
typedef int ix4x4 __attribute__((matrix_type(4, 4)));
cx4x4 c = (cx4x4) i;

This crashed the compiler with this stack trace.

clang: /tmp/llvm/lib/IR/Instructions.cpp:2934: static llvm::CastInst *llvm::CastInst::Create(Instruction::CastOps, llvm::Value *, llvm::Type *, const llvm::Twine &, llvm::Instruction *): Assertion `castIsValid(op, S, Ty) && "Invalid cast!"' 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: /tmp/build/bin/clang -cc1 -internal-isystem /tmp/build/lib/clang/13.0.0/include -nostdsysteminc -fenable-matrix -triple x86_64-apple-darwin /tmp/clang/test/CodeGen/matrix-cast.c -emit-llvm -disable-llvm-passes -o -
1.	<eof> parser at end of file
2.	/tmp/clang/test/CodeGen/matrix-cast.c:15:6: LLVM IR generation of declaration 'cast_char_matrix_to_int_same_size'
3.	/tmp/clang/test/CodeGen/matrix-cast.c:15:6: Generating code for declaration 'cast_char_matrix_to_int_same_size'
 #0 0x000000000972648a llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /tmp/llvm/lib/Support/Unix/Signals.inc:565:11
 #1 0x000000000972665b PrintStackTraceSignalHandler(void*) /tmp/llvm/lib/Support/Unix/Signals.inc:632:1
 #2 0x0000000009724c4b llvm::sys::RunSignalHandlers() /tmp/llvm/lib/Support/Signals.cpp:70:5
 #3 0x0000000009726dd1 SignalHandler(int) /tmp/llvm/lib/Support/Unix/Signals.inc:407:1
 #4 0x00007ff3d17353c0 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x153c0)
 #5 0x00007ff3d11e618b raise /build/glibc-eX1tMB/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1
 #6 0x00007ff3d11c5859 abort /build/glibc-eX1tMB/glibc-2.31/stdlib/abort.c:81:7
 #7 0x00007ff3d11c5729 get_sysdep_segment_value /build/glibc-eX1tMB/glibc-2.31/intl/loadmsgcat.c:509:8
 #8 0x00007ff3d11c5729 _nl_load_domain /build/glibc-eX1tMB/glibc-2.31/intl/loadmsgcat.c:970:34
 #9 0x00007ff3d11d6f36 (/lib/x86_64-linux-gnu/libc.so.6+0x36f36)
#10 0x0000000008a5c1bf llvm::CastInst::Create(llvm::Instruction::CastOps, llvm::Value*, llvm::Type*, llvm::Twine const&, llvm::Instruction*) /tmp/llvm/lib/IR/Instructions.cpp:2936:11
#11 0x0000000006205834 llvm::IRBuilderBase::CreateCast(llvm::Instruction::CastOps, llvm::Value*, llvm::Type*, llvm::Twine const&) /tmp/llvm/include/llvm/IR/IRBuilder.h:2106:52
#12 0x00000000061ef472 llvm::IRBuilderBase::CreateBitCast(llvm::Value*, llvm::Type*, llvm::Twine const&) /tmp/llvm/include/llvm/IR/IRBuilder.h:2065:5
#13 0x0000000009fb1140 (anonymous namespace)::ScalarExprEmitter::VisitCastExpr(clang::CastExpr*) /tmp/clang/lib/CodeGen/CGExprScalar.cpp:2069:5
#14 0x0000000009fb002e (anonymous namespace)::ScalarExprEmitter::VisitExplicitCastExpr(clang::ExplicitCastExpr*) /tmp/clang/lib/CodeGen/CGExprScalar.cpp:563:5
#15 0x0000000009fa8493 clang::StmtVisitorBase<std::add_pointer, (anonymous namespace)::ScalarExprEmitter, llvm::Value*>::VisitCStyleCastExpr(clang::CStyleCastExpr*) /tmp/build/tools/clang/include/clang/AST/StmtNodes.inc:879:1
#16 0x0000000009fa2747 clang::StmtVisitorBase<std::add_pointer, (anonymous namespace)::ScalarExprEmitter, llvm::Value*>::Visit(clang::Stmt*) /tmp/build/tools/clang/include/clang/AST/StmtNodes.inc:879:1
#17 0x0000000009f976fb (anonymous namespace)::ScalarExprEmitter::Visit(clang::Expr*) /tmp/clang/lib/CodeGen/CGExprScalar.cpp:410:3
#18 0x0000000009fa4f82 (anonymous namespace)::ScalarExprEmitter::VisitBinAssign(clang::BinaryOperator const*) /tmp/clang/lib/CodeGen/CGExprScalar.cpp:4168:9
#19 0x0000000009fa157d clang::StmtVisitorBase<std::add_pointer, (anonymous namespace)::ScalarExprEmitter, llvm::Value*>::Visit(clang::Stmt*) /tmp/clang/include/clang/AST/StmtVisitor.h:72:26
#20 0x0000000009f976fb (anonymous namespace)::ScalarExprEmitter::Visit(clang::Expr*) /tmp/clang/lib/CodeGen/CGExprScalar.cpp:410:3
#21 0x0000000009f97656 clang::CodeGen::CodeGenFunction::EmitScalarExpr(clang::Expr const*, bool) /tmp/clang/lib/CodeGen/CGExprScalar.cpp:4757:3
#22 0x0000000009e5638c clang::CodeGen::CodeGenFunction::EmitAnyExpr(clang::Expr const*, clang::CodeGen::AggValueSlot, bool) /tmp/clang/lib/CodeGen/CGExpr.cpp:218:12
#23 0x0000000009e562bd clang::CodeGen::CodeGenFunction::EmitIgnoredExpr(clang::Expr const*) /tmp/clang/lib/CodeGen/CGExpr.cpp:203:19
#24 0x0000000009fc3616 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) /tmp/clang/lib/CodeGen/CGStmt.cpp:118:5
#25 0x0000000009fcc7ab clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) /tmp/clang/lib/CodeGen/CGStmt.cpp:447:3
#26 0x0000000009e2ebd1 clang::CodeGen::CodeGenFunction::EmitFunctionBody(clang::Stmt const*) /tmp/clang/lib/CodeGen/CodeGenFunction.cpp:1187:5
#27 0x0000000009e2f675 clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) /tmp/clang/lib/CodeGen/CodeGenFunction.cpp:1345:3
#28 0x0000000009ce448e clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, llvm::GlobalValue*) /tmp/clang/lib/CodeGen/CodeGenModule.cpp:4786:3
#29 0x0000000009cdae4c clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) /tmp/clang/lib/CodeGen/CodeGenModule.cpp:3172:12
#30 0x0000000009cdfec4 clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl) /tmp/clang/lib/CodeGen/CodeGenModule.cpp:2925:5
#31 0x0000000009ce7d10 clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) /tmp/clang/lib/CodeGen/CodeGenModule.cpp:5627:38
#32 0x000000000a83b2c2 (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) /tmp/clang/lib/CodeGen/ModuleBuilder.cpp:169:73
#33 0x000000000a8356b4 clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) /tmp/clang/lib/CodeGen/CodeGenAction.cpp:215:12
#34 0x000000000cf8fab5 clang::ParseAST(clang::Sema&, bool, bool) /tmp/clang/lib/Parse/ParseAST.cpp:162:20
#35 0x000000000a65b742 clang::ASTFrontendAction::ExecuteAction() /tmp/clang/lib/Frontend/FrontendAction.cpp:1058:1
#36 0x000000000a831709 clang::CodeGenAction::ExecuteAction() /tmp/clang/lib/CodeGen/CodeGenAction.cpp:1039:5
#37 0x000000000a65b108 clang::FrontendAction::Execute() /tmp/clang/lib/Frontend/FrontendAction.cpp:953:7
#38 0x000000000a52fa45 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) /tmp/clang/lib/Frontend/CompilerInstance.cpp:955:23
#39 0x000000000a81df96 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) /tmp/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:278:8
#40 0x0000000006103d0d cc1_main(llvm::ArrayRef<char const*>, char const*, void*) /tmp/clang/tools/driver/cc1_main.cpp:246:13
#41 0x00000000060f6759 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) /tmp/clang/tools/driver/driver.cpp:335:5
#42 0x00000000060f58ee main /tmp/clang/tools/driver/driver.cpp:412:5
#43 0x00007ff3d11c70b3 __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:342:3
#44 0x00000000060f509e _start (/tmp/build/bin/clang+0x60f509e)

This cast is failing. And my suspicion is that's because we are not handling matrix types here. It seems like we need to define a matrix type in llvm/include/llvm/IR/Type.h and use that to handle castIsValid.

Do you think this is the right approach?

fhahn added a comment.Mar 25 2021, 2:09 AM

Hey @fhahn ,

I realise, as you pointed out before, that we need to do some changes in CodeGen too. I think its going to be more involved so before starting on that, it would be great if you can confirm whether I am on the right path. I will describe what I did, what happened, and what I inferred from that.

I ran this simple cast.

typedef char cx4x4 __attribute__((matrix_type(4, 4)));
typedef int ix4x4 __attribute__((matrix_type(4, 4)));
cx4x4 c = (cx4x4) i;

This crashed the compiler with this stack trace.

clang: /tmp/llvm/lib/IR/Instructions.cpp:2934: static llvm::CastInst *llvm::CastInst::Create(Instruction::CastOps, llvm::Value *, llvm::Type *, const llvm::Twine &, llvm::Instruction *): Assertion `castIsValid(op, S, Ty) && "Invalid cast!"' 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: /tmp/build/bin/clang -cc1 -internal-isystem /tmp/build/lib/clang/13.0.0/include -nostdsysteminc -fenable-matrix -triple x86_64-apple-darwin /tmp/clang/test/CodeGen/matrix-cast.c -emit-llvm -disable-llvm-passes -o -
1.	<eof> parser at end of file
2.	/tmp/clang/test/CodeGen/matrix-cast.c:15:6: LLVM IR generation of declaration 'cast_char_matrix_to_int_same_size'
3.	/tmp/clang/test/CodeGen/matrix-cast.c:15:6: Generating code for declaration 'cast_char_matrix_to_int_same_size'
 #0 0x000000000972648a llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /tmp/llvm/lib/Support/Unix/Signals.inc:565:11
 #1 0x000000000972665b PrintStackTraceSignalHandler(void*) /tmp/llvm/lib/Support/Unix/Signals.inc:632:1
 #2 0x0000000009724c4b llvm::sys::RunSignalHandlers() /tmp/llvm/lib/Support/Signals.cpp:70:5
 #3 0x0000000009726dd1 SignalHandler(int) /tmp/llvm/lib/Support/Unix/Signals.inc:407:1
 #4 0x00007ff3d17353c0 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x153c0)
 #5 0x00007ff3d11e618b raise /build/glibc-eX1tMB/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1
 #6 0x00007ff3d11c5859 abort /build/glibc-eX1tMB/glibc-2.31/stdlib/abort.c:81:7
 #7 0x00007ff3d11c5729 get_sysdep_segment_value /build/glibc-eX1tMB/glibc-2.31/intl/loadmsgcat.c:509:8
 #8 0x00007ff3d11c5729 _nl_load_domain /build/glibc-eX1tMB/glibc-2.31/intl/loadmsgcat.c:970:34
 #9 0x00007ff3d11d6f36 (/lib/x86_64-linux-gnu/libc.so.6+0x36f36)
#10 0x0000000008a5c1bf llvm::CastInst::Create(llvm::Instruction::CastOps, llvm::Value*, llvm::Type*, llvm::Twine const&, llvm::Instruction*) /tmp/llvm/lib/IR/Instructions.cpp:2936:11
#11 0x0000000006205834 llvm::IRBuilderBase::CreateCast(llvm::Instruction::CastOps, llvm::Value*, llvm::Type*, llvm::Twine const&) /tmp/llvm/include/llvm/IR/IRBuilder.h:2106:52
#12 0x00000000061ef472 llvm::IRBuilderBase::CreateBitCast(llvm::Value*, llvm::Type*, llvm::Twine const&) /tmp/llvm/include/llvm/IR/IRBuilder.h:2065:5
#13 0x0000000009fb1140 (anonymous namespace)::ScalarExprEmitter::VisitCastExpr(clang::CastExpr*) /tmp/clang/lib/CodeGen/CGExprScalar.cpp:2069:5
#14 0x0000000009fb002e (anonymous namespace)::ScalarExprEmitter::VisitExplicitCastExpr(clang::ExplicitCastExpr*) /tmp/clang/lib/CodeGen/CGExprScalar.cpp:563:5
#15 0x0000000009fa8493 clang::StmtVisitorBase<std::add_pointer, (anonymous namespace)::ScalarExprEmitter, llvm::Value*>::VisitCStyleCastExpr(clang::CStyleCastExpr*) /tmp/build/tools/clang/include/clang/AST/StmtNodes.inc:879:1
#16 0x0000000009fa2747 clang::StmtVisitorBase<std::add_pointer, (anonymous namespace)::ScalarExprEmitter, llvm::Value*>::Visit(clang::Stmt*) /tmp/build/tools/clang/include/clang/AST/StmtNodes.inc:879:1
#17 0x0000000009f976fb (anonymous namespace)::ScalarExprEmitter::Visit(clang::Expr*) /tmp/clang/lib/CodeGen/CGExprScalar.cpp:410:3
#18 0x0000000009fa4f82 (anonymous namespace)::ScalarExprEmitter::VisitBinAssign(clang::BinaryOperator const*) /tmp/clang/lib/CodeGen/CGExprScalar.cpp:4168:9
#19 0x0000000009fa157d clang::StmtVisitorBase<std::add_pointer, (anonymous namespace)::ScalarExprEmitter, llvm::Value*>::Visit(clang::Stmt*) /tmp/clang/include/clang/AST/StmtVisitor.h:72:26
#20 0x0000000009f976fb (anonymous namespace)::ScalarExprEmitter::Visit(clang::Expr*) /tmp/clang/lib/CodeGen/CGExprScalar.cpp:410:3
#21 0x0000000009f97656 clang::CodeGen::CodeGenFunction::EmitScalarExpr(clang::Expr const*, bool) /tmp/clang/lib/CodeGen/CGExprScalar.cpp:4757:3
#22 0x0000000009e5638c clang::CodeGen::CodeGenFunction::EmitAnyExpr(clang::Expr const*, clang::CodeGen::AggValueSlot, bool) /tmp/clang/lib/CodeGen/CGExpr.cpp:218:12
#23 0x0000000009e562bd clang::CodeGen::CodeGenFunction::EmitIgnoredExpr(clang::Expr const*) /tmp/clang/lib/CodeGen/CGExpr.cpp:203:19
#24 0x0000000009fc3616 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) /tmp/clang/lib/CodeGen/CGStmt.cpp:118:5
#25 0x0000000009fcc7ab clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) /tmp/clang/lib/CodeGen/CGStmt.cpp:447:3
#26 0x0000000009e2ebd1 clang::CodeGen::CodeGenFunction::EmitFunctionBody(clang::Stmt const*) /tmp/clang/lib/CodeGen/CodeGenFunction.cpp:1187:5
#27 0x0000000009e2f675 clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) /tmp/clang/lib/CodeGen/CodeGenFunction.cpp:1345:3
#28 0x0000000009ce448e clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, llvm::GlobalValue*) /tmp/clang/lib/CodeGen/CodeGenModule.cpp:4786:3
#29 0x0000000009cdae4c clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) /tmp/clang/lib/CodeGen/CodeGenModule.cpp:3172:12
#30 0x0000000009cdfec4 clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl) /tmp/clang/lib/CodeGen/CodeGenModule.cpp:2925:5
#31 0x0000000009ce7d10 clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) /tmp/clang/lib/CodeGen/CodeGenModule.cpp:5627:38
#32 0x000000000a83b2c2 (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) /tmp/clang/lib/CodeGen/ModuleBuilder.cpp:169:73
#33 0x000000000a8356b4 clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) /tmp/clang/lib/CodeGen/CodeGenAction.cpp:215:12
#34 0x000000000cf8fab5 clang::ParseAST(clang::Sema&, bool, bool) /tmp/clang/lib/Parse/ParseAST.cpp:162:20
#35 0x000000000a65b742 clang::ASTFrontendAction::ExecuteAction() /tmp/clang/lib/Frontend/FrontendAction.cpp:1058:1
#36 0x000000000a831709 clang::CodeGenAction::ExecuteAction() /tmp/clang/lib/CodeGen/CodeGenAction.cpp:1039:5
#37 0x000000000a65b108 clang::FrontendAction::Execute() /tmp/clang/lib/Frontend/FrontendAction.cpp:953:7
#38 0x000000000a52fa45 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) /tmp/clang/lib/Frontend/CompilerInstance.cpp:955:23
#39 0x000000000a81df96 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) /tmp/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:278:8
#40 0x0000000006103d0d cc1_main(llvm::ArrayRef<char const*>, char const*, void*) /tmp/clang/tools/driver/cc1_main.cpp:246:13
#41 0x00000000060f6759 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) /tmp/clang/tools/driver/driver.cpp:335:5
#42 0x00000000060f58ee main /tmp/clang/tools/driver/driver.cpp:412:5
#43 0x00007ff3d11c70b3 __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:342:3
#44 0x00000000060f509e _start (/tmp/build/bin/clang+0x60f509e)

This cast is failing. And my suspicion is that's because we are not handling matrix types here. It seems like we need to define a matrix type in llvm/include/llvm/IR/Type.h and use that to handle castIsValid.

Do you think this is the right approach?

There deliberately are no matrix types directly in LLVM. Instead, matrix values are embedded in vectors. The problem probably is that Clang does not handle matrix types and generates cast instructions between wrong types. You could try and confirm that using a debugger and printing the type of the value & the target type. The cast instructions (zext for casts between unsigned, sext between signed & fpext between floats, and the different truncate instructions) support casting vector types, but Clang needs updating to emit the correct casts (e.g. something like trunc <16 x i32> %m to <16 x i8> for your example).

To get an idea what instructions are used to convert between different types, you should be able to just take a look at the code generated for casts between the scalar types.

rjmccall added inline comments.Mar 30 2021, 12:13 AM
clang/lib/Sema/SemaCast.cpp
2325

The expected semantics for this conversion are not the ordinary bitwise-reinterpretation semantics of reinterpret_cast, so this really should not be allowed as a reinterpret_cast. Allowing it as a static_cast seems appropriate.

clang/lib/Sema/SemaExpr.cpp
7354

"Compatible" has a specific meaning in the C standard, so if you aren't intending to invoke that concept of compatibility, you should find a new word.

It looks like this kind of cast is supposed to be doing an elementwise conversion. I guess all the types you can have matrices of are interconvertible, so there are no restrictions on the element types. But you definitely need this to produce a new CastKind for elementwise conversion instead of using CK_BitCast, which does a bitwise reinterpretation, which is not what you want.

Matrix element types already have to be scalar types, so those checks aren't doing anything.

SaurabhJha added inline comments.Mar 30 2021, 12:50 AM
clang/lib/Sema/SemaExpr.cpp
7354

I see, so we need a new CK_MatrixCast, right?

Hey @fhahn @rjmccall ,

Thank you so much for your reviews. Apart from the rest of your comments, here are the two principle things I am going to do next:

  1. Replace the reinterpret_castwith static_cast. Do you think I should focus this revision to C-style casts and do static_casts in another patch?
  2. Create a new CK_MatrixCast and implement its handling.

Is there any existing code I can look at that can help me implement the handler code for CK_MatrixCast? I could look at vectors because I was doing CK_Bitcast but I don't think I can rely on that now. If there's no such existing code at the moment, that's not an issue. I think I should be able figure it out after I spend some more time on it.

Cheers,
Saurabh

Hey @fhahn @rjmccall ,

Thank you so much for your reviews. Apart from the rest of your comments, here are the two principle things I am going to do next:

  1. Replace the reinterpret_castwith static_cast. Do you think I should focus this revision to C-style casts and do static_casts in another patch?

IIRC, making C-style casts work correctly in C++ will actually be easier if you make one of the specialized casts do it; I'd say go ahead and do it in static_cast.

Casts in C use basically a completely different code path.

  1. Create a new CK_MatrixCast and implement its handling.

Is there any existing code I can look at that can help me implement the handler code for CK_MatrixCast? I could look at vectors because I was doing CK_Bitcast but I don't think I can rely on that now.

Right, vector casts are their own unfortunate thing which we don't want to semantically emulate.

What code do you want to get out of this? Are there e.g. vectorized float->double conversions we can use, or is the operation basically doomed to break the matrix apart and put it back together again?

Hey, I should mention that I am new to clang/llvm. My below thoughts could be wrong.

IIRC, making C-style casts work correctly in C++ will actually be easier if you make one of the specialized casts do it; I'd say go ahead and do it in static_cast.

Casts in C use basically a completely different code path.

Okay, then I think I will focus on static casts and C style casts for later. They use different functions, CheckStaticCast and CheckCStyleCast respectively and implementing static casts in matrix must involve change in CheckStaticCast and the function it calls.

Right, vector casts are their own unfortunate thing which we don't want to semantically emulate.

What code do you want to get out of this? Are there e.g. vectorized float->double conversions we can use, or is the operation basically doomed to break the matrix apart and put it back together again?

I think because matrices are vectors underneath, we should try vectorised conversions.

Thoughts?

Saurabh

fhahn added a comment.Mar 31 2021, 2:09 PM

What code do you want to get out of this? Are there e.g. vectorized float->double conversions we can use, or is the operation basically doomed to break the matrix apart and put it back together again?

I think because matrices are vectors underneath, we should try vectorised conversions.

I think there should be vector versions of common conversions in most modern vector instruction sets, e.g. both ARM64 and X86 (with varying levels of support, depending on the supported vector extensions) have vector instructions for sign extend i32 -> i64 and floating point extension float -> double: https://godbolt.org/z/jx4Ya4PP5. John, please let me know if you were referring to something else, but IIUC then it would be best to emit vector conversion for the full vector (that should also be the easiest in terms of codegen).

More recent instruction set versions also have specialized instructions for things like dot-products, that also extend/truncate some of their operands and/or results., which we could also make use of easily if we have the vector conversions.

What code do you want to get out of this? Are there e.g. vectorized float->double conversions we can use, or is the operation basically doomed to break the matrix apart and put it back together again?

I think because matrices are vectors underneath, we should try vectorised conversions.

I think there should be vector versions of common conversions in most modern vector instruction sets, e.g. both ARM64 and X86 (with varying levels of support, depending on the supported vector extensions) have vector instructions for sign extend i32 -> i64 and floating point extension float -> double: https://godbolt.org/z/jx4Ya4PP5. John, please let me know if you were referring to something else, but IIUC then it would be best to emit vector conversion for the full vector (that should also be the easiest in terms of codegen).

Okay. In that caae, this may be somewhat verbose because you'll have to analyze the element types in IRGen and ask the matrix-lowering code to do the appropriate conversion. Not tricky, just verbose.

Hey, elementary question about arcanist. I followed the steps here https://llvm.org/docs/Contributing.html#how-to-submit-a-patch and did

arc diff --edit --verbatim

on my current branch. Probably one mistake I did was to do a git reset HEAD~1 and create a new commit. Now its trying to create a new revision. Is that okay to create a new revision and abandoning this one?

fhahn added a comment.Apr 1 2021, 1:19 PM

Hey, elementary question about arcanist. I followed the steps here https://llvm.org/docs/Contributing.html#how-to-submit-a-patch and did

arc diff --edit --verbatim

on my current branch. Probably one mistake I did was to do a git reset HEAD~1 and create a new commit. Now its trying to create a new revision. Is that okay to create a new revision and abandoning this one?

You can't add multiple commits to the same review on Phabricator. If you have multiple commits that you want to update this review with, you can squash them into the commit you used to create this patch and then upload the updated commit. If you have multiple commit but only want to upload the latest, you can use arc diff HEAD^

SaurabhJha updated this revision to Diff 334815.Apr 1 2021, 1:33 PM

Hi Florian and John,

Thanks for the comments so far. I figure it would be easier for further discussion if I have something concrete. Here's what I have right now:

  • A new CK_MatrixCast.
  • Sema code for C-style cast along with its tests.
  • My guess on places CK_MatrixCast will go in CodeGen. I have added a TODO in CGExprScalar.cpp indicating where I think we should implement the code gen for this conversion. There's a failing CodeGen test too.
  • I am not sure yet if we need to anything with StaticAnalyzer/Core/ExprEngineC.cpp. I got a warning that CK_MatrixCast needs handling there.

My next step is to make it work for C style cast. Once that works, I can use that learning to implement static_cast.

fhahn added a comment.Apr 1 2021, 1:37 PM

Hi Florian and John,

Thanks for the comments so far. I figure it would be easier for further discussion if I have something concrete. Here's what I have right now:

  • A new CK_MatrixCast.
  • Sema code for C-style cast along with its tests.
  • My guess on places CK_MatrixCast will go in CodeGen. I have added a TODO in CGExprScalar.cpp indicating where I think we should implement the code gen for this conversion. There's a failing CodeGen test too.
  • I am not sure yet if we need to anything with StaticAnalyzer/Core/ExprEngineC.cpp. I got a warning that CK_MatrixCast needs handling there.

My next step is to make it work for C style cast. Once that works, I can use that learning to implement static_cast.

Depending on how much work implementing the other casts is, but you may want to start with getting everything work for a single type (e.g. C-style casts) and then submit that first (with codegen support). Once that is done, adding the additional checks for the other casts should be much less work. It's also easier to review if the patch is not too big & doing too much.

SaurabhJha updated this revision to Diff 334942.Apr 2 2021, 6:13 AM

Updating D99037: [Matrix] Implement explicit type conversions for matrix types

Latest update includes code gen for c style casts along with some lit tests

I pushed some unwanted changes that I used for debugging..fixing/removing them now.

SaurabhJha updated this revision to Diff 334945.Apr 2 2021, 6:25 AM

Updating D99037: [Matrix] Implement explicit type conversions for matrix types
Removed unused variables and includes and fix codegen lit tests

Added some inline comments on where I have some doubts.

clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
547

I thought doing changes here is is outside the scope of casting so I just left a TODO here. Please let me know if we want to do something else here.

clang/test/CodeGen/matrix-cast.c
40

I tried adding a float -> int conversion too but it failed because of this assertion https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/CGExprScalar.cpp#L1339-L1344 Hopefully that's intended.

fhahn added inline comments.Apr 2 2021, 7:01 AM
clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
547

I think that's fair, but you should probably add continue; rather than falling through.

clang/test/CodeGen/matrix-cast.c
16

This doesn't seem right. We are casting between 2 signed types, so the sign should get preserved, right? Shouldn't this be sext? See https://godbolt.org/z/zWznYdnKW for the scalar case.

I think you also need tests for casts with different bitwidths with unsigned, unsigned -> signed & signed -> unsigned.

40

Clang should never run into an assertion. If that should not be allowed, then Clang should emit an error during Sema. I'm not sure why there is such a restriction for vector types, but I am not sure that this shouldn't be allowed for matrixes. Perhaps @rjmccall has more thoughts on this, but conversion between scalar ints to floats is allowed AFAIKT.

fhahn added inline comments.Apr 2 2021, 7:06 AM
clang/lib/Sema/SemaCast.cpp
2915–2916

... or a matrix?

clang/test/Sema/matrix-cast.c
4

I think it would be good to add additional test coverage casting between matrix types and other types, e.g. vector types, pointer types and struct types.

It would also be good to have C++ tests that test casting with matrix types where some of the dimensions are template arguments.

fhahn added inline comments.Apr 2 2021, 7:09 AM
clang/lib/Sema/SemaExpr.cpp
7433

When we get here, SrcTy may not necessarily be a scalar I think (see my earlier note about adding more invalid cast tests for some additional cases that might reach this code)

SaurabhJha updated this revision to Diff 334951.Apr 2 2021, 7:22 AM

Update commit message to more accurately reflect the patch

fhahn added a comment.Apr 2 2021, 8:49 AM

Update commit message to more accurately reflect the patch

Just FYI, arc diff does not update the patch description on Phabricator. I think you have to edit it via the web-interface.

SaurabhJha added inline comments.Apr 2 2021, 11:08 AM
clang/test/CodeGen/matrix-cast.c
16

This is happening because we are always passing inSigned argument to Builder.CreateIntCast as false here https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/CGExprScalar.cpp#L1348. IfI change it to true, it generates sext instructions.

I am figuring out how can I determine sign of src and dest type. Because SrcTy and DestTy are vectors here, they are unsigned and SrcElementTy and DestElementTy have no method like isSignedIntegerOrEnumerationType. Once that's solved, this should be fixed.

40

I can probably try removing that assert and see if some other unit or lit tests are failing. We can then make a decision.

fhahn added inline comments.Apr 2 2021, 11:40 AM
clang/test/CodeGen/matrix-cast.c
16

Oh right, I think I see what's going on. I think the code you are referring to is specifically for the vector types in Clang, but it is checking the LLVM type and we also use LLVM IR vector types for matrix values, so the code accidentally also covers matrix values at the moment.

I *think* we should probably handled matrix values separately in this function. @rjmccall what do you think?

rjmccall added inline comments.Apr 2 2021, 1:08 PM
clang/test/CodeGen/matrix-cast.c
16

Yes, I would recommend that you recognize matrix values by their Clang type and then call something in the matrix IR-generation library.

SaurabhJha updated this revision to Diff 335083.Apr 3 2021, 6:35 AM

Addressed most of the comments. I couldn't understand "..would also be good to have C++ tests that test casting with matrix types where some of the dimensions are template arguments...". When I tried this

"""
cx4x4 m1;

(void)(ix4x4)m1
"""

it gave me the error
"""
C-style cast from 'cx4x4' (aka 'char attribute((matrix_type(4, 4)))') to 'ix4x4' (aka 'int attribute((matrix_type(4, 4)))') is not allowed
"""
should I address it as part of this patch?

SaurabhJha retitled this revision from [Matrix] Implement explicit type conversions for matrix types to [Matrix] Implement C-style explicit type conversions for matrix types.Apr 3 2021, 6:36 AM
SaurabhJha updated this revision to Diff 335084.Apr 3 2021, 6:40 AM

Update one inline comment in SemaCast.cpp

One other problem is somehow this test is failing https://github.com/llvm/llvm-project/blob/main/clang/test/SemaOpenCL/sampler_t_overload.cl#L6 with this error.

/tmp/clang/test/SemaOpenCL/sampler_t_overload.cl:6:30: error: initializer element is not a compile-time constant
constant sampler_t glb_smp = 5;
                             ^
1 error generated.

Not sure what's going on but will continue to debug. Let me know if there's something simple that I am missing here.

One other problem is somehow this test is failing https://github.com/llvm/llvm-project/blob/main/clang/test/SemaOpenCL/sampler_t_overload.cl#L6 with this error.

/tmp/clang/test/SemaOpenCL/sampler_t_overload.cl:6:30: error: initializer element is not a compile-time constant
constant sampler_t glb_smp = 5;
                             ^
1 error generated.

Not sure what's going on but will continue to debug. Let me know if there's something simple that I am missing here.

I think I got it. If I remove the definition of CAST_OPERATION(MatrixCast) from OperationKinds.def, it works. So probably a matter of defining it the correct way.

SaurabhJha updated this revision to Diff 335182.Apr 4 2021, 3:53 PM

Move the definition of MatrixCast to the bottom in OperationKinds.def

SaurabhJha updated this revision to Diff 335216.Apr 5 2021, 1:28 AM

Move back CK_MatrixCast definition to to just above CK_VectorSplat. The Matrix CodeGen is passing again but SemaOpenCL/sampler tests are failing again

fhahn added a comment.Apr 5 2021, 12:37 PM

Addressed most of the comments. I couldn't understand "..would also be good to have C++ tests that test casting with matrix types where some of the dimensions are template arguments...". When I tried this

"""
cx4x4 m1;

(void)(ix4x4)m1
"""

it gave me the error
"""
C-style cast from 'cx4x4' (aka 'char attribute((matrix_type(4, 4)))') to 'ix4x4' (aka 'int attribute((matrix_type(4, 4)))') is not allowed
"""

Oh, that's interesting, I was assuming the code-paths would be the same. I was thinking about C++ specific test cases like

template <typename X>
using matrix_t = X __attribute__((matrix_type(4, 4)));

matrix_t<int> foo(matrix_t<float> x) {
  return (matrix_t<int>)x;
}

should I address it as part of this patch?

I don't think we necessarily need to implement them in this patch, unless @rjmccall could think of any issues. IMO it would still be good to add tests to Sema to ensure we do not crash. We can then just update them once support for C++ is added.

clang/include/clang/Basic/DiagnosticSemaKinds.td
8583

I think in other places we are already using matrixes. Would be good to be consistent with the existing spelling I think (but I am no English expert)

8588

I think for other messages we say ... is not allowed. Perhaps this message should be similar? Also I'm not sure about reefing to non-matrix types. We might allow at least for conversion between arithmetic types and matrixes (broadcast). It might be OK to just drop the non matrix part?

clang/include/clang/Sema/Sema.h
11714

nit: for matrix casts?

clang/lib/CodeGen/CGExprScalar.cpp
1371

You could move the code generation part to MatrixBuilder.h?

clang/lib/Sema/SemaCast.cpp
2915–2916

nit: missing comma after a scalar.

clang/lib/Sema/SemaExpr.cpp
7348

From the comment here it sounds like this function checks if the arguments are matrix types, but it asserts. Does the comment need updating?

It looks like the part after i.e. needs rewording also, as there's some duplication?

fhahn added inline comments.Apr 5 2021, 12:45 PM
clang/lib/CodeGen/CGExprScalar.cpp
1379

I think we should support all floating point type here (isFloatingPointTy). Basically we want the same rules as for integer types (around line 1418). Perhaps it would be possible to generalize this code in a separate function that takes the LLVM types & the element type/scalar types?

SaurabhJha added inline comments.Apr 6 2021, 11:19 AM
clang/lib/CodeGen/CGExprScalar.cpp
1379

I think we should move this code to MatrixBuilder but then generalising floating point after that would be problematic since the code is splitted across this function and in MatrixBuilder, right?

fhahn added inline comments.Apr 6 2021, 11:42 AM
clang/lib/CodeGen/CGExprScalar.cpp
1379

That's a good point. Sharing the logic with the scalar case in Clang directly seems much more valuable than having it in the MatrixBuilder IMO.

SaurabhJha added inline comments.Apr 6 2021, 11:48 AM
clang/lib/CodeGen/CGExprScalar.cpp
1379

Whoops, I just moved the code to MatrixBuilder. Will revert it back and generalise it :)

SaurabhJha added inline comments.Apr 6 2021, 11:52 AM
clang/include/clang/AST/OperationKinds.def
185

This line is causing me issues that I don't know how to solve. If we leave it in the current place on line 185. The new tests Sema and CodeGen tests are passing but Clang.SemaOpenCL::sampler_t.cl and Clang.SemaOpenCL::sampler_t_overload.cl (along with other sampler tests) are failing.

And if I move it to the bottom, right after CAST_OPERATION(IntToOCLSampler), the sampler tests pass but the new matrix conversion tests are failing. Am I missing something here? My understanding was implementing new cast kind is just the matter of defining a CAST_OPERATION in this file.

SaurabhJha updated this revision to Diff 335643.Apr 6 2021, 1:14 PM

Changes in latest revision:

  • Updated definition of areMatrixTypesOfTheSameDimension to reflect the comment
  • Refactored casting between types into EmitCastBetweenScalarTypes
  • Removed mentions of "non matrix"
  • Replaced matrices with matrixes
  • Update error messages to "..is not allowed"
SaurabhJha updated this revision to Diff 335677.Apr 6 2021, 4:03 PM

I reverted the int <-> float conversion to previous code to make the tests pass. That way, we atleast have something working and we can go from there.

SaurabhJha updated this revision to Diff 335680.Apr 6 2021, 4:56 PM

Fix the bug with int <-> float conversion by explicitly passing llvm types to EmitCastBetweenScalarTypes

Hey Florian and John,

Thanks for your reviews so far. Just checked the build. Addressed all previous comments and the build is looking good too except for one thing. For open cl tests, it is failing with this curious error: initializer element is not a compile-time constant which I am still not sure how to debug. I tried to debug Clang.SemaOpenCL::sampler_t_overload.cl by moving the definition of MatrixCast in OperationKinds.def to below the definition of IntToOCLSampler. That made it work for sampler_overload but then the new matrix cast tests started failing.

Will give it another shot today. If you have any thoughts on this, let me know.

Saurabh

Okay interesting I should have posted before. Seems like when I move MatrixCast to the bottom of OperationKinds.def, and do nothing else, the matrix-cast CodeGen fails with this error. It is somehow not able to assign correct cast type.

+ /tmp/build/bin/clang -cc1 -internal-isystem /tmp/build/lib/clang/13.0.0/include -nostdsysteminc -fenable-matrix -triple x86_64-apple-darwin /tmp/clang/test/CodeGen/matrix-cast.c -emit-llvm -disable-llvm-passes -o -
+ /tmp/build/bin/FileCheck /tmp/clang/test/CodeGen/matrix-cast.c
dependent cast kind in IR gen!
UNREACHABLE executed at /tmp/clang/lib/CodeGen/CGExprScalar.cpp:1985!
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: /tmp/build/bin/clang -cc1 -internal-isystem /tmp/build/lib/clang/13.0.0/include -nostdsysteminc -fenable-matrix -triple x86_64-apple-darwin /tmp/clang/test/CodeGen/matrix-cast.c -emit-llvm -disable-llvm-passes -o -
1.	/tmp/clang/test/CodeGen/matrix-cast.c:22:1: current parser token 'void'
2.	/tmp/clang/test/CodeGen/matrix-cast.c:12:6: LLVM IR generation of declaration 'cast_char_matrix_to_int'
3.	/tmp/clang/test/CodeGen/matrix-cast.c:12:6: Generating code for declaration 'cast_char_matrix_to_int'
 #0 0x000000000974250a llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /tmp/llvm/lib/Support/Unix/Signals.inc:565:11
 #1 0x00000000097426db PrintStackTraceSignalHandler(void*) /tmp/llvm/lib/Support/Unix/Signals.inc:632:1
 #2 0x0000000009740cab llvm::sys::RunSignalHandlers() /tmp/llvm/lib/Support/Signals.cpp:70:5
 #3 0x0000000009742e51 SignalHandler(int) /tmp/llvm/lib/Support/Unix/Signals.inc:407:1
 #4 0x00007f503b2923c0 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x153c0)
 #5 0x00007f503ad4318b raise /build/glibc-eX1tMB/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1
 #6 0x00007f503ad22859 abort /build/glibc-eX1tMB/glibc-2.31/stdlib/abort.c:81:7
 #7 0x0000000009661fe4 /tmp/llvm/lib/Support/ErrorHandling.cpp:213:3
 #8 0x0000000009fd93fb (anonymous namespace)::ScalarExprEmitter::VisitCastExpr(clang::CastExpr*) /tmp/clang/lib/CodeGen/CGExprScalar.cpp:1987:5
 #9 0x0000000009fd934e (anonymous namespace)::ScalarExprEmitter::VisitExplicitCastExpr(clang::ExplicitCastExpr*) /tmp/clang/lib/CodeGen/CGExprScalar.cpp:568:5
#10 0x0000000009fd17b3 clang::StmtVisitorBase<std::add_pointer, (anonymous namespace)::ScalarExprEmitter, llvm::Value*>::VisitCStyleCastExpr(clang::CStyleCastExpr*) /tmp/build/tools/clang/include/clang/AST/StmtNodes.inc:891:1
#11 0x0000000009fcb9ff clang::StmtVisitorBase<std::add_pointer, (anonymous namespace)::ScalarExprEmitter, llvm::Value*>::Visit(clang::Stmt*) /tmp/build/tools/clang/include/clang/AST/StmtNodes.inc:891:1
#12 0x0000000009fc0d0b (anonymous namespace)::ScalarExprEmitter::Visit(clang::Expr*) /tmp/clang/lib/CodeGen/CGExprScalar.cpp:415:3
#13 0x0000000009fce242 (anonymous namespace)::ScalarExprEmitter::VisitBinAssign(clang::BinaryOperator const*) /tmp/clang/lib/CodeGen/CGExprScalar.cpp:4218:9
#14 0x0000000009fca7fd clang::StmtVisitorBase<std::add_pointer, (anonymous namespace)::ScalarExprEmitter, llvm::Value*>::Visit(clang::Stmt*) /tmp/clang/include/clang/AST/StmtVisitor.h:72:26
#15 0x0000000009fc0d0b (anonymous namespace)::ScalarExprEmitter::Visit(clang::Expr*) /tmp/clang/lib/CodeGen/CGExprScalar.cpp:415:3
#16 0x0000000009fc0c66 clang::CodeGen::CodeGenFunction::EmitScalarExpr(clang::Expr const*, bool) /tmp/clang/lib/CodeGen/CGExprScalar.cpp:4807:3
#17 0x0000000009e7edec clang::CodeGen::CodeGenFunction::EmitAnyExpr(clang::Expr const*, clang::CodeGen::AggValueSlot, bool) /tmp/clang/lib/CodeGen/CGExpr.cpp:218:12
#18 0x0000000009e7ed1d clang::CodeGen::CodeGenFunction::EmitIgnoredExpr(clang::Expr const*) /tmp/clang/lib/CodeGen/CGExpr.cpp:203:19
#19 0x0000000009fed236 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) /tmp/clang/lib/CodeGen/CGStmt.cpp:118:5
#20 0x0000000009ff664b clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) /tmp/clang/lib/CodeGen/CGStmt.cpp:453:3
#21 0x0000000009e573c1 clang::CodeGen::CodeGenFunction::EmitFunctionBody(clang::Stmt const*) /tmp/clang/lib/CodeGen/CodeGenFunction.cpp:1194:5
#22 0x0000000009e57e91 clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) /tmp/clang/lib/CodeGen/CodeGenFunction.cpp:1358:3
#23 0x0000000009d0b7de clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, llvm::GlobalValue*) /tmp/clang/lib/CodeGen/CodeGenModule.cpp:4780:3
#24 0x0000000009d0215c clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) /tmp/clang/lib/CodeGen/CodeGenModule.cpp:3166:12
#25 0x0000000009d071e4 clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl) /tmp/clang/lib/CodeGen/CodeGenModule.cpp:2919:5
#26 0x0000000009d0f040 clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) /tmp/clang/lib/CodeGen/CodeGenModule.cpp:5621:38
#27 0x000000000a86b0f2 (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) /tmp/clang/lib/CodeGen/ModuleBuilder.cpp:169:73
#28 0x000000000a8654e4 clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) /tmp/clang/lib/CodeGen/CodeGenAction.cpp:215:12
#29 0x000000000cfe2475 clang::ParseAST(clang::Sema&, bool, bool) /tmp/clang/lib/Parse/ParseAST.cpp:162:20
#30 0x000000000a688572 clang::ASTFrontendAction::ExecuteAction() /tmp/clang/lib/Frontend/FrontendAction.cpp:1058:1
#31 0x000000000a861539 clang::CodeGenAction::ExecuteAction() /tmp/clang/lib/CodeGen/CodeGenAction.cpp:1039:5
#32 0x000000000a687f38 clang::FrontendAction::Execute() /tmp/clang/lib/Frontend/FrontendAction.cpp:953:7
#33 0x000000000a55a2f5 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) /tmp/clang/lib/Frontend/CompilerInstance.cpp:958:23
#34 0x000000000a84ddc6 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) /tmp/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:278:8
#35 0x000000000610c23d cc1_main(llvm::ArrayRef<char const*>, char const*, void*) /tmp/clang/tools/driver/cc1_main.cpp:246:13
#36 0x00000000060fec59 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) /tmp/clang/tools/driver/driver.cpp:338:5
#37 0x00000000060fddee main /tmp/clang/tools/driver/driver.cpp:415:5
#38 0x00007f503ad240b3 __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:342:3
#39 0x00000000060fd59e _start (/tmp/build/bin/clang+0x60fd59e)
FileCheck error: '<stdin>' is empty.
FileCheck command line:  /tmp/build/bin/FileCheck /tmp/clang/test/CodeGen/matrix-cast.c

--

********************
********************
Failed Tests (1):
  Clang :: CodeGen/matrix-cast.c


Testing Time: 21.71s
  Failed: 1
fhahn added a comment.Apr 7 2021, 3:36 AM

Hey Florian and John,

Thanks for your reviews so far. Just checked the build. Addressed all previous comments and the build is looking good too except for one thing. For open cl tests, it is failing with this curious error: initializer element is not a compile-time constant which I am still not sure how to debug. I tried to debug Clang.SemaOpenCL::sampler_t_overload.cl by moving the definition of MatrixCast in OperationKinds.def to below the definition of IntToOCLSampler. That made it work for sampler_overload but then the new matrix cast tests started failing.

Will give it another shot today. If you have any thoughts on this, let me know.

I think the issue might be that adding this additional cast-kind caused the value to exceed the maximum supported by the CastExprBitfields; the bitfield can only store 64 values, but after adding MatrixCast, CK_IntToOCLSampler will have value 64, so assigning to the bitfield results in 0 being assigned. I *think* you have to bump the bitfield size to 7 or perhaps 8 (which may result in slightly better codegen). https://github.com/llvm/llvm-project/blob/main/clang/include/clang/AST/Stmt.h#L521

clang/lib/CodeGen/CGExprScalar.cpp
1197

Can you put up a patch that just moves the existing code to the function, without adding the matrix specifics? Hopefully that would reduce the diff and make it easy to see that the non-matrix code paths are unchanged?

I think the issue might be that adding this additional cast-kind caused the value to exceed the maximum supported by the CastExprBitfields; the bitfield can only store 64 values, but after adding MatrixCast, CK_IntToOCLSampler will have value 64, so assigning to the bitfield results in 0 being assigned. I *think* you have to bump the bitfield size to 7 or perhaps 8 (which may result in slightly better codegen). https://github.com/llvm/llvm-project/blob/main/clang/include/clang/AST/Stmt.h#L521

This worked. Setting it to 7 made the tests pass.

I have created a separate patch for codegen refactoring here https://reviews.llvm.org/D100051. Once that's merged, I can rebase this patch/branch against that.

SaurabhJha updated this revision to Diff 335913.Apr 7 2021, 1:02 PM

Rebased with latest main

SaurabhJha added inline comments.Apr 7 2021, 1:08 PM
clang/lib/CodeGen/CGExprScalar.cpp
1453

Not sure why this was changed. Perhaps clang-clean.

Hopefully this will work. My IDE is a bit wonky and it will take hours to rebuild for me after rebase. So pushed here with the hope that this could be validated using web build.

fhahn added inline comments.Apr 7 2021, 2:45 PM
clang/lib/CodeGen/CGExprScalar.cpp
1219

We should be able to assert here that both types are not matrix types, I think?

1376

nit: no braces required here

1453

Not sure, but please remove the change from the diff.

Address comments

SaurabhJha added inline comments.Apr 8 2021, 12:44 AM
clang/lib/CodeGen/CGExprScalar.cpp
1219

I did !SrcType->isMatrixType() && !DstType->isMatrixType() instead of !SrcType->isMatrixType() || !DstType->isMatrixType() which I hope was the correct thing to do.

fhahn added a comment.Apr 8 2021, 2:42 AM

Thanks for the latest update! This basically looks good to me, with a few final nits!

clang/include/clang/Basic/DiagnosticSemaKinds.td
8584

nit: matrix types?

8586

nit: _and_incompatible_type?

clang/include/clang/Sema/Sema.h
11718

Can the name for Tr be improved? Perhaps ToTy or TargetTy?

clang/lib/CodeGen/CGExprScalar.cpp
1219

Thanks! Can you also add a message to the assert , like && "cannot cast between matrix and non-matrix types")

clang/lib/Sema/SemaCast.cpp
2932

nit: no braces.

clang/lib/Sema/SemaExpr.cpp
7357

nit: No ( ...... ) required here.

clang/test/CodeGen/matrix-cast.c
83

I think this is still missing a test from unsigned to signed?

SaurabhJha updated this revision to Diff 336154.Apr 8 2021, 9:44 AM

Addressed latest round of comments.
Also rebased with latest main as the windows build failed for some reason

SaurabhJha added inline comments.Apr 8 2021, 9:50 AM
clang/test/CodeGen/matrix-cast.c
83

I added a new cast_unsigned_long_int_matrix_to_short

The windows build failure is solved by itself and its all passing now!

fhahn accepted this revision.Apr 9 2021, 1:26 AM

LGTM, thanks for working on this!

clang/include/clang/Sema/Sema.h
11715

Nit: matrixes for consistency

clang/lib/CodeGen/CGExprScalar.cpp
1201–1226

I think the comment here could be a bit shorter and to the point. Perhaps something like The *Element* types are used to determine the kind of cast to perform.

The assignments are just below and probably are clear from the code.

1210

nit: matrixes for consistency

This revision is now accepted and ready to land.Apr 9 2021, 1:26 AM

LGTM, thanks for working on this!

Thanks so much Florian. Can you please also commit this on my behalf as I don't have commit access? Cheers.

Will create a new patch to address your last comments

fhahn added a comment.Apr 9 2021, 4:03 AM

Will create a new patch to address your last comments

Can you directly update this one? I'll commit it after the update.

SaurabhJha updated this revision to Diff 336395.Apr 9 2021, 4:36 AM

Replace matrices with matrixes in comments and rewrite the comment about element types

Will create a new patch to address your last comments

Can you directly update this one? I'll commit it after the update.

Sure, done. I did not know I could change the patch after its accepted.

Seems like the new build is passing. Can you please commit it on my behalf
if it looks okay to you?

Thanks a lot for your help in this patch.

Saurabh