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

Passing array to function using initializer syntax leads to crash #340

Open
blucia0a opened this issue Apr 30, 2023 · 0 comments
Open

Passing array to function using initializer syntax leads to crash #340

blucia0a opened this issue Apr 30, 2023 · 0 comments

Comments

@blucia0a
Copy link

This issue is about passing an array to a function using initializer syntax. If a function takes an array argument and I pass it an initializer list that I cast to an array, then cgeist crashes while trying to convert the argument to an array.

Here is a minimal example of the problem:

$ cat arraycall.c
int f(int a[], int i){
  return a[i];
}

int g(){
  return f(((int []){0,1,2}),2);
}

When I run cgeist on this program here is the output that I see (which is a crash):

$ ../mlir-build/bin/cgeist -S --function=* ./arraycall.c -o arraycall.mlir
cgeist: /home/blucia/cvsandbox/riptools/extern/Polygeist/tools/cgeist/Lib/clang-mlir.cc:1635: ValueCategory MLIRScanner::CommonArrayToPointer(mlir::Location, ValueCategory): Assertion `scalar.val' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.      Program arguments: ../mlir-build/bin/cgeist -S --function=* ./arraycall.c -o arraycall.mlir -opaque-pointers=0
1.      <eof> parser at end of file
 #0 0x00007f59d0084b94 PrintStackTraceSignalHandler(void*) Signals.cpp:0:0
 #1 0x00007f59d0082344 SignalHandler(int) Signals.cpp:0:0
 #2 0x00007f59cfac3090 (/lib/x86_64-linux-gnu/libc.so.6+0x43090)
 #3 0x00007f59cfac300b raise /build/glibc-SzIz7B/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1
 #4 0x00007f59cfaa2859 abort /build/glibc-SzIz7B/glibc-2.31/stdlib/abort.c:81:7
 #5 0x00007f59cfaa2729 get_sysdep_segment_value /build/glibc-SzIz7B/glibc-2.31/intl/loadmsgcat.c:509:8
 #6 0x00007f59cfaa2729 _nl_load_domain /build/glibc-SzIz7B/glibc-2.31/intl/loadmsgcat.c:970:34
 #7 0x00007f59cfab3fd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #8 0x0000560cf414a302 MLIRScanner::CommonArrayToPointer(mlir::Location, ValueCategory) (../mlir-build/bin/cgeist+0x3d302)
 #9 0x0000560cf4181c37 MLIRScanner::VisitCastExpr(clang::CastExpr*) (../mlir-build/bin/cgeist+0x74c37)
#10 0x0000560cf41c96ea MLIRScanner::VisitCallExpr(clang::CallExpr*) (../mlir-build/bin/cgeist+0xbc6ea)
#11 0x0000560cf41a0aaf MLIRScanner::VisitReturnStmt(clang::ReturnStmt*) (../mlir-build/bin/cgeist+0x93aaf)
#12 0x0000560cf41a0624 MLIRScanner::VisitCompoundStmt(clang::CompoundStmt*) (../mlir-build/bin/cgeist+0x93624)
#13 0x0000560cf418cc02 MLIRScanner::init(mlir::func::FuncOp, clang::FunctionDecl const*) (../mlir-build/bin/cgeist+0x7fc02)
#14 0x0000560cf418e392 MLIRASTConsumer::run() (../mlir-build/bin/cgeist+0x81392)
#15 0x00007f59cd83bb75 clang::ParseAST(clang::Sema&, bool, bool) (/home/blucia/cvsandbox/riptools/mlir-build/bin/../lib/../lib/libclangParse.so.16git+0x39b75)
#16 0x00007f59d33e1b79 clang::FrontendAction::Execute() (/home/blucia/cvsandbox/riptools/mlir-build/bin/../lib/libclangFrontend.so.16git+0x14cb79)
#17 0x0000560cf413a5d8 main (../mlir-build/bin/cgeist+0x2d5d8)
#18 0x00007f59cfaa4083 __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:342:3
#19 0x0000560cf413d61e _start (../mlir-build/bin/cgeist+0x3061e)
Aborted

Compiling with clang works:

$ ../mlir-build/bin/clang -S -emit-llvm -o arraycall.llvm arraycall.c
$

And the resulting LLVM IR seems reasonable (notice the alloca of the array at the start of g()):

$ cat arraycall.llvm
; ModuleID = 'arraycall.c'
source_filename = "arraycall.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @f(ptr noundef %a, i32 noundef %i) #0 {
entry:
  %a.addr = alloca ptr, align 8
  %i.addr = alloca i32, align 4
  store ptr %a, ptr %a.addr, align 8
  store i32 %i, ptr %i.addr, align 4
  %0 = load ptr, ptr %a.addr, align 8
  %1 = load i32, ptr %i.addr, align 4
  %idxprom = sext i32 %1 to i64
  %arrayidx = getelementptr inbounds i32, ptr %0, i64 %idxprom
  %2 = load i32, ptr %arrayidx, align 4
  ret i32 %2
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @g() #0 {
entry:
  %.compoundliteral = alloca [3 x i32], align 4
  %arrayinit.begin = getelementptr inbounds [3 x i32], ptr %.compoundliteral, i64 0, i64 0
  store i32 0, ptr %arrayinit.begin, align 4
  %arrayinit.element = getelementptr inbounds i32, ptr %arrayinit.begin, i64 1
  store i32 1, ptr %arrayinit.element, align 4
  %arrayinit.element1 = getelementptr inbounds i32, ptr %arrayinit.element, i64 1
  store i32 2, ptr %arrayinit.element1, align 4
  %arraydecay = getelementptr inbounds [3 x i32], ptr %.compoundliteral, i64 0, i64 0
  %call = call i32 @f(ptr noundef %arraydecay, i32 noundef 2)
  ret i32 %call
}

attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }

!llvm.module.flags = !{!0, !1, !2, !3, !4}
!llvm.ident = !{!5}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 2}
!4 = !{i32 7, !"frame-pointer", i32 2}
!5 = !{!"clang version 16.0.0 (https://github.com/llvm/llvm-project.git cbc378ecb87e3f31dd5aff91f2a621d500640412)"}

That code runs correctly when I compile all the way to executable using gcc and clang.

I tried commenting out the failing assertion (and the one immediately after it) to see if I could recklessly get the code to go through without crashing, but unfortunately, that didn't work and I stopped following that thread.

The expected behavior for this program would be to stack allocate (i.e., alloca) the argument array in g(), just before the call to f(), although I'm not sure what that looks like in terms of memref.

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

No branches or pull requests

1 participant