Hi,> Hi Alexandre, > > LLVM currently doesn't have trunc nsw/nuw, no. > Which frontend would emit such instructions? Any application in mind? > Just asking because if no frontend could emit those, then the motivation to > add nsw/nuw support to trunc would be very low I guess.I think the clang frontend could use that to allow better static analysis of integer overflows on the LLVM IR. It might be interesting for static analysis tools that want to know if you truncate something that is too large for the target range but you need the sign to determine, e.g. the C/C++ frontend could use that flag for trunc of signed/unsigned integers, then you could e.g. check if (uint8_t)x changes the values if x has stuff out of the 0..255 range. e.g. x as int with -100 => trunc nuw to 8 => bad (int8_t)x => trunc nsw to 8 => ok Greetings Christoph> > Thanks, > Nuno > > -----Original Message----- > From: Alexandre Isoard via llvm-dev > Sent: Monday, July 3, 2017 8:38 PM > To: llvm-dev > Subject: [llvm-dev] trunc nsw/nuw? > > > Hello, > > From [1], trunc does not seems to have a nsw/nuw attribute. > Is it possible to have that? Or do we have that and it is not up-to-date? > > The definition would be: > > If the nuw keyword is present, the result value of the trunc is a poison > value if the truncated high order bits are non-zero. If the nsw keyword is > present, the result value of the trunc is a poison value if the truncated > high order bits are not all equal to the non-truncated bit of the highest > order. > > This allow to cancel out: > - sext with trunc nsw > - zext with trunc nuw > > And probably to commute with add/sub/mul/lshr/ashr/shl/urem/udiv/udiv (with > the correct flags). > > [1]: http://llvm.org/docs/LangRef.html#trunc-to-instruction > > > -- > > Alexandre Isoard > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-- ----------------------------- Dr.-Ing. Christoph Cullmann --------- AbsInt Angewandte Informatik GmbH Email: cullmann at AbsInt.com Science Park 1 Tel: +49-681-38360-22 66123 Saarbrücken Fax: +49-681-38360-20 GERMANY WWW: http://www.AbsInt.com -------------------------------------------------------------------- Geschäftsführung: Dr.-Ing. Christian Ferdinand Eingetragen im Handelsregister des Amtsgerichts Saarbrücken, HRB 11234
Hi, My motivation was to allow clang to keep the semantic information for "long long" to "int" cast. I assume the C/C++ semantic does not specify the behavior in case of overflow for signed integers. Which means we can assume (trust the programmer!?) that signed overflow/underflow do not happen on the truncation. Unsigned integer is "unfortunately" probably properly defined in C/C++. Note that it might be useful to have a nuw attribute at C/C++ level as well, that could be applied to unsigned integer variables by the programmer when he wants to be nice to his preferred compiler. My true motivation behind that is because I end-up with trunc/sext for getelementptr arguments sometimes and I would love to get rid of the spurious ones. They are mostly caused by users casting a size_t into an int on a 64 bit architecture and using that as an array index. I am not sure I am allowed to say that the size_t to int cast is a signed cast. Then in OpenCL (spir64): int i = get_global_id(0); // returns a size_t short val = i; ... = val * A[i]; would become: %global_id.0 = i64 get_global_id(i32 0) %i = trunc nsw i64 %global_id.0 to i32 %idx = sext i32 %i to i64 %A.addr = gep i16, i16* %A.ptr, i64 %idx %A.val = load i16 %A.addr %i.val = trunc nsw i32 %i to i16 %val = mul nsw i16 %i, %A.val And I can get rid of the truncation for the gep (and can "upgrade" the i16 computation to i32 in LLVM if I want so). Does that make sense? Best regard. On Tue, Jul 4, 2017 at 7:41 AM, Dr.-Ing. Christoph Cullmann < cullmann at absint.com> wrote:> Hi, > > > Hi Alexandre, > > > > LLVM currently doesn't have trunc nsw/nuw, no. > > Which frontend would emit such instructions? Any application in mind? > > Just asking because if no frontend could emit those, then the motivation > to > > add nsw/nuw support to trunc would be very low I guess. > I think the clang frontend could use that to allow better static analysis > of integer overflows > on the LLVM IR. > > It might be interesting for static analysis tools that want to know if you > truncate something > that is too large for the target range but you need the sign to determine, > e.g. the C/C++ frontend > could use that flag for trunc of signed/unsigned integers, then you could > e.g. check if > > (uint8_t)x > > changes the values if x has stuff out of the 0..255 range. > > e.g. x as int with -100 => trunc nuw to 8 => bad > > (int8_t)x > > => trunc nsw to 8 => ok > > Greetings > Christoph > > > > > Thanks, > > Nuno > > > > -----Original Message----- > > From: Alexandre Isoard via llvm-dev > > Sent: Monday, July 3, 2017 8:38 PM > > To: llvm-dev > > Subject: [llvm-dev] trunc nsw/nuw? > > > > > > Hello, > > > > From [1], trunc does not seems to have a nsw/nuw attribute. > > Is it possible to have that? Or do we have that and it is not up-to-date? > > > > The definition would be: > > > > If the nuw keyword is present, the result value of the trunc is a poison > > value if the truncated high order bits are non-zero. If the nsw keyword > is > > present, the result value of the trunc is a poison value if the truncated > > high order bits are not all equal to the non-truncated bit of the highest > > order. > > > > This allow to cancel out: > > - sext with trunc nsw > > - zext with trunc nuw > > > > And probably to commute with add/sub/mul/lshr/ashr/shl/urem/udiv/udiv > (with > > the correct flags). > > > > [1]: http://llvm.org/docs/LangRef.html#trunc-to-instruction > > > > > > -- > > > > Alexandre Isoard > > > > _______________________________________________ > > LLVM Developers mailing list > > llvm-dev at lists.llvm.org > > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > -- > ----------------------------- Dr.-Ing. Christoph Cullmann --------- > AbsInt Angewandte Informatik GmbH Email: cullmann at AbsInt.com > Science Park 1 Tel: +49-681-38360-22 > 66123 Saarbrücken Fax: +49-681-38360-20 > GERMANY WWW: http://www.AbsInt.com > -------------------------------------------------------------------- > Geschäftsführung: Dr.-Ing. Christian Ferdinand > Eingetragen im Handelsregister des Amtsgerichts Saarbrücken, HRB 11234 >-- *Alexandre Isoard* -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170704/136c9603/attachment-0001.html>
On 07/04/2017 01:41 AM, Dr.-Ing. Christoph Cullmann via llvm-dev wrote:> Hi, > >> Hi Alexandre, >> >> LLVM currently doesn't have trunc nsw/nuw, no. >> Which frontend would emit such instructions? Any application in mind? >> Just asking because if no frontend could emit those, then the motivation to >> add nsw/nuw support to trunc would be very low I guess. > I think the clang frontend could use that to allow better static analysis of integer overflows > on the LLVM IR. > > It might be interesting for static analysis tools that want to know if you truncate something > that is too large for the target range but you need the sign to determine, e.g. the C/C++ frontend > could use that flag for trunc of signed/unsigned integers, then you could e.g. check if > > (uint8_t)x > > changes the values if x has stuff out of the 0..255 range. > > e.g. x as int with -100 => trunc nuw to 8 => bad > > (int8_t)x > > => trunc nsw to 8 => okI'm not sure that a C/C++ frontend could add this flag. In C++, the conversion for unsigned types is specified and for signed types, it's implementation defined, but in neither case is it UB. -Hal> > Greetings > Christoph > >> Thanks, >> Nuno >> >> -----Original Message----- >> From: Alexandre Isoard via llvm-dev >> Sent: Monday, July 3, 2017 8:38 PM >> To: llvm-dev >> Subject: [llvm-dev] trunc nsw/nuw? >> >> >> Hello, >> >> From [1], trunc does not seems to have a nsw/nuw attribute. >> Is it possible to have that? Or do we have that and it is not up-to-date? >> >> The definition would be: >> >> If the nuw keyword is present, the result value of the trunc is a poison >> value if the truncated high order bits are non-zero. If the nsw keyword is >> present, the result value of the trunc is a poison value if the truncated >> high order bits are not all equal to the non-truncated bit of the highest >> order. >> >> This allow to cancel out: >> - sext with trunc nsw >> - zext with trunc nuw >> >> And probably to commute with add/sub/mul/lshr/ashr/shl/urem/udiv/udiv (with >> the correct flags). >> >> [1]: http://llvm.org/docs/LangRef.html#trunc-to-instruction >> >> >> -- >> >> Alexandre Isoard >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-- Hal Finkel Lead, Compiler Technology and Programming Languages Leadership Computing Facility Argonne National Laboratory
Hi,> On 07/04/2017 01:41 AM, Dr.-Ing. Christoph Cullmann via llvm-dev wrote: >> Hi, >> >>> Hi Alexandre, >>> >>> LLVM currently doesn't have trunc nsw/nuw, no. >>> Which frontend would emit such instructions? Any application in mind? >>> Just asking because if no frontend could emit those, then the motivation to >>> add nsw/nuw support to trunc would be very low I guess. >> I think the clang frontend could use that to allow better static analysis of >> integer overflows >> on the LLVM IR. >> >> It might be interesting for static analysis tools that want to know if you >> truncate something >> that is too large for the target range but you need the sign to determine, e.g. >> the C/C++ frontend >> could use that flag for trunc of signed/unsigned integers, then you could e.g. >> check if >> >> (uint8_t)x >> >> changes the values if x has stuff out of the 0..255 range. >> >> e.g. x as int with -100 => trunc nuw to 8 => bad >> >> (int8_t)x >> >> => trunc nsw to 8 => ok > > I'm not sure that a C/C++ frontend could add this flag. In C++, the > conversion for unsigned types is specified and for signed types, it's > implementation defined, but in neither case is it UB.Yes, you are right, that would be a missuse of these flags and one would need other markers for that. In principle what would be nice for static analysis on IR is some "we cast from signed to unsigned" or back, even for equal bit widths to detect overflows in the representable values. Greetings Christoph -- ----------------------------- Dr.-Ing. Christoph Cullmann --------- AbsInt Angewandte Informatik GmbH Email: cullmann at AbsInt.com Science Park 1 Tel: +49-681-38360-22 66123 Saarbrücken Fax: +49-681-38360-20 GERMANY WWW: http://www.AbsInt.com -------------------------------------------------------------------- Geschäftsführung: Dr.-Ing. Christian Ferdinand Eingetragen im Handelsregister des Amtsgerichts Saarbrücken, HRB 11234
On Wed, Jul 5, 2017 at 3:59 PM, Hal Finkel via llvm-dev < llvm-dev at lists.llvm.org> wrote:> > On 07/04/2017 01:41 AM, Dr.-Ing. Christoph Cullmann via llvm-dev wrote: > >> Hi, >> >> Hi Alexandre, >>> >>> LLVM currently doesn't have trunc nsw/nuw, no. >>> Which frontend would emit such instructions? Any application in mind? >>> Just asking because if no frontend could emit those, then the motivation >>> to >>> add nsw/nuw support to trunc would be very low I guess. >>> >> I think the clang frontend could use that to allow better static analysis >> of integer overflows >> on the LLVM IR. >> >> It might be interesting for static analysis tools that want to know if >> you truncate something >> that is too large for the target range but you need the sign to >> determine, e.g. the C/C++ frontend >> could use that flag for trunc of signed/unsigned integers, then you could >> e.g. check if >> >> (uint8_t)x >> >> changes the values if x has stuff out of the 0..255 range. >> >> e.g. x as int with -100 => trunc nuw to 8 => bad >> >> (int8_t)x >> >> => trunc nsw to 8 => ok >> > > I'm not sure that a C/C++ frontend could add this flag. In C++, the > conversion for unsigned types is specified and for signed types, it's > implementation defined, but in neither case is it UB. >Hmm, I don't get it. Two questions: - if the conversion for unsigned types is specified, how is it undefined behavior? - if the conversion for signed types is UB, then this is a direct application of those flags, isn't it? -Hal> > > >> Greetings >> Christoph >> >> Thanks, >>> Nuno >>> >>> -----Original Message----- >>> From: Alexandre Isoard via llvm-dev >>> Sent: Monday, July 3, 2017 8:38 PM >>> To: llvm-dev >>> Subject: [llvm-dev] trunc nsw/nuw? >>> >>> >>> Hello, >>> >>> From [1], trunc does not seems to have a nsw/nuw attribute. >>> Is it possible to have that? Or do we have that and it is not up-to-date? >>> >>> The definition would be: >>> >>> If the nuw keyword is present, the result value of the trunc is a poison >>> value if the truncated high order bits are non-zero. If the nsw keyword >>> is >>> present, the result value of the trunc is a poison value if the truncated >>> high order bits are not all equal to the non-truncated bit of the highest >>> order. >>> >>> This allow to cancel out: >>> - sext with trunc nsw >>> - zext with trunc nuw >>> >>> And probably to commute with add/sub/mul/lshr/ashr/shl/urem/udiv/udiv >>> (with >>> the correct flags). >>> >>> [1]: http://llvm.org/docs/LangRef.html#trunc-to-instruction >>> >>> >>> -- >>> >>> Alexandre Isoard >>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> llvm-dev at lists.llvm.org >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>> >> > -- > Hal Finkel > Lead, Compiler Technology and Programming Languages > Leadership Computing Facility > Argonne National Laboratory > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-- *Alexandre Isoard* -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170705/1f643272/attachment.html>