Skip to content

Not fully support long double on some platform #931

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

Closed
ladisgin opened this issue Oct 2, 2024 · 2 comments
Closed

Not fully support long double on some platform #931

ladisgin opened this issue Oct 2, 2024 · 2 comments
Assignees
Labels
bug Something isn't working good first issue Good for newcomers

Comments

@ladisgin
Copy link

ladisgin commented Oct 2, 2024

For target x86_64-none-linux

struct A {
  long double y;
};

void foo() {
  A x;
}

Failed assert from clangir/mlir/include/mlir/IR/StorageUniquerSupport.h:180

https://godbolt.org/z/5McnErs65

stacktrace
error: IntType only supports widths from 1up to 64
clang: /home/ladisgin/git_proj/clangir/llvm/../mlir/include/mlir/IR/StorageUniquerSupport.h:180: static ConcreteT mlir::detail::StorageUserBase<ConcreteT, BaseT, StorageT, UniquerT, Traits>::get(mlir::MLIRContext*, Args&& ...) [with Args = {unsigned int, bool}; ConcreteT = mlir::cir::IntType; BaseT = mlir::Type; StorageT = mlir::cir::detail::IntTypeStorage; UniquerT = mlir::detail::TypeUniquer; Traits = {mlir::DataLayoutTypeInterface::Trait}]: Assertion `succeeded(ConcreteT::verify(getDefaultDiagnosticEmitFn(ctx), args...))' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: /home/ladisgin/git_proj/clangir/build/bin/clang -c -S -Xclang -emit-cir misaligned-param.c
1.	<eof> parser at end of file
2.	misaligned-param.c:7:13: LLVM IR generation of declaration 'foo'
 #0 0x000000000b236a1e llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/ladisgin/git_proj/clangir/llvm/lib/Support/Unix/Signals.inc:723:22
 #1 0x000000000b236e5c PrintStackTraceSignalHandler(void*) /home/ladisgin/git_proj/clangir/llvm/lib/Support/Unix/Signals.inc:798:1
 #2 0x000000000b23465e llvm::sys::RunSignalHandlers() /home/ladisgin/git_proj/clangir/llvm/lib/Support/Signals.cpp:105:20
 #3 0x000000000b2362fe llvm::sys::CleanupOnSignal(unsigned long) /home/ladisgin/git_proj/clangir/llvm/lib/Support/Unix/Signals.inc:367:31
 #4 0x000000000b167656 (anonymous namespace)::CrashRecoveryContextImpl::HandleCrash(int, unsigned long) /home/ladisgin/git_proj/clangir/llvm/lib/Support/CrashRecoveryContext.cpp:73:5
 #5 0x000000000b167ae5 CrashRecoverySignalHandler(int) /home/ladisgin/git_proj/clangir/llvm/lib/Support/CrashRecoveryContext.cpp:391:1
 #6 0x00007f31ea64fd00 __restore_rt (/lib64/libc.so.6+0x40d00)
 #7 0x00007f31ea6a8664 __pthread_kill_implementation (/lib64/libc.so.6+0x99664)
 #8 0x00007f31ea64fc4e gsignal (/lib64/libc.so.6+0x40c4e)
 #9 0x00007f31ea637902 abort (/lib64/libc.so.6+0x28902)
#10 0x00007f31ea63781e _nl_load_domain.cold (/lib64/libc.so.6+0x2881e)
#11 0x00007f31ea647d87 (/lib64/libc.so.6+0x38d87)
#12 0x000000000f0dbdc3 mlir::cir::IntType mlir::detail::StorageUserBase<mlir::cir::IntType, mlir::Type, mlir::cir::detail::IntTypeStorage, mlir::detail::TypeUniquer, mlir::DataLayoutTypeInterface::Trait>::get<unsigned int, bool>(mlir::MLIRContext*, unsigned int&&, bool&&) /home/ladisgin/git_proj/clangir/llvm/../mlir/include/mlir/IR/StorageUniquerSupport.h:180:5
#13 0x000000000f0d0383 mlir::cir::IntType::get(mlir::MLIRContext*, unsigned int, bool) /home/ladisgin/git_proj/clangir/build/tools/clang/include/clang/CIR/Dialect/IR/CIROpsTypes.cpp.inc:224:1
#14 0x000000000d751e6a (anonymous namespace)::CIRRecordLowering::getUIntNType(unsigned long) /home/ladisgin/git_proj/clangir/clang/lib/CIR/CodeGen/CIRRecordLayoutBuilder.cpp:146:35
#15 0x000000000d754072 (anonymous namespace)::CIRRecordLowering::determinePacked(bool) /home/ladisgin/git_proj/clangir/clang/lib/CIR/CodeGen/CIRRecordLayoutBuilder.cpp:660:39
#16 0x000000000d75269a (anonymous namespace)::CIRRecordLowering::lower(bool) /home/ladisgin/git_proj/clangir/clang/lib/CIR/CodeGen/CIRRecordLayoutBuilder.cpp:299:16
#17 0x000000000d754557 cir::CIRGenTypes::computeRecordLayout(clang::RecordDecl const*, mlir::cir::StructType*) /home/ladisgin/git_proj/clangir/clang/lib/CIR/CodeGen/CIRRecordLayoutBuilder.cpp:698:25
#18 0x000000000d6771ae cir::CIRGenTypes::convertRecordDeclType(clang::RecordDecl const*) /home/ladisgin/git_proj/clangir/clang/lib/CIR/CodeGen/CIRGenTypes.cpp:225:22
#19 0x000000000d677929 cir::CIRGenTypes::ConvertType(clang::QualType) /home/ladisgin/git_proj/clangir/clang/lib/CIR/CodeGen/CIRGenTypes.cpp:367:55
#20 0x000000000d75d274 (anonymous namespace)::X86_64ABIInfo::computeInfo(cir::CIRGenFunctionInfo&) const /home/ladisgin/git_proj/clangir/clang/lib/CIR/CodeGen/TargetInfo.cpp:331:39
#21 0x000000000d678cb3 cir::CIRGenTypes::arrangeCIRFunctionInfo(clang::CanQual<clang::Type>, cir::FnInfoOpts, llvm::ArrayRef<clang::CanQual<clang::Type>>, clang::FunctionType::ExtInfo, llvm::ArrayRef<clang::FunctionType::ExtParameterInfo>, cir::RequiredArgs) /home/ladisgin/git_proj/clangir/clang/lib/CIR/CodeGen/CIRGenTypes.cpp:805:42
#22 0x000000000d685df3 arrangeCIRFunctionInfo(cir::CIRGenTypes&, cir::FnInfoOpts, llvm::SmallVectorImpl<clang::CanQual<clang::Type>>&, clang::CanQual<clang::FunctionProtoType>) /home/ladisgin/git_proj/clangir/clang/lib/CIR/CodeGen/CIRGenCall.cpp:1225:36
#23 0x000000000d685e5b cir::CIRGenTypes::arrangeFreeFunctionType(clang::CanQual<clang::FunctionProtoType>) /home/ladisgin/git_proj/clangir/clang/lib/CIR/CodeGen/CIRGenCall.cpp:1234:34
#24 0x000000000d687268 cir::CIRGenTypes::arrangeFunctionDeclaration(clang::FunctionDecl const*) /home/ladisgin/git_proj/clangir/clang/lib/CIR/CodeGen/CIRGenCall.cpp:1530:65
#25 0x000000000d678fbc cir::CIRGenTypes::arrangeGlobalDeclaration(clang::GlobalDecl) /home/ladisgin/git_proj/clangir/clang/lib/CIR/CodeGen/CIRGenTypes.cpp:829:39
#26 0x000000000d60c5f0 cir::CIRGenModule::buildGlobalFunctionDefinition(clang::GlobalDecl, mlir::Operation*) /home/ladisgin/git_proj/clangir/clang/lib/CIR/CodeGen/CIRGenModule.cpp:569:69
#27 0x000000000d60fb5b cir::CIRGenModule::buildGlobalDefinition(clang::GlobalDecl, mlir::Operation*) /home/ladisgin/git_proj/clangir/clang/lib/CIR/CodeGen/CIRGenModule.cpp:1374:5
#28 0x000000000d60c37a cir::CIRGenModule::buildGlobal(clang::GlobalDecl) /home/ladisgin/git_proj/clangir/clang/lib/CIR/CodeGen/CIRGenModule.cpp:538:5
#29 0x000000000d611551 cir::CIRGenModule::buildTopLevelDecl(clang::Decl*) /home/ladisgin/git_proj/clangir/clang/lib/CIR/CodeGen/CIRGenModule.cpp:1728:5
#30 0x000000000d608334 cir::CIRGenerator::HandleTopLevelDecl(clang::DeclGroupRef) /home/ladisgin/git_proj/clangir/clang/lib/CIR/CodeGen/CIRGenerator.cpp:84:3
#31 0x000000000d36fe5d cir::CIRGenConsumer::HandleTopLevelDecl(clang::DeclGroupRef) /home/ladisgin/git_proj/clangir/clang/lib/CIR/FrontendAction/CIRGenAction.cpp:156:12
#32 0x00000000113b6230 clang::ParseAST(clang::Sema&, bool, bool) /home/ladisgin/git_proj/clangir/clang/lib/Parse/ParseAST.cpp:167:20
#33 0x000000000c6a1ba4 clang::ASTFrontendAction::ExecuteAction() /home/ladisgin/git_proj/clangir/clang/lib/Frontend/FrontendAction.cpp:1212:11
#34 0x000000000d36e2a7 cir::CIRGenAction::ExecuteAction() /home/ladisgin/git_proj/clangir/clang/lib/CIR/FrontendAction/CIRGenAction.cpp:405:5
#35 0x000000000c6a1501 clang::FrontendAction::Execute() /home/ladisgin/git_proj/clangir/clang/lib/Frontend/FrontendAction.cpp:1102:38
#36 0x000000000c5c4048 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) /home/ladisgin/git_proj/clangir/clang/lib/Frontend/CompilerInstance.cpp:1061:42
#37 0x000000000c849e1d clang::ExecuteCompilerInvocation(clang::CompilerInstance*) /home/ladisgin/git_proj/clangir/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:369:38
#38 0x00000000094772cf cc1_main(llvm::ArrayRef<char const*>, char const*, void*) /home/ladisgin/git_proj/clangir/clang/tools/driver/cc1_main.cpp:232:40
#39 0x0000000009469746 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) /home/ladisgin/git_proj/clangir/clang/tools/driver/driver.cpp:215:20
#40 0x0000000009469929 clang_main(int, char**, llvm::ToolContext const&)::'lambda'(llvm::SmallVectorImpl<char const*>&)::operator()(llvm::SmallVectorImpl<char const*>&) const /home/ladisgin/git_proj/clangir/clang/tools/driver/driver.cpp:356:5
#41 0x000000000946aec7 int llvm::function_ref<int (llvm::SmallVectorImpl<char const*>&)>::callback_fn<clang_main(int, char**, llvm::ToolContext const&)::'lambda'(llvm::SmallVectorImpl<char const*>&)>(long, llvm::SmallVectorImpl<char const*>&) /home/ladisgin/git_proj/clangir/llvm/include/llvm/ADT/STLFunctionalExtras.h:47:3
#42 0x000000000c41c299 llvm::function_ref<int (llvm::SmallVectorImpl<char const*>&)>::operator()(llvm::SmallVectorImpl<char const*>&) const /home/ladisgin/git_proj/clangir/llvm/include/llvm/ADT/STLFunctionalExtras.h:69:3
#43 0x000000000c41b008 clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::'lambda'()::operator()() const /home/ladisgin/git_proj/clangir/clang/lib/Driver/Job.cpp:440:32
#44 0x000000000c41b42d void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::'lambda'()>(long) /home/ladisgin/git_proj/clangir/llvm/include/llvm/ADT/STLFunctionalExtras.h:46:40
#45 0x0000000009e7d46c llvm::function_ref<void ()>::operator()() const /home/ladisgin/git_proj/clangir/llvm/include/llvm/ADT/STLFunctionalExtras.h:68:62
#46 0x000000000b167cb2 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) /home/ladisgin/git_proj/clangir/llvm/lib/Support/CrashRecoveryContext.cpp:427:10
#47 0x000000000c41b1fc clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const /home/ladisgin/git_proj/clangir/clang/lib/Driver/Job.cpp:440:7
#48 0x000000000c3b9f61 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const /home/ladisgin/git_proj/clangir/clang/lib/Driver/Compilation.cpp:199:22
#49 0x000000000c3ba28d clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const /home/ladisgin/git_proj/clangir/clang/lib/Driver/Compilation.cpp:253:62
#50 0x000000000c3ccb10 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) /home/ladisgin/git_proj/clangir/clang/lib/Driver/Driver.cpp:1951:28
#51 0x000000000946aa83 clang_main(int, char**, llvm::ToolContext const&) /home/ladisgin/git_proj/clangir/clang/tools/driver/driver.cpp:391:39
#52 0x000000000949fe7f main /home/ladisgin/git_proj/clangir/build/tools/clang/tools/driver/clang-driver.cpp:17:20
#53 0x00007f31ea639088 __libc_start_call_main (/lib64/libc.so.6+0x2a088)
#54 0x00007f31ea63914b __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x2a14b)
#55 0x0000000009468ba5 _start (/home/ladisgin/git_proj/clangir/build/bin/clang+0x9468ba5)
clang: error: clang frontend command failed with exit code 134 (use -v to see invocation)
clang version 19.0.0git ([email protected]:llvm/clangir.git 52323c17c6a3708b3eb72651465f7d4b82f057e7)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/ladisgin/git_proj/clangir/build/bin
Build config: +unoptimized, +assertions
clang: error: unable to execute command: Aborted (core dumped)
clang: note: diagnostic msg: Error generating preprocessed source(s).

@smeenai also gave another example in the discord for aarch64-none-linux-android21. https://godbolt.org/z/8Y85148EY

@bcardosolopes bcardosolopes added bug Something isn't working good first issue Good for newcomers labels Oct 2, 2024
@mvvsmk
Copy link
Contributor

mvvsmk commented Oct 9, 2024

I would love to work on this issue:
With some preliminary testing I have found the following :

test case 1 (https://godbolt.org/z/5McnErs65) (struct {long double})

  1. the CIRRecordLowering::determinePacked function calls the following
    /// Wraps mlir::cir::IntType with some implicit arguments.
    mlir::Type getUIntNType(uint64_t NumBits) {
    unsigned AlignedBits = llvm::PowerOf2Ceil(NumBits);
    AlignedBits = std::max(8u, AlignedBits);
    return mlir::cir::IntType::get(&cirGenTypes.getMLIRContext(), AlignedBits,
    /*isSigned=*/false);
    }

Note

here mlir::cir::IntType::get I presume, is specialized for int, I couldn't verify, ( I am new to tablegen; could you point to
where I could find its definition)

test case 2 ( https://godbolt.org/z/8Y85148EY) (global long double)

  1. I don't think the long double type is completely implimented, this is the condition where it fails if (&format == &llvm::APFloat::IEEEquad())
    mlir::cir::LongDoubleType
    getLongDoubleTy(const llvm::fltSemantics &format) const {
    if (&format == &llvm::APFloat::IEEEdouble())
    return mlir::cir::LongDoubleType::get(getContext(), typeCache.DoubleTy);
    if (&format == &llvm::APFloat::x87DoubleExtended())
    return mlir::cir::LongDoubleType::get(getContext(), typeCache.FP80Ty);
    if (&format == &llvm::APFloat::IEEEquad())
    llvm_unreachable("NYI");
    if (&format == &llvm::APFloat::PPCDoubleDouble())
    llvm_unreachable("NYI");
    llvm_unreachable("unsupported long double format");
    }

Leads

  • I believe we need to add the implementation in CIRGenBuilder ( I don't know what to add here: maybe another member variable for typeCache is the way to go)
  • For test case 1, I can dig deeper if I can find the implementation.
    Any suggestions are much appreciated :)

@Lancern
Copy link
Member

Lancern commented Oct 10, 2024

@mvvsmk Thanks for trying to solve this issue!

here mlir::cir::IntType::get I presume, is specialized for int, I couldn't verify, ( I am new to tablegen; could you point to where I could find its definition)

You can find the TableGen definition at

def CIR_IntType : CIR_Type<"Int", "int",
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {

I don't think the long double type is completely implimented, this is the condition where it fails

Indeed. The long double type is kinda a mess and it has different underlying floating point formats on different targets. Currently CIR only supports the fp64 and fp80 formats, the fp128 format (a.k.a. IEEEquad) format is not supported yet.

I believe we need to add the implementation in CIRGenBuilder ( I don't know what to add here: maybe another member variable for typeCache is the way to go)

Actually the implementation may require more work.

The long double type is represented in CIR as !cir.long_double. This MLIR type has a type parameter that indicates the underlying format. For example, on x86_64 linux where long double uses fp80 as the underlying format, long double is lowered to !cir.long_double<!cir.f80>. On x86_64 Windows where long double uses fp64 as the underlying format, long double is lowered to !cir.long_double<!cir.double>. However we don't have a CIR type yet that represents the fp128 format. So the first step you may want to do is to add a new type !cir.f128. You can reference to https://github.com/llvm/clangir/blob/main/clang/include/clang/CIR/Dialect/IR/CIRTypes.td for how to define a new floating point type. Once you add the !cir.f128 type, you may also want to update the verifier of !cir.long_double to make it accept !cir.f128 as its parameter. The verifier can be found at

LogicalResult
LongDoubleType::verify(function_ref<InFlightDiagnostic()> emitError,
mlir::Type underlying) {

Then you could start emitting this new long double type variant. Obviously you need to update the CIRGenBuilder here, and you may also have to resolve other assert failures along the way.

For test case 1, I can dig deeper if I can find the implementation.

I believe the story behind test case 1 is more subtle. The direct cause of test case 1 is not missing fp128 support, but the lack of support for 128-bit integers. This is already tracked in #953 .

keryell pushed a commit to keryell/clangir that referenced this issue Oct 19, 2024
…d (in CIR + Direct to LLVM) (llvm#966)

Fixes llvm#931
Added type definition in CIRTypes.td, created appropriate functions for
the same in CIRTypes.cpp like getPreferredAlignment,
getPreferredAlignment, etc. Optionally added lowering in LowerToLLVM.cpp
lanza pushed a commit that referenced this issue Nov 5, 2024
…d (in CIR + Direct to LLVM) (#966)

Fixes #931
Added type definition in CIRTypes.td, created appropriate functions for
the same in CIRTypes.cpp like getPreferredAlignment,
getPreferredAlignment, etc. Optionally added lowering in LowerToLLVM.cpp
lanza pushed a commit that referenced this issue Mar 18, 2025
…d (in CIR + Direct to LLVM) (#966)

Fixes #931
Added type definition in CIRTypes.td, created appropriate functions for
the same in CIRTypes.cpp like getPreferredAlignment,
getPreferredAlignment, etc. Optionally added lowering in LowerToLLVM.cpp
xlauko pushed a commit to trailofbits/instafix-llvm that referenced this issue Mar 28, 2025
…d (in CIR + Direct to LLVM) (llvm#966)

Fixes llvm/clangir#931
Added type definition in CIRTypes.td, created appropriate functions for
the same in CIRTypes.cpp like getPreferredAlignment,
getPreferredAlignment, etc. Optionally added lowering in LowerToLLVM.cpp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

4 participants