Assertions and assumptions

I find myself considering to use

@inline function __unreachable()
   Base.llvmcall("unreachable", Void, Tuple{}, Tuple());
end

@inline function assume(x::Bool)
    x || __unreachable();
end

This yields the nice

function foo(x)
    assume(x> 0)
    x>0 ? x: -x
end

@code_llvm foo(2.4)

define double @julia_foo_63669(double) #0 !dbg !5 {
top:
  ret double %0
}

Would this be a workaround for https://github.com/JuliaLang/julia/issues/269?

That is, use the dreaded any for the data-layout and use assume instead of type-asserts in order to get static dispatch to the right method, without the branch?

Of course one would maybe like some macro-magic in order to turn assumes into asserts unless some command-line switch is provided; also Iā€™m not sure whether one can force llvm to not actually emit code evaluating the conditional if it contains non-inlined function calls; in such cases, the assume should rather be eliminated.

A truly evil person might consider changing all asserts into assumes when running with --optimize, a la https://github.com/JuliaLang/julia/issues/7732.

What do you think? Does an assume belong into base in order to tell the compiler about invariants you know?

1 Like