[llvm-dev] Unsigned int displaying as negative

Daniel Berlin via llvm-dev llvm-dev at lists.llvm.org
Wed Feb 15 14:15:19 PST 2017


If you want to see what happens, the transforms/* tests have examples where
nsw disappears.


On Wed, Feb 15, 2017 at 1:58 PM, Ryan Taylor via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> For every example we've seen, nsw is very consistent with signed
> operation. I understand it's a 'potential for signed overflow' flag but it
> seems very consistent with signedness.
>
> On Wed, Feb 15, 2017 at 2:48 PM, Manuel Jacob <me at manueljacob.de> wrote:
>
>> Where does the unsignedSub come from?
>>
>>
>> On 2017-02-15 20:38, Ryan Taylor wrote:
>>
>>> Sorry, it should be:
>>>
>>> defm SUB16u_  : ABD_NonCommutative<"sub16u", unsignedSub, LOADRegs,
>>> GPRRegs, DSTRegs, i16, i16, i16, uimm16, immZExt16x>;
>>>
>>> On Wed, Feb 15, 2017 at 2:37 PM, Ryan Taylor <ryta1203 at gmail.com> wrote:
>>>
>>> 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
>>>> all.
>>>>
>>>> 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
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>
> _______________________________________________
> 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/b3d322d9/attachment-0001.html>


More information about the llvm-dev mailing list