Even though the else clause doesn't run, the code generation for it does –
that's what's throwing the error here. When you use intrinsics, you're not
really operating on values, you're telling the code generator what code to
emit. In this case, you're telling it to emit invalid code for the second
branch – truncating a UInt64 to UInt144, which is, of course, impossible.
You can get the effect you want by conditionally defining the zero method:

if sizeof(UInt144) > sizeof(UInt64)
    zero_B(::Type{UInt144}) =
box(UInt144,zext_int(UInt144,unbox(UInt64,zero(UInt64))))
else
    zero_B(::Type{UInt144}) =
box(UInt144,trunc_int(UInt144,unbox(UInt64,zero(UInt64))))
end

I should warn you that while Julia supports custom bits types with
"strange" sizes like 144, you are fairly likely to encounter code
generation problems with LLVM here and there. We still have a fair number
of workarounds for such bugs for 128-bit integer types. That said, it's a
good exercise and we should submit upstream bug reports with LLVM to fix
such issues.

On Wed, May 27, 2015 at 7:28 PM, Bryce Corrigan <[email protected]>
wrote:

> Hi all,
>
> I wonder if anyone can spot an obvious problem with the function zero_B
> below, which produces a segfault, whereas zero_A does not.
>
> I understand that in many instances this task of converting to a bitstype
> is more safety completed with high-level Julia functionality like
> reinterpret or immutable wrappers. However, I'm working on a library that
> works directly with data byte-fields. With this kind of coding it seems
> inevitable that one runs into bugs (like the recent LLVM shift bug), but
> here I was unable either to figure out my coding mistake or to find any
> recent bug-reports matching this pattern.
>
> Thanks in advance for any clues...!
> Bryce
>
>
>
>
> import Base.Intrinsics: box, unbox, zext_int, trunc_int
>
> bitstype 144 UInt144
>
> function zero_A(::Type{UInt144})
>
>  box(UInt144,zext_int(UInt144,unbox(UInt64,zero(UInt64))))
>
> end
>
>
> function zero_B(::Type{UInt144})
>
>  if sizeof(UInt144) > sizeof(UInt64)
>
>    box(UInt144,zext_int(UInt144,unbox(UInt64,zero(UInt64))))
>
>  else
>
>    box(UInt144,trunc_int(UInt144,unbox(UInt64,zero(UInt64))))
>
>  end
>
> end
>
>
>
> julia> zero_A(UInt144)
> UInt144(0x000000000000000000000000000000000000)
>
> julia> zero_B(UInt144)
>
> Assertion failed: (castIsValid(op, S, Ty) && "Invalid cast!"), function
> Create, file Instructions.cpp, line 2290.
>
> signal (6): Abort trap: 6
>
> __pthread_kill at /usr/lib/system/libsystem_kernel.dylib (unknown line)
>
>
> Abort trap: 6
>
>
>
>
>
>
>
>
>
>
>
>

Reply via email to