[llvm-dev] Unsigned int displaying as negative

Ryan Taylor via llvm-dev llvm-dev at lists.llvm.org
Wed Feb 15 11:37:57 PST 2017

I see. If I put simm16 and immSExt16x in place of uimm16 and immZExt16x
respectively, the imm matches but it prints out -32768 (which is invalid
for sub16u). We are using uimm16 not match unsigned but for PrintMethod,
effectively uimm16 and simm16 are both Operand<i16>. I'm still unclear why
simm16 matches and uimm16 does not. Here is the pattern if that helps at

So just as a reference:

def simm16      : Operand<i16> {
  let DecoderMethod= "DecodeSimm16";
  let OperandType = "OPERAND_IMMEDIATE";

def uimm16      : Operand<i16> {
  let PrintMethod = "printUnsignedImm";
  let OperandType = "OPERAND_IMMEDIATE";

def immSExt16x : ImmLeaf<i16, [{ return isInt<16>(Imm); }]>;
def immZExt16x : ImmLeaf<i16, [{ return isUInt<16>(Imm); }]>;

defm SUB16u_  : ABD_NonCommutative<"sub16u", unsignedSub, LOADRegs,
GPRRegs, DSTRegs, i16, i16, i16, simm16, immZExt16x>;

multiclass ABD_NonCommutative<string asmstr, SDPatternOperator OpNode,
RegisterClass srcAReg, RegisterClass srcBReg,
               RegisterClass dstReg, ValueType srcAType, ValueType
srcBType, ValueType dstType,
               Operand ImmOd, ImmLeaf imm_type>
     def IMM_MEM_MEM      : SetABDIn<asmstr, ImmOd, memhx, memhx,
                                [(directStore (dstType (OpNode
imm_type:$srcA, (srcBType (load addr16:$srcB)))), addr16:$dstD)]>;

class SetABDIn<string asmstr, DAGOperand srcA, DAGOperand srcB, DAGOperand
dstD, list<dag> pattern>
            : A_B_D<(outs), (ins srcA:$srcA, srcB:$srcB, dstD:$dstD),
            !strconcat(asmstr, "\t$srcA, $srcB, $dstD"), pattern, IIAlu>
    let mayStore = 1;
    let mayLoad = 1;

On Wed, Feb 15, 2017 at 2:24 PM, Manuel Jacob <me at manueljacob.de> wrote:

> On 2017-02-15 19:54, Ryan Taylor wrote:
>> Thanks for your reply.
>> We are propagating sign info to tablegen currently using
>> BinaryWithFlagsSDNode.Flags.hasNoSignedWrap atm.
> Note that this flag doesn't indicate signedness of the operation.  It just
> means that the optimizer or code generator can assume that no signed
> overflow will happen during the operation.  To get a better understanding
> of why this flag is not suitable for reconstructing the signedness of an
> operation (which is actually inherently signedness-agnostic), imagine an
> instruction that has both the NoSignedWrap and NoUnsignedWrap flags set.
> What would be the "signedness" of this instruction?  This question doesn't
> have an answer, because adds don't have "signedness" when using two's
> complement.
> I imagine (I have not looked) they are printed according to instruction in
>> AsmPrinter.cpp (pure speculation).
> I'm not quite sure what you're referring to.
> I'm still confused as to why 0x7FFF is ok to match 16 bit int but not
>> 0x8000?
> I can't answer this question without knowing how your patterns look like
> exactly, but possibly this happens specifically because you try to
> propagate sign info (which doesn't really work, as explained above).
> Thanks.
>> On Wed, Feb 15, 2017 at 1:44 PM, Manuel Jacob <me at manueljacob.de> wrote:
>> Hi Ryan,
>>> It is important to get clear about that LLVM IR integers (and operations
>>> if they don't have to) have no sign.  But IR integers have to be printed
>>> somehow and it was decided to print them as being signed.
>>> I'm not a SelectionDAG and tablegen expert really, but I'm sure it is the
>>> same in the code generator.  Sometimes the signedness is important for an
>>> instruction because flags are affected.  But I'm ignoring that for now,
>>> as
>>> they would be represented as llvm.*.with.overflow in the IR with explicit
>>> signedness.
>>> In cases where flags don't matter, just select the best instruction.  I'd
>>> advise against trying to reconstruct the signedness of an operation.
>>> That's impossible to do in general and there's no good reason to do that.
>>> -Manuel
>>> On 2017-02-15 19:19, Ryan Taylor via llvm-dev wrote:
>>> I'm curious why 'unsigned short w = 0x8000' is displayed as -32768 in the
>>>> IR?
>>>> This propagates to the DAG and hence tablegen, where I am missing
>>>> matching
>>>> on some immediates because the immediate is not being looked at as
>>>> unsigned? For example, we have no issue if instead of 0x8000 we use
>>>> 0x7FFF,
>>>> then everything is fine, the match is fine.
>>>> I can understand that it's just being printed as 'signed' even when it's
>>>> unsigned due to the bit pattern (2s complement)  but it seems to affect
>>>> matching.
>>>> We'd like;
>>>> unsigned short x, y;
>>>> int main() {
>>>>    unsigned short w = 0x8000;
>>>>    y = w - x;
>>>>    return 0;
>>>> }
>>>> To match to something like 'sub16u $0x8000, x, y' (if I set w = 0x7FFF,
>>>> then we get sub16u $0x7FFF, x, y' but not when using 0x8000).
>>>> We have some code to determine if the operation is a signed or unsigned
>>>> operation in tablegen. Can anyone suggest a good way to get around this?
>>>> Thanks,
>>>> Ryan
>>>> _______________________________________________
>>>> LLVM Developers mailing list
>>>> llvm-dev at lists.llvm.org
>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170215/c04c1a89/attachment.html>

More information about the llvm-dev mailing list