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

[Bug]: Internal compiler error OPT-INF-EFS-0652 when converting to C-pointer a function with arrays passed by reference #25075

Open
lucaferranti opened this issue May 20, 2024 · 5 comments

Comments

@lucaferranti
Copy link
Contributor

lucaferranti commented May 20, 2024

Summary of Problem

Description:

Running the code below produces the error message below. I cannot get the function to be non-generic. When I had the [1..3 real(64) inlied in the proc declaration I was getting an error message that the proc is generic and cannot be captured. Factoring that out to a type variable led to the internal compiler error below.

Is this a blocking issue with no known work-arounds?

Steps to Reproduce

Source Code:

use CTypes;

type D = [1..3] real(64);

proc normalize(ref ret: D, const ref input: D): void {
  for i in 1..3 {
    ret[i] = input[i];
  }
}

var f = c_ptrTo(normalize);

Error message:

internal error: OPT-INF-EFS-0652 chpl version 2.1.0 pre-release (44b3e6b437)

Internal errors indicate a bug in the Chapel compiler,
and we're sorry for the hassle.  We would appreciate your reporting this bug --
please see https://chapel-lang.org/bugs.html for instructions.

Compile command: chpl tmp.chpl

Associated Future Test(s):

Configuration Information

  • Output of chpl --version:
❯ chpl --version
chpl version 2.1.0 pre-release (44b3e6b437)
  built with LLVM version 14.0.0
  available LLVM targets: m68k, xcore, x86-64, x86, wasm64, wasm32, ve, systemz, sparcel, sparcv9, sparc, riscv64, riscv32, ppc64le, ppc64, ppc32le, ppc32, nvptx64, nvptx, msp430, mips64el, mips64, mipsel, mips, lanai, hexagon, bpfeb, bpfel, bpf, avr, thumbeb, thumb, armeb, arm, amdgcn, r600, aarch64_32, aarch64_be, aarch64, arm64_32, arm64
Copyright 2020-2024 Hewlett Packard Enterprise Development LP
Copyright 2004-2019 Cray Inc.
(See LICENSE file for more details)
  • Output of $CHPL_HOME/util/printchplenv --anonymize:
CHPL_TARGET_PLATFORM: linux64
CHPL_TARGET_COMPILER: llvm
CHPL_TARGET_ARCH: x86_64
CHPL_TARGET_CPU: native
CHPL_LOCALE_MODEL: flat
CHPL_COMM: none
CHPL_TASKS: qthreads
CHPL_LAUNCHER: none
CHPL_TIMERS: generic
CHPL_UNWIND: none
CHPL_MEM: jemalloc
CHPL_ATOMICS: cstdlib
CHPL_GMP: bundled
CHPL_HWLOC: bundled
CHPL_RE2: bundled
CHPL_LLVM: system
CHPL_AUX_FILESYS: none
  • Back-end compiler and version, e.g. gcc --version or clang --version:
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

As a bonus question, I'd like to learn to debug those better myself. Any general pointer on what is a good workflow? How do I use read the error mesage code and extract meaningful information from it?

@lucaferranti
Copy link
Contributor Author

lucaferranti commented May 20, 2024

Porting discussion from element.

Related issue: #22238

That was using the same type trick as workaround and indeed in my code if I change the last line to

var f = normalize;

it compiles, so it seems the issue arises from the convertion to C pointer.

@lydia-duncan

This comment was marked as resolved.

@lucaferranti
Copy link
Contributor Author

lucaferranti commented May 21, 2024

I am probably just writing down what is obvious for you and saving you 5 mins top, but it looks the compiler error is

internal error: assertion error [optimizations/inferConstRefs.cpp:652]

which is the following assertion

        SymExpr* se = info->fnUses;
        info->fnUses = se->symbolSymExprsNext;

        CallExpr* call = toCallExpr(se->parentExpr);
        INT_ASSERT(call && call->isResolved());

Do I understand correctly that isResolved checks if the type is concrete and fully inferred? (which is not the case for generic procs). If that is the case, then my hand-waving guess would be:

  1. In the original case
use CTypes;

proc normalize(ref ret: [1..3] real(64), const ref input: [1..3] real(64)): void {
  for i in 1..3 {
    ret[i] = input[i];
  }
}

var f = c_ptrTo(normalize);

c_ptrTo fails because the function is generic, because the array type is not fully specified (could be distributed or not).

  1. factoring out to type D = [1..3] real(64) before the function declaration somehow exploits a loophole in the check for generic functions, which leads to the function to not be considered generic and failing an assertion later.

@mppf
Copy link
Member

mppf commented May 21, 2024

A workaround is to compile with --no-infer-const-refs. That disables the optimization that is hitting the assertion.

@lydia-duncan
Copy link
Member

lydia-duncan commented May 21, 2024

isResolved checks whether the call itself has gone through resolution. I think that's why this is an internal assertion error - we expect every function call in the code to either have been resolved by this point in compilation or to have been removed because it was not used in the program. If the compiler tried to resolve the call and failed, it should have generated an error message rather than leaving it unresolved in the AST.

Functions that are generic can still get called just fine, but we expect to have created a concrete instantiation of them for each particular call by this point in compilation

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

No branches or pull requests

4 participants