Stefan,
Got it -- thanks. This is very helpful and actually it seems quite obvious
that I was misunderstanding how the intrinsics work.
The intended algorithm (for which this was the simplest condensed example
that produced the segfault) constructs and manipulates values whose types
belong to a finite set and can have various lengths that depend on the
input itself, even though input and outputs to the algorithm alway have the
same type. To implement this efficiently I've used @nif from Cartesian, but
in essence it seems it's not just a matter of efficiency: for the code to
be correct, I need to ensure the variable names and types are varying along
each conditional in a way such that the use of intrinsics is valid
regardless of the runtime branch.
As far as the LLVM support for nonstandard integer sizes goes, yes I've
found that is a little bit of a thicket. So far I've found that addition
and valid nonzero logical shifts work, but multiplication and shufflevector
are broken for such types, in quite serious ways that lead to nonsense
results. The issues with multiplication are known but when I get around to
it I mean to submit a bug report for shufflevector. However, I think most
of the problems I've had with Julia are actually related to the
misunderstanding mentioned above.
Thanks very much again,
Bryce
On Thursday, May 28, 2015 at 12:51:44 PM UTC-4, Stefan Karpinski wrote:
>
> 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]
> <javascript:>> 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
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>