Ryan Taylor via llvm-dev
2017-Feb-15 19:37 UTC
[llvm-dev] Unsigned int displaying as negative
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 >>>> >>>> >>>-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170215/c04c1a89/attachment.html>
Ryan Taylor via llvm-dev
2017-Feb-15 19:38 UTC
[llvm-dev] Unsigned int displaying as negative
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 >>>>> >>>>> >>>> >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170215/c5832463/attachment.html>
Manuel Jacob via llvm-dev
2017-Feb-15 19:48 UTC
[llvm-dev] Unsigned int displaying as negative
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 >>>>>> >>>>>> >>>>>
Friedman, Eli via llvm-dev
2017-Feb-15 20:14 UTC
[llvm-dev] Unsigned int displaying as negative
On 2/15/2017 11:37 AM, Ryan Taylor via llvm-dev 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); }]>;"Imm" in ImmLeaf is an int64_t, sign-extended from your immediate type (in this case, int16_t). You'd need to insert an explicit cast to uint16_t to get the behavior you want. I'm not sure why you're doing this, though; every 16-bit integer immediate fits into a 16-bit integer, so a correctly implemented "immZExt16x" is just equivalent to "imm". -Eli -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
Ryan Taylor via llvm-dev
2017-Feb-15 20:29 UTC
[llvm-dev] Unsigned int displaying as negative
I believe that the idea of simm16 and uimm16 was taken over from MipsInstrInfo.td. It's entirely possible that the concepts were misunderstood then. So, a broader question, what is the best way to map down to an unsigned/signed sub/add (is this even possible)? How to add signed/unsigned immediates? Thanks. On Wed, Feb 15, 2017 at 3:14 PM, Friedman, Eli <efriedma at codeaurora.org> wrote:> On 2/15/2017 11:37 AM, Ryan Taylor via llvm-dev 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); }]>; >> > > "Imm" in ImmLeaf is an int64_t, sign-extended from your immediate type (in > this case, int16_t). You'd need to insert an explicit cast to uint16_t to > get the behavior you want. > > I'm not sure why you're doing this, though; every 16-bit integer immediate > fits into a 16-bit integer, so a correctly implemented "immZExt16x" is just > equivalent to "imm". > > > -Eli > > -- > Employee of Qualcomm Innovation Center, Inc. > Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux > Foundation Collaborative Project > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170215/4cb8d871/attachment.html>