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!

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).

Ahh! Yes youâ€™re right, thank you 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.