Building signed integer constants

Hello All :slight_smile:

I have an unknown integer/float Type and a signed value (I tried with both int64_t and converting to APInt):

auto type = blockArg.getType();
int64_t value = 2; 
auto i = APInt(type.getIntOrFloatBitWidth(), value, isSigned=true);

and want to create a new constant of type type with value value:

 // I have tried with both i and value and get the same result
IntegerAttr attr = rewriter.getIntegerAttr(type, i or value);
auto c = materializeConstant(rewriter, attr, type, loc)->getResult(0);

However in this case, I end up with

 %c-2_i2 = hw.constant -2 : i2

Where I expect to get value = 2

I am guessing this may come from the heighest bit of i2 (i.e. 10) being treated as the sign after value is truncated?
Not sure how to go about constructing a simple constant like this, any help would be appreciated!

Thanks in advance !!

I think the Type being i2, ie. “signless 2 bit integer”, it’s actually not defined whether the underlying binary representation 0b10 means 2 or -2

So the only problem might be how the number is represented in the textual IR, not the actual value being wrong. You would probably have to code the printer of the hw.constant op so that it always prints the number as unsigned (if your dialect only deals with unsigned numbers) or you will have to “give” the constant the signedness information by ways of typing it either as unsigned ui2 or signed si3 (or larger).

See also here: MLIR Rationale - MLIR

Ahh! Yes you’re right, thank you :slight_smile: and that section of the documentation is very helpful

I actually don’t need to print it - I was just checking for debug purposes. I guess that any comparisons / constant folding on that constant will be treated however the dialect defines those operations on unsigned values?

It would depend on how the specific Op interprets a signless integer. In the arith dialect, for example, there are some operations where signedness of operands doesn’t matter, like addition or multiplication. But for other operations, like comparisons, the information about how to interpret the signedness of operands is carried either in the Op itself (like arith.extsi / arith.extui) or in an Attribute (like arith.cmpi). And folding should also work by this principle.