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

Florian Hahn via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 25 02:09:59 PDT 2021


fhahn added a comment.

In D99037#2649065 <https://reviews.llvm.org/D99037#2649065>, @SaurabhJha wrote:

> 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 <https://github.com/llvm/llvm-project/blob/5d6b4aa80d6df62b924a12af030c5ded868ee4f1/llvm/lib/IR/Instructions.cpp#L2934> cast is failing. And my suspicion is that's because we are not handling matrix types here <https://github.com/llvm/llvm-project/blob/5d6b4aa80d6df62b924a12af030c5ded868ee4f1/llvm/lib/IR/Instructions.cpp#L3317-L3398>. 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.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D99037/new/

https://reviews.llvm.org/D99037



More information about the cfe-commits mailing list