Just so I understand, you are constructing a UniformQuantizedType with a signed integer type (i.e. si8) not a signless (i.e. i8)? As mentioned, the entire dialect predated the introduction of signed/unsigned types and follows the typical LLVM convention of using signless integers and maintaining the signedness separately where it is important. Given the current state of it, the right thing would likely be to require that the UQT can only be constructed with signless integers. That restriction is not implemented because they didn’t exist when it was created.
This could certainly be made more ergonomic. At this point, I would likely opt to not change the internal representation of the type (i.e. it operates on signless integers with an unsigned flag) but we could change the builder and accessors to let you use signed/unsigned types and bridge those properly. I’d rather not change the internal representation or the printed form at this point as it has fairly wide use, but we can make it better for interop with newer types.
Yes, an option is indeed to extend the API to make it work with signed/unsigned integers (builder and also getters since requesting the storage type would always return a signless integer). Keeping backward compatibility by keeping the same internals and the same behavior of the existing API looks good to me.
Something I’ve noticed also is the usage of ‘i8’ (for signed) and ‘ui8’ (for unsigned) in the dump. ‘i8’ is usually for signless integers so I think it would be more consistent to use ‘si8’ instead.
FTR - it is parsing as an MLIR i8and the type carries a flag indicating whether these should be interpreted as unsigned quantities in contexts where that is important (it mostly isn’t). This is pretty aligned with how LLVM reasons about signless integers. For convenience, when the type was created, the printer prints (i8, unsigned_bit==1) as u8 but could have also spelled this as i8 unsigned or something more explicit.
I think that “preference for signless integer conventions” in LLVM are often a source of confusion for folks coming from outside LLVM and isn’t itself a reason to go the other way.
If we’re changing the way it prints, I’d rather align it closer to the internal representation (which uses a signless type) rather than the cute i8 → u8 string munging it does now. I agree that is confusing.