Tinygo: error: interp: branch on a non-const-propagated constant expression

Created on 6 Jul 2019  路  19Comments  路  Source: tinygo-org/tinygo

This error happened when compiling https://github.com/diamondburned/smart-contract-go/blob/master/examples/transfer-back/main.go with /tinygo build -o ./main.wasm.

With -printir: http://0x0.st/zLo5.txt

error: interp: branch on a non-constant is returned with -gc none.

Since Google suggests something about consts not being supported, I wrote some smaller code to confirm that, but couldn't.

bug next-release

Most helpful comment

1430 has been merged so this should be fixed in the next release.

All 19 comments

Output of clang --version:

clang --version
clang version 8.0.0 (tags/RELEASE_800/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /nix/store/m3h541dxlbms8zdqmw3b78pyygazwlv6-clang-8.0.0/bin

Output of llc -version:

LLVM (http://llvm.org/):
  LLVM version 8.0.0
  Optimized build.
  Default target: x86_64-unknown-linux-gnu
  Host CPU: skylake

  Registered Targets:
    aarch64    - AArch64 (little endian)
    aarch64_be - AArch64 (big endian)
    amdgcn     - AMD GCN GPUs
    arm        - ARM
    arm64      - ARM64 (little endian)
    armeb      - ARM (big endian)
    bpf        - BPF (host endian)
    bpfeb      - BPF (big endian)
    bpfel      - BPF (little endian)
    hexagon    - Hexagon
    lanai      - Lanai
    mips       - MIPS (32-bit big endian)
    mips64     - MIPS (64-bit big endian)
    mips64el   - MIPS (64-bit little endian)
    mipsel     - MIPS (32-bit little endian)
    msp430     - MSP430 [experimental]
    nvptx      - NVIDIA PTX 32-bit
    nvptx64    - NVIDIA PTX 64-bit
    ppc32      - PowerPC 32
    ppc64      - PowerPC 64
    ppc64le    - PowerPC 64 LE
    r600       - AMD GPUs HD2XXX-HD6XXX
    sparc      - Sparc
    sparcel    - Sparc LE
    sparcv9    - Sparc V9
    systemz    - SystemZ
    thumb      - Thumb
    thumbeb    - Thumb (big endian)
    wasm32     - WebAssembly 32-bit
    wasm64     - WebAssembly 64-bit
    x86        - 32-bit X86: Pentium-Pro and above
    x86-64     - 64-bit X86: EM64T and AMD64
    xcore      - XCore

Output of tinygo version:

tinygo version 0.7.0-dev linux/amd64

If it helps:

{ pkgs ? import <nixpkgs> {} }:

let
  unstable = import <unstable> {};
in pkgs.stdenv.mkDerivation rec {
    name = "perlin";

    buildInputs = with unstable; [
        cquery emscripten wabt llvm-polly lld_8
        llvmPackages.clang-unwrapped clang-polly
    ];
}

P/S: My code has no go: grep 'go ' **.go returns nothing.

Thank you for reporting! This is a bug in the interp package and I know roughly what to look for.

Unfortunately, I can't access the gitlab.com/diamondburned/smart-contract-go package. Assuming it can't be made public, can you share a reduced test case? The issue lies in the initialization code of the package or one of its dependencies, so you can test in which package it lies simply by importing it.

Also, is there a reason why you pass -gc=dumb?

I made a mistake, it was github. I just passed in -gc=dumb to test it.

P/S: Pushed a commit to fix it.

Are there any updates on this?

Hi @diamondburned you might want to try the current dev branch of TinyGo as it probably addresses this issue.

As of TinyGo v0.8.0 several packages including encoding/base64 still cannot be imported due to this error, so this is still not fixed.

FYI importing crypto/rand also causes error: interp: branch on a non-constant on the latest tinygo-dev.

Apparently it's a problem with runtime.isnil, a trick to work around an important missed optimization in LLVM 8 (in short, nil pointer checking would almost entirely break escape analysis). This is now unnecessary: a fix for this has been merged in LLVM 9. So I hope that once we change to the right way of doing it (plain icmp and special function attributes that are valid in Go), this bug will be fixed at the same time.

This should now be corrected in the dev branch, since we are using LLVM 9.

No. LLVM 9 has a new optimization that allows us to avoid the runtime.isnil workaround. But implementing this takes more than just switching to LLVM 9, unfortunately.

Any plan regarding this issue?

I'm trying to translate this function from C/GCC to TinyGo, as part of #863. I get this error when I use arm.AsmFull and the mrs instruction:

AsmFull("mrs {dest}, faultmask", map[string]interface{}{"dest": &faultmask})
if faultmask != 0 {
    return -1
}

I am actually using crypto/rand in my project and just ran into this problem. I am using tinygo version 0.14.1 darwin/amd64 (using go version go1.13.4 and LLVM version 10.0.1). Any recommended work arounds?

Maybe just manually open /dev/urandom instead?

See https://github.com/tinygo-org/tinygo/pull/1430 for a PR that tries to solve this (but isn't ready yet).

1430 has been merged so this should be fixed in the next release.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

torntrousers picture torntrousers  路  8Comments

mcrosson picture mcrosson  路  3Comments

prologic picture prologic  路  8Comments

bradleypeabody picture bradleypeabody  路  6Comments

bradleypeabody picture bradleypeabody  路  7Comments