Currently, the various targets only handle arbitrary precision integers of discrete byte sizes (1, 2, 4, 8 bytes). However, the LLVM IR can now handle integer bit widths from 1 bit to 8 million bits. In cases where the integer bit size doesn't match the discrete byte size of a "known" integer, the common code generator will generate an assertion because the integer size doesn't map to something the machine recognizes. This problem needs to be fixed because: a) it prevents codegen for programs with "funny" bit sizes. b) it prevents bit-size optimizations from working. For example, a bit size minimization pass might be able to determine that an i32 value really only needs 14 bits. It would thus fit into an i16 instead of an i32. However the pass would generate i14 which would cause the common code gen to assert.
Some additional notes: 1. The <= 64bits case should be done separately from the >64 bits case. This can be done in terms of the machine's native integer instructions and can probably be done in lib/CodeGen without affecting the targets by simply adding the needed ext/trunc nodes. 2. For the > 64 bits case, a much more complicated code gen is required to handle multi-word arithmetic (e.g. look at APInt::KnuthDivide). With some help from TargetData it might be possible to write some lowering code that generates the complicated goop necessary, but its more likely that some kind of runtime support (GMP?) is needed for this. 3. Two intrinsics need to be implemented: part_set and part_select.
The code generator already has partial support for i128 as well. Supporting arbitrary width integers should be done the same way we support arbitrary width vectors: SDISel should lower to an MVT::Integer type, then legalize should turn these into specific supported widths. As usual with legalize, it can turn the operations into open-coded instructions or into libcalls. We obviously won't be able to use the GCC runtime library for the > 64 case, but that's an implementation detail. -Chris
> Supporting arbitrary width integers should be done the same way we support > arbitrary width vectors: SDISel should lower to an MVT::Integer type, then > legalize should turn these into specific supported widths. Are you saying you want a new MVT::Integer type that represents an arbitrary precision integer type? If so, where does the width of the type get stored? IIRC MVT is just an enum.
yes, that is what I'm saying. It gets stored in the operand list, and we use special opcodes, just like vectors do with VADD etc.
Dan is working on this, at least for 128-bit integers. Supporting arbitrary strange sizes is probably blocked on LegalizeDAGTypes being finished.
This is basically done, except for >64 bit constants (which is what Dan is working on). It is waiting on LegalizeTypes however. Also, there is a maximum bitwidth of 256 bits, which could easily be increased by stealing some more bits from extended vector types.
Support for >64 bit constants in codegen is done.
This is done now that LegalizeTypes has landed.