[llvm-dev] Unsigned int displaying as negative

Manuel Jacob via llvm-dev llvm-dev at lists.llvm.org
Wed Feb 15 11:48:29 PST 2017


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


More information about the llvm-dev mailing list