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

Compile failed maybe related to defer #802

Open
cpunion opened this issue Sep 21, 2024 · 0 comments
Open

Compile failed maybe related to defer #802

cpunion opened this issue Sep 21, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@cpunion
Copy link
Contributor

cpunion commented Sep 21, 2024

Description

Current behavior

Consider the following Go code:

var envs = []int{}

func Test() int {
	defer print(1)
	a := 1
	for _, env := range envs {
		if env != 1 {
			a = a + 1
		}
	}
	return a
}

This generates LLVM IR: (WRONG SAMPLE)

define i64 @main.Test() {
_llgo_0:
  %0 = load i32, ptr @__llgo_defer, align 4
  %1 = call ptr @pthread_getspecific(i32 %0)
  %2 = alloca i8, i64 196, align 1
  %3 = alloca i8, i64 40, align 1
  %4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %3, i32 0, i32 0
  store ptr %2, ptr %4, align 8
  %5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %3, i32 0, i32 1
  store i64 0, ptr %5, align 4
  %6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %3, i32 0, i32 2
  store ptr %1, ptr %6, align 8
  %7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %3, i32 0, i32 3
  store ptr blockaddress(@main.Test, %_llgo_6), ptr %7, align 8
  %8 = call i32 @pthread_setspecific(i32 %0, ptr %3)
  %9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %3, i32 0, i32 1
  %10 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %3, i32 0, i32 3
  %11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %3, i32 0, i32 4
  %12 = call i32 @sigsetjmp(ptr %2, i32 0)
  %13 = icmp eq i32 %12, 0
  br i1 %13, label %_llgo_8, label %_llgo_9

_llgo_1:                                          ; preds = %_llgo_7
  ret i64 0

_llgo_2:                                          ; preds = %_llgo_5, %_llgo_3, %_llgo_8
  %14 = phi i64 [ 1, %_llgo_8 ], [ %14, %_llgo_3 ], [ %26, %_llgo_5 ]
  %15 = phi i64 [ -1, %_llgo_8 ], [ %16, %_llgo_3 ], [ %16, %_llgo_5 ]
  %16 = add i64 %15, 1
  %17 = icmp slt i64 %16, %33
  br i1 %17, label %_llgo_3, label %_llgo_4

_llgo_3:                                          ; preds = %_llgo_2
  %18 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %32, 0
  %19 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %32, 1
  %20 = icmp slt i64 %16, 0
  %21 = icmp sge i64 %16, %19
  %22 = or i1 %21, %20
  call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %22)
  %23 = getelementptr inbounds i64, ptr %18, i64 %16
  %24 = load i64, ptr %23, align 4
  %25 = icmp ne i64 %24, 1
  br i1 %25, label %_llgo_5, label %_llgo_2

_llgo_4:                                          ; preds = %_llgo_2
  store ptr blockaddress(@main.Test, %_llgo_10), ptr %11, align 8
  br label %_llgo_6

_llgo_5:                                          ; preds = %_llgo_3
  %26 = add i64 %14, 1
  br label %_llgo_2

_llgo_6:                                          ; preds = %_llgo_9, %_llgo_4
  store ptr blockaddress(@main.Test, %_llgo_7), ptr %10, align 8
  %27 = load i64, ptr %9, align 4
  call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 1)
  %28 = load %"github.com/goplus/llgo/internal/runtime.Defer", ptr %3, align 8
  %29 = extractvalue %"github.com/goplus/llgo/internal/runtime.Defer" %28, 2
  %30 = call i32 @pthread_setspecific(i32 %0, ptr %29)
  %31 = load ptr, ptr %11, align 8
  indirectbr ptr %31, [label %_llgo_7, label %_llgo_10]

_llgo_7:                                          ; preds = %_llgo_9, %_llgo_6
  call void @"github.com/goplus/llgo/internal/runtime.Rethrow"(ptr %1)
  br label %_llgo_1

_llgo_8:                                          ; preds = %_llgo_0
  %32 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr @main.envs, align 8
  %33 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %32, 1
  br label %_llgo_2

_llgo_9:                                          ; preds = %_llgo_0
  store ptr blockaddress(@main.Test, %_llgo_7), ptr %11, align 8
  %34 = load ptr, ptr %10, align 8
  indirectbr ptr %34, [label %_llgo_7, label %_llgo_6]

_llgo_10:                                         ; preds = %_llgo_6
  ret i64 %14
}

Compile it with llc:

$ /opt/homebrew/bin/llc llgo_autogen.ll
Instruction does not dominate all uses!
  %14 = phi i64 [ 1, %_llgo_8 ], [ %14, %_llgo_3 ], [ %26, %_llgo_5 ]
  ret i64 %14

But it can be compiled by clang:

/opt/homebrew/bin/clang -c llgo_autogen.ll
warning: overriding the module target triple with arm64-apple-macosx14.0.0 [-Woverride-module]
1 warning generated.

When generate code with debug info, the code almost same except debug info:

define i64 @main.Test() !dbg !22 {
_llgo_0:
  %0 = load i32, ptr @__llgo_defer, align 4, !dbg !25
  %1 = call ptr @pthread_getspecific(i32 %0), !dbg !25
  %2 = alloca i8, i64 196, align 1, !dbg !25
  %3 = alloca i8, i64 40, align 1, !dbg !25
  %4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %3, i32 0, i32 0, !dbg !25
  store ptr %2, ptr %4, align 8, !dbg !25
  %5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %3, i32 0, i32 1, !dbg !25
  store i64 0, ptr %5, align 4, !dbg !25
  %6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %3, i32 0, i32 2, !dbg !25
  store ptr %1, ptr %6, align 8, !dbg !25
  %7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %3, i32 0, i32 3, !dbg !25
  store ptr blockaddress(@main.Test, %_llgo_6), ptr %7, align 8, !dbg !25
  %8 = call i32 @pthread_setspecific(i32 %0, ptr %3), !dbg !25
  %9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %3, i32 0, i32 1, !dbg !25
  %10 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %3, i32 0, i32 3, !dbg !25
  %11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %3, i32 0, i32 4, !dbg !25
  %12 = call i32 @sigsetjmp(ptr %2, i32 0), !dbg !25
  %13 = icmp eq i32 %12, 0, !dbg !25
  br i1 %13, label %_llgo_8, label %_llgo_9, !dbg !25

_llgo_1:                                          ; preds = %_llgo_7
  ret i64 0, !dbg !26

_llgo_2:                                          ; preds = %_llgo_5, %_llgo_3, %_llgo_8
  %14 = phi i64 [ 1, %_llgo_8 ], [ %14, %_llgo_3 ], [ %26, %_llgo_5 ], !dbg !25
  %15 = phi i64 [ -1, %_llgo_8 ], [ %16, %_llgo_3 ], [ %16, %_llgo_5 ], !dbg !25
  %16 = add i64 %15, 1, !dbg !26
  %17 = icmp slt i64 %16, %33, !dbg !26
  br i1 %17, label %_llgo_3, label %_llgo_4, !dbg !26

_llgo_3:                                          ; preds = %_llgo_2
  %18 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %32, 0, !dbg !27
  %19 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %32, 1, !dbg !27
  %20 = icmp slt i64 %16, 0, !dbg !27
  %21 = icmp sge i64 %16, %19, !dbg !27
  %22 = or i1 %21, %20, !dbg !27
  call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %22), !dbg !27
  %23 = getelementptr inbounds i64, ptr %18, i64 %16, !dbg !27
  %24 = load i64, ptr %23, align 4, !dbg !26
  call void @llvm.dbg.value(metadata i64 %24, metadata !28, metadata !DIExpression()), !dbg !29
  call void @llvm.dbg.value(metadata i64 %24, metadata !28, metadata !DIExpression()), !dbg !30
  %25 = icmp ne i64 %24, 1, !dbg !31
  br i1 %25, label %_llgo_5, label %_llgo_2, !dbg !31

_llgo_4:                                          ; preds = %_llgo_2
  call void @llvm.dbg.value(metadata i64 %14, metadata !32, metadata !DIExpression()), !dbg !33
  store ptr blockaddress(@main.Test, %_llgo_10), ptr %11, align 8, !dbg !34
  br label %_llgo_6, !dbg !34

_llgo_5:                                          ; preds = %_llgo_3
  call void @llvm.dbg.value(metadata i64 %14, metadata !32, metadata !DIExpression()), !dbg !35
  %26 = add i64 %14, 1, !dbg !34
  call void @llvm.dbg.value(metadata i64 %26, metadata !32, metadata !DIExpression()), !dbg !36
  br label %_llgo_2, !dbg !34

_llgo_6:                                          ; preds = %_llgo_9, %_llgo_4
  store ptr blockaddress(@main.Test, %_llgo_7), ptr %10, align 8, !dbg !34
  %27 = load i64, ptr %9, align 4, !dbg !34
  call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 1), !dbg !34
  %28 = load %"github.com/goplus/llgo/internal/runtime.Defer", ptr %3, align 8, !dbg !34
  %29 = extractvalue %"github.com/goplus/llgo/internal/runtime.Defer" %28, 2, !dbg !34
  %30 = call i32 @pthread_setspecific(i32 %0, ptr %29), !dbg !34
  %31 = load ptr, ptr %11, align 8, !dbg !34
  indirectbr ptr %31, [label %_llgo_7, label %_llgo_10], !dbg !34

_llgo_7:                                          ; preds = %_llgo_9, %_llgo_6
  call void @"github.com/goplus/llgo/internal/runtime.Rethrow"(ptr %1), !dbg !25
  br label %_llgo_1, !dbg !25

_llgo_8:                                          ; preds = %_llgo_0
  call void @llvm.dbg.value(metadata i64 1, metadata !32, metadata !DIExpression()), !dbg !37
  %32 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr @main.envs, align 8, !dbg !27
  call void @llvm.dbg.value(metadata %"github.com/goplus/llgo/internal/runtime.Slice" %32, metadata !38, metadata !DIExpression()), !dbg !27
  %33 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %32, 1, !dbg !26
  br label %_llgo_2, !dbg !26

_llgo_9:                                          ; preds = %_llgo_0
  store ptr blockaddress(@main.Test, %_llgo_7), ptr %11, align 8, !dbg !34
  %34 = load ptr, ptr %10, align 8, !dbg !34
  indirectbr ptr %34, [label %_llgo_7, label %_llgo_6], !dbg !34

_llgo_10:                                         ; preds = %_llgo_6
  ret i64 %14, !dbg !34
}

When remove the debug tokens and lines, it is no difference between them.

Compile it with llc:

$ /opt/homebrew/bin/llc llgo_autogen.ll
Instruction does not dominate all uses!
  %14 = phi i64 [ 1, %_llgo_8 ], [ %14, %_llgo_3 ], [ %26, %_llgo_5 ], !dbg !25
  ret i64 %14, !dbg !34
LLVM ERROR: Broken module found, compilation aborted!
PLEASE submit a bug report to https://github.com/Homebrew/homebrew-core/issues and include the crash backtrace.
Stack dump:
0.	Program arguments: /opt/homebrew/bin/llc llgo_autogen.ll
 #0 0x0000000111fe1d60 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x4695d60)
 #1 0x0000000111fe2134 SignalHandler(int) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x4696134)
 #2 0x00000001805f7584 (/usr/lib/system/libsystem_platform.dylib+0x180477584)
 #3 0x00000001805c6c20 (/usr/lib/system/libsystem_pthread.dylib+0x180446c20)
 #4 0x00000001804d3a20 (/usr/lib/system/libsystem_c.dylib+0x180353a20)
 #5 0x000000010d9e7da0 llvm::report_fatal_error(llvm::Twine const&, bool) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x9bda0)
 #6 0x0000000111fd4870 llvm::report_fatal_error(llvm::StringRef, bool) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x4688870)
 #7 0x000000010db08d10 llvm::UpgradeDebugInfo(llvm::Module&) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x1bcd10)
 #8 0x00000001119addd4 llvm::LLParser::validateEndOfModule(bool) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x4061dd4)
 #9 0x00000001119ac984 llvm::LLParser::Run(bool, llvm::function_ref<std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>> (llvm::StringRef, llvm::StringRef)>) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x4060984)
#10 0x00000001119e7e90 parseAssemblyInto(llvm::MemoryBufferRef, llvm::Module*, llvm::ModuleSummaryIndex*, llvm::SMDiagnostic&, llvm::SlotMapping*, bool, llvm::function_ref<std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>> (llvm::StringRef, llvm::StringRef)>) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x409be90)
#11 0x00000001119e8138 llvm::parseAssembly(llvm::MemoryBufferRef, llvm::SMDiagnostic&, llvm::LLVMContext&, llvm::SlotMapping*, llvm::function_ref<std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>> (llvm::StringRef, llvm::StringRef)>) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x409c138)
#12 0x000000010dd877e8 llvm::parseIR(llvm::MemoryBufferRef, llvm::SMDiagnostic&, llvm::LLVMContext&, llvm::ParserCallbacks) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x43b7e8)
#13 0x000000010dd881e0 llvm::parseIRFile(llvm::StringRef, llvm::SMDiagnostic&, llvm::LLVMContext&, llvm::ParserCallbacks) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x43c1e0)
#14 0x00000001048b9428 compileModule(char**, llvm::LLVMContext&) (/opt/homebrew/Cellar/llvm/18.1.8/bin/llc+0x100005428)
#15 0x00000001048b84a8 main (/opt/homebrew/Cellar/llvm/18.1.8/bin/llc+0x1000044a8)
#16 0x000000018023e0e0
[1]    77142 abort      /opt/homebrew/bin/llc llgo_autogen.ll

Compile it with clang:

$ /opt/homebrew/bin/clang -c llgo_autogen.ll
Instruction does not dominate all uses!
  %14 = phi i64 [ 1, %_llgo_8 ], [ %14, %_llgo_3 ], [ %26, %_llgo_5 ], !dbg !25
  ret i64 %14, !dbg !34
fatal error: error in backend: Broken module found, compilation aborted!
PLEASE submit a bug report to https://github.com/Homebrew/homebrew-core/issues and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: /opt/homebrew/bin/clang -c llgo_autogen.ll
 #0 0x000000011aeb9d60 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x4695d60)
 #1 0x0000000116979560 llvm::sys::CleanupOnSignal(unsigned long) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x155560)
 #2 0x000000011aeab718 (anonymous namespace)::CrashRecoveryContextImpl::HandleCrash(int, unsigned long) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x4687718)
 #3 0x000000011aeab6c8 llvm::CrashRecoveryContext::HandleExit(int) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x46876c8)
 #4 0x000000011aeb95b4 llvm::sys::Process::Exit(int, bool) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x46955b4)
 #5 0x0000000104323b8c LLVMErrorHandler(void*, char const*, bool) (/opt/homebrew/Cellar/llvm/18.1.8/bin/clang-18+0x100007b8c)
 #6 0x00000001168bfd74 llvm::report_fatal_error(llvm::Twine const&, bool) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x9bd74)
 #7 0x000000011aeac870 llvm::report_fatal_error(llvm::StringRef, bool) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x4688870)
 #8 0x00000001169e0d10 llvm::UpgradeDebugInfo(llvm::Module&) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x1bcd10)
 #9 0x000000011a885dd4 llvm::LLParser::validateEndOfModule(bool) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x4061dd4)
#10 0x000000011a884984 llvm::LLParser::Run(bool, llvm::function_ref<std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>> (llvm::StringRef, llvm::StringRef)>) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x4060984)
#11 0x000000011a8bfe90 parseAssemblyInto(llvm::MemoryBufferRef, llvm::Module*, llvm::ModuleSummaryIndex*, llvm::SMDiagnostic&, llvm::SlotMapping*, bool, llvm::function_ref<std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>> (llvm::StringRef, llvm::StringRef)>) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x409be90)
#12 0x000000011a8c0138 llvm::parseAssembly(llvm::MemoryBufferRef, llvm::SMDiagnostic&, llvm::LLVMContext&, llvm::SlotMapping*, llvm::function_ref<std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>> (llvm::StringRef, llvm::StringRef)>) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x409c138)
#13 0x0000000116c5f7e8 llvm::parseIR(llvm::MemoryBufferRef, llvm::SMDiagnostic&, llvm::LLVMContext&, llvm::ParserCallbacks) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x43b7e8)
#14 0x000000010ab07730 clang::CodeGenAction::loadModule(llvm::MemoryBufferRef) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libclang-cpp.dylib+0x193f730)
#15 0x000000010ab08774 clang::CodeGenAction::ExecuteAction() (/opt/homebrew/Cellar/llvm/18.1.8/lib/libclang-cpp.dylib+0x1940774)
#16 0x000000010b264dd4 clang::FrontendAction::Execute() (/opt/homebrew/Cellar/llvm/18.1.8/lib/libclang-cpp.dylib+0x209cdd4)
#17 0x000000010b1e7ad4 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libclang-cpp.dylib+0x201fad4)
#18 0x000000010b2b7c28 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libclang-cpp.dylib+0x20efc28)
#19 0x0000000104322b28 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/homebrew/Cellar/llvm/18.1.8/bin/clang-18+0x100006b28)
#20 0x0000000104321218 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) (/opt/homebrew/Cellar/llvm/18.1.8/bin/clang-18+0x100005218)
#21 0x000000010ae65d28 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::__1::optional<llvm::StringRef>>, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>*, bool*) const::$_0>(long) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libclang-cpp.dylib+0x1c9dd28)
#22 0x00000001168b0b48 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x8cb48)
#23 0x000000010ae65524 clang::driver::CC1Command::Execute(llvm::ArrayRef<std::__1::optional<llvm::StringRef>>, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>*, bool*) const (/opt/homebrew/Cellar/llvm/18.1.8/lib/libclang-cpp.dylib+0x1c9d524)
#24 0x000000010ae26190 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/homebrew/Cellar/llvm/18.1.8/lib/libclang-cpp.dylib+0x1c5e190)
#25 0x000000010ae46e00 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::__1::pair<int, clang::driver::Command const*>>&) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libclang-cpp.dylib+0x1c7ee00)
#26 0x000000010431fd44 clang_main(int, char**, llvm::ToolContext const&) (/opt/homebrew/Cellar/llvm/18.1.8/bin/clang-18+0x100003d44)
#27 0x000000010432ce38 main (/opt/homebrew/Cellar/llvm/18.1.8/bin/clang-18+0x100010e38)
#28 0x000000018023e0e0
clang: error: clang frontend command failed with exit code 70 (use -v to see invocation)
Homebrew clang version 18.1.8
Target: arm64-apple-darwin23.4.0
Thread model: posix
InstalledDir: /opt/homebrew/bin
clang: note: diagnostic msg: Error generating preprocessed source(s) - no preprocessable inputs.

When remove the defer statement, it compile passed. The code generated:

define i64 @main.Test() !dbg !22 {
_llgo_0:
  call void @llvm.dbg.value(metadata i64 1, metadata !25, metadata !DIExpression()), !dbg !26
  %0 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr @main.envs, align 8, !dbg !27
  call void @llvm.dbg.value(metadata %"github.com/goplus/llgo/internal/runtime.Slice" %0, metadata !28, metadata !DIExpression()), !dbg !27
  %1 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1, !dbg !29
  br label %_llgo_1, !dbg !29

_llgo_1:                                          ; preds = %_llgo_4, %_llgo_2, %_llgo_0
  %2 = phi i64 [ 1, %_llgo_0 ], [ %2, %_llgo_2 ], [ %14, %_llgo_4 ], !dbg !30
  %3 = phi i64 [ -1, %_llgo_0 ], [ %4, %_llgo_2 ], [ %4, %_llgo_4 ], !dbg !30
  %4 = add i64 %3, 1, !dbg !29
  %5 = icmp slt i64 %4, %1, !dbg !29
  br i1 %5, label %_llgo_2, label %_llgo_3, !dbg !29

_llgo_2:                                          ; preds = %_llgo_1
  %6 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0, !dbg !27
  %7 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1, !dbg !27
  %8 = icmp slt i64 %4, 0, !dbg !27
  %9 = icmp sge i64 %4, %7, !dbg !27
  %10 = or i1 %9, %8, !dbg !27
  call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %10), !dbg !27
  %11 = getelementptr inbounds i64, ptr %6, i64 %4, !dbg !27
  %12 = load i64, ptr %11, align 4, !dbg !29
  call void @llvm.dbg.value(metadata i64 %12, metadata !31, metadata !DIExpression()), !dbg !32
  call void @llvm.dbg.value(metadata i64 %12, metadata !31, metadata !DIExpression()), !dbg !33
  %13 = icmp ne i64 %12, 1, !dbg !34
  br i1 %13, label %_llgo_4, label %_llgo_1, !dbg !34

_llgo_3:                                          ; preds = %_llgo_1
  call void @llvm.dbg.value(metadata i64 %2, metadata !25, metadata !DIExpression()), !dbg !35
  ret i64 %2, !dbg !36

_llgo_4:                                          ; preds = %_llgo_2
  call void @llvm.dbg.value(metadata i64 %2, metadata !25, metadata !DIExpression()), !dbg !37
  %14 = add i64 %2, 1, !dbg !36
  call void @llvm.dbg.value(metadata i64 %14, metadata !25, metadata !DIExpression()), !dbg !38
  br label %_llgo_1, !dbg !36
}

The flow graph of code block WRONG SAMPLE

image

There was a wrong path from _llgo_0 to _llgo_10 that didn't through _llgo_2, and the return value is allocated in _llgo_2. Maybe it's jumping correctly by the blockaddress, but it can't pass the compiling.

It led to this issue: https://github.com/goplus/llgo/actions/runs/10971740620/job/30467224448?pr=794

Below is the right path, the _llgo_1 (same as _llgo_2 in the defer version) is always executed.

image
@xushiwei xushiwei added the bug Something isn't working label Sep 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants