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

Support for bitfields #13

Closed
bcardosolopes opened this issue Sep 26, 2022 · 5 comments
Closed

Support for bitfields #13

bcardosolopes opened this issue Sep 26, 2022 · 5 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@bcardosolopes
Copy link
Member

Involves adding new CIR operations and CodeGen support.

@bcardosolopes bcardosolopes added enhancement New feature or request good first issue Good for newcomers labels Sep 26, 2022
@felipealmeida
Copy link

Hello @bcardosolopes ,

I'm moving all discussion to here. About your comment: "It might also be worth checking out how polygeist does some of that lowering, could provide interesting insights.". Unfortunately I haven't found absolutely anything about bitfields in Polygeist. I looked online and shallowly in the source code. I'll take a deeper look soon, but it may very well be that we are the first, specially because bitfields are not very well seen and hardly does what people expect it to do (standard-wise), but it still useful where implementation defined behavior is OK (which is my case).

@bcardosolopes
Copy link
Member Author

Ok, looks like we have some interesting land to explore, thanks for taking a look @felipealmeida - we much very want to see support for bitfields too.

@felipealmeida
Copy link

Hello, I'm using this example:

struct field {
  char c;
  unsigned i0 : 8;
  unsigned i1 : 8;
  unsigned i2 : 8;
  unsigned i3 : 8;
  char d;
};


void foo (struct field* f, char a) {

}

Generating this (as a test):

#loc2 = loc(fused["test.c":12:11, "test.c":12:25])
#loc3 = loc(fused["test.c":12:28, "test.c":12:33])
module {
  cir.func @foo(%arg0: !cir.ptr<!cir.struct<"struct.field", i8, !cir.bitfield<i32, "offsets"<0, 8, 16, 24>, "sizes"<8, 8, 8, 8> >, i8>> loc(fused["test.c":12:11, "test.c":12:25]), %arg1: i8 loc(fused["test.c":12:28, "test.c":12:33])) {
    %0 = cir.alloca !cir.ptr<!cir.struct<"struct.field", i8, !cir.bitfield<i32, "offsets"<0, 8, 16, 24>, "sizes"<8, 8, 8, 8> >, i8>>, cir.ptr <!cir.ptr<!cir.struct<"struct.field", i8, !cir.bitfield<i32, "offsets"<0, 8, 16, 24>, "sizes"<8, 8, 8, 8> >, i8>>>, ["f", paraminit] {alignment = 8 : i64} loc(#loc2)
    %1 = cir.alloca i8, cir.ptr <i8>, ["a", paraminit] {alignment = 1 : i64} loc(#loc3)
    cir.store %arg0, %0 : !cir.ptr<!cir.struct<"struct.field", i8, !cir.bitfield<i32, "offsets"<0, 8, 16, 24>, "sizes"<8, 8, 8, 8> >, i8>>, cir.ptr <!cir.ptr<!cir.struct<"struct.field", i8, !cir.bitfield<i32, "offsets"<0, 8, 16, 24>, "sizes"<8, 8, 8, 8> >, i8>>> loc(#loc4)
    cir.store %arg1, %1 : i8, cir.ptr <i8> loc(#loc4)
    cir.return loc(#loc5)
  } loc(#loc1)
} loc(#loc0)
#loc0 = loc(unknown)
#loc1 = loc(fused["test.c":12:1, "test.c":14:1])
#loc4 = loc("test.c":12:36)
#loc5 = loc("test.c":14:1)

I don't think the current bitfield definition is good, probably not even legal, maybe cir.bitfield<i32, [0, 8], [8, 8], [16, 8], [24, 8]>. Let me know if anyone has any criticism.

Kind regards,

lanza pushed a commit that referenced this issue Dec 20, 2022
…D112621

It seems like `LHS` and `RHS` could be empty range sets.
This caused an assertion failure inside RangeConstraintManager.

I'm hoisting out the check from the function into the call-site.
This way we could assert that we only want to deal with non-empty range
sets.

The relevant part of the trace:
```
 #6 0x00007fe6ff5f81a6 __assert_fail_base (/lib64/libc.so.6+0x2f1a6)
 #7 0x00007fe6ff5f8252 (/lib64/libc.so.6+0x2f252)
 #8 0x00000000049caed2 (anonymous namespace)::SymbolicRangeInferrer::VisitBinaryOperator(clang::ento::RangeSet, clang::BinaryOperatorKind, clang::ento::RangeSet, clang::QualType) RangeConstraintManager.cpp:0:0
 #9 0x00000000049c9867 (anonymous namespace)::SymbolicRangeInferrer::infer(clang::ento::SymExpr const*) RangeConstraintManager.cpp:0:0
#10 0x00000000049bebf5 (anonymous namespace)::RangeConstraintManager::assumeSymNE(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::ento::SymExpr const*, llvm::APSInt const&, llvm::APSInt const&) RangeConstraintManager.cpp:0:0
#11 0x00000000049d368c clang::ento::RangedConstraintManager::assumeSymUnsupported(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::ento::SymExpr const*, bool) (../../main-github/llvm/build-all/bin/clang+0x49d368c)
#12 0x00000000049f0b09 clang::ento::SimpleConstraintManager::assumeAux(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::ento::NonLoc, bool) (../../main-github/llvm/build-all/bin/clang+0x49f0b09)
#13 0x00000000049f096a clang::ento::SimpleConstraintManager::assume(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::ento::NonLoc, bool) (../../main-github/llvm/build-all/bin/clang+0x49f096a)
#14 0x00000000049f086d clang::ento::SimpleConstraintManager::assumeInternal(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::ento::DefinedSVal, bool) (../../main-github/llvm/build-all/bin/clang+0x49f086d)
#15 0x000000000492d3e3 clang::ento::ConstraintManager::assumeDual(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::ento::DefinedSVal) (../../main-github/llvm/build-all/bin/clang+0x492d3e3)
#16 0x0000000004955b6d clang::ento::ExprEngine::evalEagerlyAssumeBinOpBifurcation(clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNodeSet&, clang::Expr const*) (../../main-github/llvm/build-all/bin/clang+0x4955b6d)
#17 0x00000000049514b6 clang::ento::ExprEngine::Visit(clang::Stmt const*, clang::ento::ExplodedNode*, clang::ento::ExplodedNodeSet&) (../../main-github/llvm/build-all/bin/clang+0x49514b6)
#18 0x000000000494c73e clang::ento::ExprEngine::ProcessStmt(clang::Stmt const*, clang::ento::ExplodedNode*) (../../main-github/llvm/build-all/bin/clang+0x494c73e)
#19 0x000000000494c459 clang::ento::ExprEngine::processCFGElement(clang::CFGElement, clang::ento::ExplodedNode*, unsigned int, clang::ento::NodeBuilderContext*) (../../main-github/llvm/build-all/bin/clang+0x494c459)
#20 0x000000000492f3d0 clang::ento::CoreEngine::HandlePostStmt(clang::CFGBlock const*, unsigned int, clang::ento::ExplodedNode*) (../../main-github/llvm/build-all/bin/clang+0x492f3d0)
#21 0x000000000492e1f6 clang::ento::CoreEngine::ExecuteWorkList(clang::LocationContext const*, unsigned int, llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>) (../../main-github/llvm/build-all/bin/clang+0x492e1f6)
```

Differential Revision: https://reviews.llvm.org/D112621
lanza pushed a commit that referenced this issue May 3, 2023
This change prevents rare deadlocks observed for specific macOS/iOS GUI
applications which issue many `dlopen()` calls from multiple different
threads at startup and where TSan finds and reports a race during
startup.  Providing a reliable test for this has been deemed infeasible.

Although I've only observed this deadlock on Apple platforms,
conceptually the cause is not confined to Apple code so the fix lives in
platform-independent code.

Deadlock scenario:
```
Thread 2                    | Thread 4
ReportRace()                |
Lock internal TSan mutexes  |
  &ctx->slot_mtx            |
                            | dlopen() interceptor
                            | OnLibraryLoaded()
                            | MemoryMappingLayout::DumpListOfModules()
                            | calls dyld API, which takes internal lock
                            | lock() interceptor
                            | TSan tries to take internal mutexes again
                            |   &ctx->slot_mtx
call into symbolizer        |
MemoryMappingLayout::DumpListOfModules()
calls dyld API, which hangs on trying to take lock
```
Resulting in:
* Thread 2 has internal TSan mutex, blocked on dyld lock
* Thread 4 has dyld lock, blocked on internal TSan mutex

The fix prevents this situation by not intercepting any of the calls
originating from `MemoryMappingLayout::DumpListOfModules()`.

Stack traces for deadlock between ReportRace() and dlopen() interceptor:
```
thread #2, queue = 'com.apple.root.default-qos'
  frame #0: libsystem_kernel.dylib
  frame #1: libclang_rt.tsan_osx_dynamic.dylib`::wrap_os_unfair_lock_lock_with_options(lock=<unavailable>, options=<unavailable>) at tsan_interceptors_mac.cpp:306:3
  frame #2: dyld`dyld4::RuntimeLocks::withLoadersReadLock(this=0x000000016f21b1e0, work=0x00000001814523c0) block_pointer) at DyldRuntimeState.cpp:227:28
  frame #3: dyld`dyld4::APIs::_dyld_get_image_header(this=0x0000000101012a20, imageIndex=614) at DyldAPIs.cpp:240:11
  frame #4: libclang_rt.tsan_osx_dynamic.dylib`__sanitizer::MemoryMappingLayout::CurrentImageHeader(this=<unavailable>) at sanitizer_procmaps_mac.cpp:391:35
  frame #5: libclang_rt.tsan_osx_dynamic.dylib`__sanitizer::MemoryMappingLayout::Next(this=0x000000016f2a2800, segment=0x000000016f2a2738) at sanitizer_procmaps_mac.cpp:397:51
  frame #6: libclang_rt.tsan_osx_dynamic.dylib`__sanitizer::MemoryMappingLayout::DumpListOfModules(this=0x000000016f2a2800, modules=0x00000001011000a0) at sanitizer_procmaps_mac.cpp:460:10
  frame #7: libclang_rt.tsan_osx_dynamic.dylib`__sanitizer::ListOfModules::init(this=0x00000001011000a0) at sanitizer_mac.cpp:610:18
  frame #8: libclang_rt.tsan_osx_dynamic.dylib`__sanitizer::Symbolizer::FindModuleForAddress(unsigned long) [inlined] __sanitizer::Symbolizer::RefreshModules(this=0x0000000101100078) at sanitizer_symbolizer_libcdep.cpp:185:12
  frame #9: libclang_rt.tsan_osx_dynamic.dylib`__sanitizer::Symbolizer::FindModuleForAddress(this=0x0000000101100078, address=6465454512) at sanitizer_symbolizer_libcdep.cpp:204:5
  frame #10: libclang_rt.tsan_osx_dynamic.dylib`__sanitizer::Symbolizer::SymbolizePC(this=0x0000000101100078, addr=6465454512) at sanitizer_symbolizer_libcdep.cpp:88:15
  frame #11: libclang_rt.tsan_osx_dynamic.dylib`__tsan::SymbolizeCode(addr=6465454512) at tsan_symbolize.cpp:106:35
  frame #12: libclang_rt.tsan_osx_dynamic.dylib`__tsan::SymbolizeStack(trace=StackTrace @ 0x0000600002d66d00) at tsan_rtl_report.cpp:112:28
  frame #13: libclang_rt.tsan_osx_dynamic.dylib`__tsan::ScopedReportBase::AddMemoryAccess(this=0x000000016f2a2a90, addr=4381057136, external_tag=<unavailable>, s=<unavailable>, tid=<unavailable>, stack=<unavailable>, mset=0x00000001012fc310) at tsan_rtl_report.cpp:190:16
  frame #14: libclang_rt.tsan_osx_dynamic.dylib`__tsan::ReportRace(thr=0x00000001012fc000, shadow_mem=0x000008020a4340e0, cur=<unavailable>, old=<unavailable>, typ0=1) at tsan_rtl_report.cpp:795:9
  frame #15: libclang_rt.tsan_osx_dynamic.dylib`__tsan::DoReportRace(thr=0x00000001012fc000, shadow_mem=0x000008020a4340e0, cur=Shadow @ x22, old=Shadow @ 0x0000600002d6b4f0, typ=1) at tsan_rtl_access.cpp:166:3
  frame #16: libclang_rt.tsan_osx_dynamic.dylib`::__tsan_read8(void *) at tsan_rtl_access.cpp:220:5
  frame #17: libclang_rt.tsan_osx_dynamic.dylib`::__tsan_read8(void *) [inlined] __tsan::MemoryAccess(thr=0x00000001012fc000, pc=<unavailable>, addr=<unavailable>, size=8, typ=1) at tsan_rtl_access.cpp:442:3
  frame #18: libclang_rt.tsan_osx_dynamic.dylib`::__tsan_read8(addr=<unavailable>) at tsan_interface.inc:34:3
  <call into TSan from from instrumented code>

thread #4, queue = 'com.apple.dock.fullscreen'
  frame #0:  libsystem_kernel.dylib
  frame #1:  libclang_rt.tsan_osx_dynamic.dylib`__sanitizer::FutexWait(p=<unavailable>, cmp=<unavailable>) at sanitizer_mac.cpp:540:3
  frame #2:  libclang_rt.tsan_osx_dynamic.dylib`__sanitizer::Semaphore::Wait(this=<unavailable>) at sanitizer_mutex.cpp:35:7
  frame #3:  libclang_rt.tsan_osx_dynamic.dylib`__sanitizer::Mutex::Lock(this=0x0000000102992a80) at sanitizer_mutex.h:196:18
  frame #4:  libclang_rt.tsan_osx_dynamic.dylib`__tsan::ScopedInterceptor::~ScopedInterceptor() [inlined] __sanitizer::GenericScopedLock<__sanitizer::Mutex>::GenericScopedLock(this=<unavailable>, mu=0x0000000102992a80) at sanitizer_mutex.h:383:10
  frame #5:  libclang_rt.tsan_osx_dynamic.dylib`__tsan::ScopedInterceptor::~ScopedInterceptor() [inlined] __sanitizer::GenericScopedLock<__sanitizer::Mutex>::GenericScopedLock(this=<unavailable>, mu=0x0000000102992a80) at sanitizer_mutex.h:382:77
  frame #6:  libclang_rt.tsan_osx_dynamic.dylib`__tsan::ScopedInterceptor::~ScopedInterceptor() at tsan_rtl.h:708:10
  frame #7:  libclang_rt.tsan_osx_dynamic.dylib`__tsan::ScopedInterceptor::~ScopedInterceptor() [inlined] __tsan::TryTraceFunc(thr=0x000000010f084000, pc=0) at tsan_rtl.h:751:7
  frame #8:  libclang_rt.tsan_osx_dynamic.dylib`__tsan::ScopedInterceptor::~ScopedInterceptor() [inlined] __tsan::FuncExit(thr=0x000000010f084000) at tsan_rtl.h:798:7
  frame #9:  libclang_rt.tsan_osx_dynamic.dylib`__tsan::ScopedInterceptor::~ScopedInterceptor(this=0x000000016f3ba280) at tsan_interceptors_posix.cpp:300:5
  frame #10: libclang_rt.tsan_osx_dynamic.dylib`__tsan::ScopedInterceptor::~ScopedInterceptor(this=<unavailable>) at tsan_interceptors_posix.cpp:293:41
  frame #11: libclang_rt.tsan_osx_dynamic.dylib`::wrap_os_unfair_lock_lock_with_options(lock=0x000000016f21b1e8, options=OS_UNFAIR_LOCK_NONE) at tsan_interceptors_mac.cpp:310:1
  frame #12: dyld`dyld4::RuntimeLocks::withLoadersReadLock(this=0x000000016f21b1e0, work=0x00000001814525d4) block_pointer) at DyldRuntimeState.cpp:227:28
  frame #13: dyld`dyld4::APIs::_dyld_get_image_vmaddr_slide(this=0x0000000101012a20, imageIndex=412) at DyldAPIs.cpp:273:11
  frame #14: libclang_rt.tsan_osx_dynamic.dylib`__sanitizer::MemoryMappingLayout::Next(__sanitizer::MemoryMappedSegment*) at sanitizer_procmaps_mac.cpp:286:17
  frame #15: libclang_rt.tsan_osx_dynamic.dylib`__sanitizer::MemoryMappingLayout::Next(this=0x000000016f3ba560, segment=0x000000016f3ba498) at sanitizer_procmaps_mac.cpp:432:15
  frame #16: libclang_rt.tsan_osx_dynamic.dylib`__sanitizer::MemoryMappingLayout::DumpListOfModules(this=0x000000016f3ba560, modules=0x000000016f3ba618) at sanitizer_procmaps_mac.cpp:460:10
  frame #17: libclang_rt.tsan_osx_dynamic.dylib`__sanitizer::ListOfModules::init(this=0x000000016f3ba618) at sanitizer_mac.cpp:610:18
  frame #18: libclang_rt.tsan_osx_dynamic.dylib`__sanitizer::LibIgnore::OnLibraryLoaded(this=0x0000000101f3aa40, name="<some library>") at sanitizer_libignore.cpp:54:11
  frame #19: libclang_rt.tsan_osx_dynamic.dylib`::wrap_dlopen(filename="<some library>", flag=<unavailable>) at sanitizer_common_interceptors.inc:6466:3
  <library code>
```

rdar://106766395

Differential Revision: https://reviews.llvm.org/D146593
@gitoleg
Copy link
Collaborator

gitoleg commented Jun 28, 2023

Hey,
as far as I understand there is no progress on this issue, so can you give an advice on implementation? The part I think about is mlir::LValue that is similar to clang::LValue, but lack the union with BitFieldInfo, and looks like it's not easy to implement it, since the value is not stored by pointer. So... Any ideas? Thank you!

@gitoleg
Copy link
Collaborator

gitoleg commented Jun 29, 2023

Is it a right place to discuss CIR design questions?

gitoleg added a commit to gitoleg/clangir that referenced this issue Aug 14, 2023
bcardosolopes added a commit that referenced this issue Sep 15, 2023
Breaks ninja check-clang-cir

This reverts commit 471e568.
gitoleg added a commit to gitoleg/clangir that referenced this issue Sep 25, 2023
bcardosolopes pushed a commit that referenced this issue Sep 26, 2023
This is an updated PR for [PR
#233](#233) with some fixes
explained in [PR #261](#261) which
now can be safely closed.

First of all, let me introduce how do the bitfields looks like in CIR.
For the struct `S` defined as following:
```
typedef struct {
  int a : 4;
  int b : 27;
  int c : 17;
  int d : 2;
  int e : 15;  
  unsigned f;
} S; 
```
the CIR type is `!ty_22S22 = !cir.struct<struct "S" {!u32i, !u32i,
!u16i, !u32i} #cir.record.decl.ast>` where all the bitfields are packed
in the first three storages.
 
Also, the next bugs was fixed:
- type mismatch
- index out of bounds
- single bitfield of size < 8 

The cases covered with tests.
lanza pushed a commit that referenced this issue Oct 27, 2023
This PR introduces bitfelds support.  This now works:

```
#include <stdio.h>

typedef struct {
    int a1 : 4;
    int a2 : 28;
    int a3 : 16;
    int a4 : 3;
    int a5 : 17;
    int a6 : 25; 
} A;

void init(A* a) {
    a->a1 = 1;
    a->a2 = 321;
    a->a3 = 15;
    a->a4 = -2;
    a->a5 = -123;
    a->a6 = 1234;
}

void print(A* a) {
    printf("%d %d %d %d %d %d\n",
        a->a1,
        a->a2,
        a->a3,
        a->a4,
        a->a5,
        a->a6
    );
}

int main() {
    A a;
    init(&a);
    print(&a);
    return 0;
}

```
the output is: 
`1 321 15 -2 -123 1234`
lanza pushed a commit that referenced this issue Oct 27, 2023
Breaks ninja check-clang-cir

This reverts commit 471e568.
lanza pushed a commit that referenced this issue Oct 27, 2023
This is an updated PR for [PR
#233](#233) with some fixes
explained in [PR #261](#261) which
now can be safely closed.

First of all, let me introduce how do the bitfields looks like in CIR.
For the struct `S` defined as following:
```
typedef struct {
  int a : 4;
  int b : 27;
  int c : 17;
  int d : 2;
  int e : 15;  
  unsigned f;
} S; 
```
the CIR type is `!ty_22S22 = !cir.struct<struct "S" {!u32i, !u32i,
!u16i, !u32i} #cir.record.decl.ast>` where all the bitfields are packed
in the first three storages.
 
Also, the next bugs was fixed:
- type mismatch
- index out of bounds
- single bitfield of size < 8 

The cases covered with tests.
lanza pushed a commit that referenced this issue Dec 20, 2023
This PR introduces bitfelds support.  This now works:

```
#include <stdio.h>

typedef struct {
    int a1 : 4;
    int a2 : 28;
    int a3 : 16;
    int a4 : 3;
    int a5 : 17;
    int a6 : 25;
} A;

void init(A* a) {
    a->a1 = 1;
    a->a2 = 321;
    a->a3 = 15;
    a->a4 = -2;
    a->a5 = -123;
    a->a6 = 1234;
}

void print(A* a) {
    printf("%d %d %d %d %d %d\n",
        a->a1,
        a->a2,
        a->a3,
        a->a4,
        a->a5,
        a->a6
    );
}

int main() {
    A a;
    init(&a);
    print(&a);
    return 0;
}

```
the output is:
`1 321 15 -2 -123 1234`
lanza pushed a commit that referenced this issue Dec 20, 2023
Breaks ninja check-clang-cir

This reverts commit 471e568.
lanza pushed a commit that referenced this issue Dec 20, 2023
This is an updated PR for [PR
#233](#233) with some fixes
explained in [PR #261](#261) which
now can be safely closed.

First of all, let me introduce how do the bitfields looks like in CIR.
For the struct `S` defined as following:
```
typedef struct {
  int a : 4;
  int b : 27;
  int c : 17;
  int d : 2;
  int e : 15;  
  unsigned f;
} S; 
```
the CIR type is `!ty_22S22 = !cir.struct<struct "S" {!u32i, !u32i,
!u16i, !u32i} #cir.record.decl.ast>` where all the bitfields are packed
in the first three storages.
 
Also, the next bugs was fixed:
- type mismatch
- index out of bounds
- single bitfield of size < 8 

The cases covered with tests.
lanza pushed a commit that referenced this issue Jan 29, 2024
This PR introduces bitfelds support.  This now works:

```
#include <stdio.h>

typedef struct {
    int a1 : 4;
    int a2 : 28;
    int a3 : 16;
    int a4 : 3;
    int a5 : 17;
    int a6 : 25;
} A;

void init(A* a) {
    a->a1 = 1;
    a->a2 = 321;
    a->a3 = 15;
    a->a4 = -2;
    a->a5 = -123;
    a->a6 = 1234;
}

void print(A* a) {
    printf("%d %d %d %d %d %d\n",
        a->a1,
        a->a2,
        a->a3,
        a->a4,
        a->a5,
        a->a6
    );
}

int main() {
    A a;
    init(&a);
    print(&a);
    return 0;
}

```
the output is:
`1 321 15 -2 -123 1234`
lanza pushed a commit that referenced this issue Jan 29, 2024
Breaks ninja check-clang-cir

This reverts commit 471e568.
lanza pushed a commit that referenced this issue Jan 29, 2024
This is an updated PR for [PR
#233](#233) with some fixes
explained in [PR #261](#261) which
now can be safely closed.

First of all, let me introduce how do the bitfields looks like in CIR.
For the struct `S` defined as following:
```
typedef struct {
  int a : 4;
  int b : 27;
  int c : 17;
  int d : 2;
  int e : 15;
  unsigned f;
} S;
```
the CIR type is `!ty_22S22 = !cir.struct<struct "S" {!u32i, !u32i,
!u16i, !u32i} #cir.record.decl.ast>` where all the bitfields are packed
in the first three storages.

Also, the next bugs was fixed:
- type mismatch
- index out of bounds
- single bitfield of size < 8

The cases covered with tests.
lanza pushed a commit that referenced this issue Mar 23, 2024
This PR introduces bitfelds support.  This now works:

```
#include <stdio.h>

typedef struct {
    int a1 : 4;
    int a2 : 28;
    int a3 : 16;
    int a4 : 3;
    int a5 : 17;
    int a6 : 25;
} A;

void init(A* a) {
    a->a1 = 1;
    a->a2 = 321;
    a->a3 = 15;
    a->a4 = -2;
    a->a5 = -123;
    a->a6 = 1234;
}

void print(A* a) {
    printf("%d %d %d %d %d %d\n",
        a->a1,
        a->a2,
        a->a3,
        a->a4,
        a->a5,
        a->a6
    );
}

int main() {
    A a;
    init(&a);
    print(&a);
    return 0;
}

```
the output is:
`1 321 15 -2 -123 1234`
lanza pushed a commit that referenced this issue Mar 23, 2024
Breaks ninja check-clang-cir

This reverts commit 471e568.
lanza pushed a commit that referenced this issue Mar 23, 2024
This is an updated PR for [PR
#233](#233) with some fixes
explained in [PR #261](#261) which
now can be safely closed.

First of all, let me introduce how do the bitfields looks like in CIR.
For the struct `S` defined as following:
```
typedef struct {
  int a : 4;
  int b : 27;
  int c : 17;
  int d : 2;
  int e : 15;
  unsigned f;
} S;
```
the CIR type is `!ty_22S22 = !cir.struct<struct "S" {!u32i, !u32i,
!u16i, !u32i} #cir.record.decl.ast>` where all the bitfields are packed
in the first three storages.

Also, the next bugs was fixed:
- type mismatch
- index out of bounds
- single bitfield of size < 8

The cases covered with tests.
eZWALT pushed a commit to eZWALT/clangir that referenced this issue Mar 24, 2024
This PR introduces bitfelds support.  This now works:

```
#include <stdio.h>

typedef struct {
    int a1 : 4;
    int a2 : 28;
    int a3 : 16;
    int a4 : 3;
    int a5 : 17;
    int a6 : 25;
} A;

void init(A* a) {
    a->a1 = 1;
    a->a2 = 321;
    a->a3 = 15;
    a->a4 = -2;
    a->a5 = -123;
    a->a6 = 1234;
}

void print(A* a) {
    printf("%d %d %d %d %d %d\n",
        a->a1,
        a->a2,
        a->a3,
        a->a4,
        a->a5,
        a->a6
    );
}

int main() {
    A a;
    init(&a);
    print(&a);
    return 0;
}

```
the output is:
`1 321 15 -2 -123 1234`
eZWALT pushed a commit to eZWALT/clangir that referenced this issue Mar 24, 2024
eZWALT pushed a commit to eZWALT/clangir that referenced this issue Mar 24, 2024
…lvm#268)

This is an updated PR for [PR
llvm#233](llvm#233) with some fixes
explained in [PR llvm#261](llvm#261) which
now can be safely closed.

First of all, let me introduce how do the bitfields looks like in CIR.
For the struct `S` defined as following:
```
typedef struct {
  int a : 4;
  int b : 27;
  int c : 17;
  int d : 2;
  int e : 15;
  unsigned f;
} S;
```
the CIR type is `!ty_22S22 = !cir.struct<struct "S" {!u32i, !u32i,
!u16i, !u32i} #cir.record.decl.ast>` where all the bitfields are packed
in the first three storages.

Also, the next bugs was fixed:
- type mismatch
- index out of bounds
- single bitfield of size < 8

The cases covered with tests.
eZWALT pushed a commit to eZWALT/clangir that referenced this issue Mar 24, 2024
This PR introduces bitfelds support.  This now works:

```
#include <stdio.h>

typedef struct {
    int a1 : 4;
    int a2 : 28;
    int a3 : 16;
    int a4 : 3;
    int a5 : 17;
    int a6 : 25;
} A;

void init(A* a) {
    a->a1 = 1;
    a->a2 = 321;
    a->a3 = 15;
    a->a4 = -2;
    a->a5 = -123;
    a->a6 = 1234;
}

void print(A* a) {
    printf("%d %d %d %d %d %d\n",
        a->a1,
        a->a2,
        a->a3,
        a->a4,
        a->a5,
        a->a6
    );
}

int main() {
    A a;
    init(&a);
    print(&a);
    return 0;
}

```
the output is:
`1 321 15 -2 -123 1234`
eZWALT pushed a commit to eZWALT/clangir that referenced this issue Mar 24, 2024
eZWALT pushed a commit to eZWALT/clangir that referenced this issue Mar 24, 2024
…lvm#268)

This is an updated PR for [PR
llvm#233](llvm#233) with some fixes
explained in [PR llvm#261](llvm#261) which
now can be safely closed.

First of all, let me introduce how do the bitfields looks like in CIR.
For the struct `S` defined as following:
```
typedef struct {
  int a : 4;
  int b : 27;
  int c : 17;
  int d : 2;
  int e : 15;
  unsigned f;
} S;
```
the CIR type is `!ty_22S22 = !cir.struct<struct "S" {!u32i, !u32i,
!u16i, !u32i} #cir.record.decl.ast>` where all the bitfields are packed
in the first three storages.

Also, the next bugs was fixed:
- type mismatch
- index out of bounds
- single bitfield of size < 8

The cases covered with tests.
lanza pushed a commit that referenced this issue Apr 29, 2024
This PR introduces bitfelds support.  This now works:

```
#include <stdio.h>

typedef struct {
    int a1 : 4;
    int a2 : 28;
    int a3 : 16;
    int a4 : 3;
    int a5 : 17;
    int a6 : 25;
} A;

void init(A* a) {
    a->a1 = 1;
    a->a2 = 321;
    a->a3 = 15;
    a->a4 = -2;
    a->a5 = -123;
    a->a6 = 1234;
}

void print(A* a) {
    printf("%d %d %d %d %d %d\n",
        a->a1,
        a->a2,
        a->a3,
        a->a4,
        a->a5,
        a->a6
    );
}

int main() {
    A a;
    init(&a);
    print(&a);
    return 0;
}

```
the output is:
`1 321 15 -2 -123 1234`
lanza pushed a commit that referenced this issue Apr 29, 2024
Breaks ninja check-clang-cir

This reverts commit 471e568.
lanza pushed a commit that referenced this issue Apr 29, 2024
This is an updated PR for [PR
#233](#233) with some fixes
explained in [PR #261](#261) which
now can be safely closed.

First of all, let me introduce how do the bitfields looks like in CIR.
For the struct `S` defined as following:
```
typedef struct {
  int a : 4;
  int b : 27;
  int c : 17;
  int d : 2;
  int e : 15;
  unsigned f;
} S;
```
the CIR type is `!ty_22S22 = !cir.struct<struct "S" {!u32i, !u32i,
!u16i, !u32i} #cir.record.decl.ast>` where all the bitfields are packed
in the first three storages.

Also, the next bugs was fixed:
- type mismatch
- index out of bounds
- single bitfield of size < 8

The cases covered with tests.
lanza pushed a commit that referenced this issue Apr 29, 2024
This PR introduces bitfelds support.  This now works:

```
#include <stdio.h>

typedef struct {
    int a1 : 4;
    int a2 : 28;
    int a3 : 16;
    int a4 : 3;
    int a5 : 17;
    int a6 : 25;
} A;

void init(A* a) {
    a->a1 = 1;
    a->a2 = 321;
    a->a3 = 15;
    a->a4 = -2;
    a->a5 = -123;
    a->a6 = 1234;
}

void print(A* a) {
    printf("%d %d %d %d %d %d\n",
        a->a1,
        a->a2,
        a->a3,
        a->a4,
        a->a5,
        a->a6
    );
}

int main() {
    A a;
    init(&a);
    print(&a);
    return 0;
}

```
the output is:
`1 321 15 -2 -123 1234`
lanza pushed a commit that referenced this issue Apr 29, 2024
Breaks ninja check-clang-cir

This reverts commit 471e568.
lanza pushed a commit that referenced this issue Apr 29, 2024
This is an updated PR for [PR
#233](#233) with some fixes
explained in [PR #261](#261) which
now can be safely closed.

First of all, let me introduce how do the bitfields looks like in CIR.
For the struct `S` defined as following:
```
typedef struct {
  int a : 4;
  int b : 27;
  int c : 17;
  int d : 2;
  int e : 15;
  unsigned f;
} S;
```
the CIR type is `!ty_22S22 = !cir.struct<struct "S" {!u32i, !u32i,
!u16i, !u32i} #cir.record.decl.ast>` where all the bitfields are packed
in the first three storages.

Also, the next bugs was fixed:
- type mismatch
- index out of bounds
- single bitfield of size < 8

The cases covered with tests.
eZWALT pushed a commit to eZWALT/clangir that referenced this issue Apr 29, 2024
This PR introduces bitfelds support.  This now works:

```
#include <stdio.h>

typedef struct {
    int a1 : 4;
    int a2 : 28;
    int a3 : 16;
    int a4 : 3;
    int a5 : 17;
    int a6 : 25;
} A;

void init(A* a) {
    a->a1 = 1;
    a->a2 = 321;
    a->a3 = 15;
    a->a4 = -2;
    a->a5 = -123;
    a->a6 = 1234;
}

void print(A* a) {
    printf("%d %d %d %d %d %d\n",
        a->a1,
        a->a2,
        a->a3,
        a->a4,
        a->a5,
        a->a6
    );
}

int main() {
    A a;
    init(&a);
    print(&a);
    return 0;
}

```
the output is:
`1 321 15 -2 -123 1234`
eZWALT pushed a commit to eZWALT/clangir that referenced this issue Apr 29, 2024
eZWALT pushed a commit to eZWALT/clangir that referenced this issue Apr 29, 2024
…lvm#268)

This is an updated PR for [PR
llvm#233](llvm#233) with some fixes
explained in [PR llvm#261](llvm#261) which
now can be safely closed.

First of all, let me introduce how do the bitfields looks like in CIR.
For the struct `S` defined as following:
```
typedef struct {
  int a : 4;
  int b : 27;
  int c : 17;
  int d : 2;
  int e : 15;
  unsigned f;
} S;
```
the CIR type is `!ty_22S22 = !cir.struct<struct "S" {!u32i, !u32i,
!u16i, !u32i} #cir.record.decl.ast>` where all the bitfields are packed
in the first three storages.

Also, the next bugs was fixed:
- type mismatch
- index out of bounds
- single bitfield of size < 8

The cases covered with tests.
lanza pushed a commit that referenced this issue Apr 29, 2024
This PR introduces bitfelds support.  This now works:

```
#include <stdio.h>

typedef struct {
    int a1 : 4;
    int a2 : 28;
    int a3 : 16;
    int a4 : 3;
    int a5 : 17;
    int a6 : 25;
} A;

void init(A* a) {
    a->a1 = 1;
    a->a2 = 321;
    a->a3 = 15;
    a->a4 = -2;
    a->a5 = -123;
    a->a6 = 1234;
}

void print(A* a) {
    printf("%d %d %d %d %d %d\n",
        a->a1,
        a->a2,
        a->a3,
        a->a4,
        a->a5,
        a->a6
    );
}

int main() {
    A a;
    init(&a);
    print(&a);
    return 0;
}

```
the output is:
`1 321 15 -2 -123 1234`
lanza pushed a commit that referenced this issue Apr 29, 2024
Breaks ninja check-clang-cir

This reverts commit 471e568.
lanza pushed a commit that referenced this issue Apr 29, 2024
This is an updated PR for [PR
#233](#233) with some fixes
explained in [PR #261](#261) which
now can be safely closed.

First of all, let me introduce how do the bitfields looks like in CIR.
For the struct `S` defined as following:
```
typedef struct {
  int a : 4;
  int b : 27;
  int c : 17;
  int d : 2;
  int e : 15;
  unsigned f;
} S;
```
the CIR type is `!ty_22S22 = !cir.struct<struct "S" {!u32i, !u32i,
!u16i, !u32i} #cir.record.decl.ast>` where all the bitfields are packed
in the first three storages.

Also, the next bugs was fixed:
- type mismatch
- index out of bounds
- single bitfield of size < 8

The cases covered with tests.
bruteforceboy pushed a commit to bruteforceboy/clangir that referenced this issue Oct 2, 2024
This PR introduces bitfelds support.  This now works:

```
#include <stdio.h>

typedef struct {
    int a1 : 4;
    int a2 : 28;
    int a3 : 16;
    int a4 : 3;
    int a5 : 17;
    int a6 : 25;
} A;

void init(A* a) {
    a->a1 = 1;
    a->a2 = 321;
    a->a3 = 15;
    a->a4 = -2;
    a->a5 = -123;
    a->a6 = 1234;
}

void print(A* a) {
    printf("%d %d %d %d %d %d\n",
        a->a1,
        a->a2,
        a->a3,
        a->a4,
        a->a5,
        a->a6
    );
}

int main() {
    A a;
    init(&a);
    print(&a);
    return 0;
}

```
the output is:
`1 321 15 -2 -123 1234`
bruteforceboy pushed a commit to bruteforceboy/clangir that referenced this issue Oct 2, 2024
bruteforceboy pushed a commit to bruteforceboy/clangir that referenced this issue Oct 2, 2024
…lvm#268)

This is an updated PR for [PR
llvm#233](llvm#233) with some fixes
explained in [PR llvm#261](llvm#261) which
now can be safely closed.

First of all, let me introduce how do the bitfields looks like in CIR.
For the struct `S` defined as following:
```
typedef struct {
  int a : 4;
  int b : 27;
  int c : 17;
  int d : 2;
  int e : 15;
  unsigned f;
} S;
```
the CIR type is `!ty_22S22 = !cir.struct<struct "S" {!u32i, !u32i,
!u16i, !u32i} #cir.record.decl.ast>` where all the bitfields are packed
in the first three storages.

Also, the next bugs was fixed:
- type mismatch
- index out of bounds
- single bitfield of size < 8

The cases covered with tests.
Hugobros3 pushed a commit to shady-gang/clangir that referenced this issue Oct 2, 2024
This PR introduces bitfelds support.  This now works:

```
#include <stdio.h>

typedef struct {
    int a1 : 4;
    int a2 : 28;
    int a3 : 16;
    int a4 : 3;
    int a5 : 17;
    int a6 : 25;
} A;

void init(A* a) {
    a->a1 = 1;
    a->a2 = 321;
    a->a3 = 15;
    a->a4 = -2;
    a->a5 = -123;
    a->a6 = 1234;
}

void print(A* a) {
    printf("%d %d %d %d %d %d\n",
        a->a1,
        a->a2,
        a->a3,
        a->a4,
        a->a5,
        a->a6
    );
}

int main() {
    A a;
    init(&a);
    print(&a);
    return 0;
}

```
the output is:
`1 321 15 -2 -123 1234`
Hugobros3 pushed a commit to shady-gang/clangir that referenced this issue Oct 2, 2024
Hugobros3 pushed a commit to shady-gang/clangir that referenced this issue Oct 2, 2024
…lvm#268)

This is an updated PR for [PR
llvm#233](llvm#233) with some fixes
explained in [PR llvm#261](llvm#261) which
now can be safely closed.

First of all, let me introduce how do the bitfields looks like in CIR.
For the struct `S` defined as following:
```
typedef struct {
  int a : 4;
  int b : 27;
  int c : 17;
  int d : 2;
  int e : 15;
  unsigned f;
} S;
```
the CIR type is `!ty_22S22 = !cir.struct<struct "S" {!u32i, !u32i,
!u16i, !u32i} #cir.record.decl.ast>` where all the bitfields are packed
in the first three storages.

Also, the next bugs was fixed:
- type mismatch
- index out of bounds
- single bitfield of size < 8

The cases covered with tests.
keryell pushed a commit to keryell/clangir that referenced this issue Oct 19, 2024
This PR introduces bitfelds support.  This now works:

```
#include <stdio.h>

typedef struct {
    int a1 : 4;
    int a2 : 28;
    int a3 : 16;
    int a4 : 3;
    int a5 : 17;
    int a6 : 25;
} A;

void init(A* a) {
    a->a1 = 1;
    a->a2 = 321;
    a->a3 = 15;
    a->a4 = -2;
    a->a5 = -123;
    a->a6 = 1234;
}

void print(A* a) {
    printf("%d %d %d %d %d %d\n",
        a->a1,
        a->a2,
        a->a3,
        a->a4,
        a->a5,
        a->a6
    );
}

int main() {
    A a;
    init(&a);
    print(&a);
    return 0;
}

```
the output is:
`1 321 15 -2 -123 1234`
keryell pushed a commit to keryell/clangir that referenced this issue Oct 19, 2024
keryell pushed a commit to keryell/clangir that referenced this issue Oct 19, 2024
…lvm#268)

This is an updated PR for [PR
llvm#233](llvm#233) with some fixes
explained in [PR llvm#261](llvm#261) which
now can be safely closed.

First of all, let me introduce how do the bitfields looks like in CIR.
For the struct `S` defined as following:
```
typedef struct {
  int a : 4;
  int b : 27;
  int c : 17;
  int d : 2;
  int e : 15;
  unsigned f;
} S;
```
the CIR type is `!ty_22S22 = !cir.struct<struct "S" {!u32i, !u32i,
!u16i, !u32i} #cir.record.decl.ast>` where all the bitfields are packed
in the first three storages.

Also, the next bugs was fixed:
- type mismatch
- index out of bounds
- single bitfield of size < 8

The cases covered with tests.
lanza pushed a commit that referenced this issue Nov 5, 2024
This PR introduces bitfelds support.  This now works:

```
#include <stdio.h>

typedef struct {
    int a1 : 4;
    int a2 : 28;
    int a3 : 16;
    int a4 : 3;
    int a5 : 17;
    int a6 : 25;
} A;

void init(A* a) {
    a->a1 = 1;
    a->a2 = 321;
    a->a3 = 15;
    a->a4 = -2;
    a->a5 = -123;
    a->a6 = 1234;
}

void print(A* a) {
    printf("%d %d %d %d %d %d\n",
        a->a1,
        a->a2,
        a->a3,
        a->a4,
        a->a5,
        a->a6
    );
}

int main() {
    A a;
    init(&a);
    print(&a);
    return 0;
}

```
the output is:
`1 321 15 -2 -123 1234`
lanza pushed a commit that referenced this issue Nov 5, 2024
Breaks ninja check-clang-cir

This reverts commit 471e568.
lanza pushed a commit that referenced this issue Nov 5, 2024
This is an updated PR for [PR
#233](#233) with some fixes
explained in [PR #261](#261) which
now can be safely closed.

First of all, let me introduce how do the bitfields looks like in CIR.
For the struct `S` defined as following:
```
typedef struct {
  int a : 4;
  int b : 27;
  int c : 17;
  int d : 2;
  int e : 15;
  unsigned f;
} S;
```
the CIR type is `!ty_22S22 = !cir.struct<struct "S" {!u32i, !u32i,
!u16i, !u32i} #cir.record.decl.ast>` where all the bitfields are packed
in the first three storages.

Also, the next bugs was fixed:
- type mismatch
- index out of bounds
- single bitfield of size < 8

The cases covered with tests.
seven-mile pushed a commit to seven-mile/clangir that referenced this issue Nov 13, 2024
… depobj construct (#114221)

A codegen crash is occurring when a depend object was initialized with
omp_all_memory in the depobj directive.
llvm/llvm-project#114214
The root cause of issue looks to be the improper handling of the
dependency list when omp_all_memory was specified.

The change introduces the use of OMPTaskDataTy to manage dependencies.
The buildDependences function is called to construct the dependency
list, and the list is iterated over to emit and store the dependencies.

Reduced Test Case : 
```
#include <omp.h>

int main()

{ omp_depend_t obj; #pragma omp depobj(obj) depend(inout: omp_all_memory) }
```

```
 llvm#1 0x0000000003de6623 SignalHandler(int) Signals.cpp:0:0
 llvm#2 0x00007f8e4a6b990f (/lib64/libpthread.so.0+0x1690f)
 llvm#3 0x00007f8e4a117d2a raise (/lib64/libc.so.6+0x4ad2a)
 llvm#4 0x00007f8e4a1193e4 abort (/lib64/libc.so.6+0x4c3e4)
 llvm#5 0x00007f8e4a10fc69 __assert_fail_base (/lib64/libc.so.6+0x42c69)
 llvm#6 0x00007f8e4a10fcf1 __assert_fail (/lib64/libc.so.6+0x42cf1)
 llvm#7 0x0000000004114367 clang::CodeGen::CodeGenFunction::EmitOMPDepobjDirective(clang::OMPDepobjDirective const&) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x4114367)
 llvm#8 0x00000000040f8fac clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x40f8fac)
 llvm#9 0x00000000040ff4fb clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x40ff4fb)
llvm#10 0x00000000041847b2 clang::CodeGen::CodeGenFunction::EmitFunctionBody(clang::Stmt const*) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x41847b2)
llvm#11 0x0000000004199e4a clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x4199e4a)
llvm#12 0x00000000041f7b9d clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x41f7b9d)
llvm#13 0x00000000041f16a3 clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x41f16a3)
llvm#14 0x00000000041fd954 clang::CodeGen::CodeGenModule::EmitDeferred() (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x41fd954)
llvm#15 0x0000000004200277 clang::CodeGen::CodeGenModule::Release() (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x4200277)
llvm#16 0x00000000046b6a49 (anonymous namespace)::CodeGeneratorImpl::HandleTranslationUnit(clang::ASTContext&) ModuleBuilder.cpp:0:0
llvm#17 0x00000000046b4cb6 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x46b4cb6)
llvm#18 0x0000000006204d5c clang::ParseAST(clang::Sema&, bool, bool) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x6204d5c)
llvm#19 0x000000000496b278 clang::FrontendAction::Execute() (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x496b278)
llvm#20 0x00000000048dd074 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x48dd074)
llvm#21 0x0000000004a38092 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x4a38092)
llvm#22 0x0000000000fd4e9c cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0xfd4e9c)
llvm#23 0x0000000000fcca73 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
llvm#24 0x0000000000fd140c clang_main(int, char**, llvm::ToolContext const&) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0xfd140c)
llvm#25 0x0000000000ee2ef3 main (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0xee2ef3)
llvm#26 0x00007f8e4a10224c __libc_start_main (/lib64/libc.so.6+0x3524c)
llvm#27 0x0000000000fcaae9 _start /home/abuild/rpmbuild/BUILD/glibc-2.31/csu/../sysdeps/x86_64/start.S:120:0
clang: error: unable to execute command: Aborted
```

---------

Co-authored-by: Chandra Ghale <ghale@pe31.hpc.amslabs.hpecorp.net>
smeenai pushed a commit that referenced this issue Nov 22, 2024
…onger cause a crash (#116569)

This PR fixes a bug introduced by #110199, which causes any half float
argument to crash the compiler on MIPS64.

Currently compiling this bit of code with `llc -mtriple=mips64`: 
```
define void @half_args(half %a) nounwind {
entry:
        ret void
}
```

Crashes with the following log:
```
LLVM ERROR: unable to allocate function argument #0
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: llc -mtriple=mips64
1.	Running pass 'Function Pass Manager' on module '<stdin>'.
2.	Running pass 'MIPS DAG->DAG Pattern Instruction Selection' on function '@half_args'
 #0 0x000055a3a4013df8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/davide/Ps2/rps2-tools/prefix/bin/llc+0x32d0df8)
 #1 0x000055a3a401199e llvm::sys::RunSignalHandlers() (/home/davide/Ps2/rps2-tools/prefix/bin/llc+0x32ce99e)
 #2 0x000055a3a40144a8 SignalHandler(int) Signals.cpp:0:0
 #3 0x00007f00bde558c0 __restore_rt libc_sigaction.c:0:0
 #4 0x00007f00bdea462c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x00007f00bde55822 gsignal ./signal/../sysdeps/posix/raise.c:27:6
 #6 0x00007f00bde3e4af abort ./stdlib/abort.c:81:7
 #7 0x000055a3a3f80e3c llvm::report_fatal_error(llvm::Twine const&, bool) (/home/davide/Ps2/rps2-tools/prefix/bin/llc+0x323de3c)
 #8 0x000055a3a2e20dfa (/home/davide/Ps2/rps2-tools/prefix/bin/llc+0x20dddfa)
 #9 0x000055a3a2a34e20 llvm::MipsTargetLowering::LowerFormalArguments(llvm::SDValue, unsigned int, bool, llvm::SmallVectorImpl<llvm::ISD::InputArg> const&, llvm::SDLoc const&, llvm::SelectionDAG&, llvm::SmallVectorImpl<llvm::SDValue>&) const MipsISelLowering.cpp:0:0
#10 0x000055a3a3d896a9 llvm::SelectionDAGISel::LowerArguments(llvm::Function const&) (/home/davide/Ps2/rps2-tools/prefix/bin/llc+0x30466a9)
#11 0x000055a3a3e0b3ec llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) (/home/davide/Ps2/rps2-tools/prefix/bin/llc+0x30c83ec)
#12 0x000055a3a3e09e21 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) (/home/davide/Ps2/rps2-tools/prefix/bin/llc+0x30c6e21)
#13 0x000055a3a2aae1ca llvm::MipsDAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) MipsISelDAGToDAG.cpp:0:0
#14 0x000055a3a3e07706 llvm::SelectionDAGISelLegacy::runOnMachineFunction(llvm::MachineFunction&) (/home/davide/Ps2/rps2-tools/prefix/bin/llc+0x30c4706)
#15 0x000055a3a3051ed6 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/home/davide/Ps2/rps2-tools/prefix/bin/llc+0x230eed6)
#16 0x000055a3a35a3ec9 llvm::FPPassManager::runOnFunction(llvm::Function&) (/home/davide/Ps2/rps2-tools/prefix/bin/llc+0x2860ec9)
#17 0x000055a3a35ac3b2 llvm::FPPassManager::runOnModule(llvm::Module&) (/home/davide/Ps2/rps2-tools/prefix/bin/llc+0x28693b2)
#18 0x000055a3a35a499c llvm::legacy::PassManagerImpl::run(llvm::Module&) (/home/davide/Ps2/rps2-tools/prefix/bin/llc+0x286199c)
#19 0x000055a3a262abbb main (/home/davide/Ps2/rps2-tools/prefix/bin/llc+0x18e7bbb)
#20 0x00007f00bde3fc4c __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#21 0x00007f00bde3fd05 call_init ./csu/../csu/libc-start.c:128:20
#22 0x00007f00bde3fd05 __libc_start_main@GLIBC_2.2.5 ./csu/../csu/libc-start.c:347:5
#23 0x000055a3a2624921 _start /builddir/glibc-2.39/csu/../sysdeps/x86_64/start.S:117:0
```

This is caused by the fact that after the change, `f16`s are no longer
lowered as `f32`s in calls.

Two possible fixes are available:
- Update calling conventions to properly support passing `f16` as
integers.
- Update `useFPRegsForHalfType()` to return `true` so that `f16` are
still kept in `f32` registers, as before #110199.

This PR implements the first solution to not introduce any more ABI
changes as #110199 already did.

As of what is the correct ABI for halfs, I don't think there is a
correct answer. GCC doesn't support halfs on MIPS, and I couldn't find
any information on old MIPS ABI manuals either.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

3 participants