Bevin Hansson via llvm-dev
2020-Jul-08 15:30 UTC
[llvm-dev] [RFC] Saturating left shift intrinsics
Hello, This is an RFC for adding intrinsics which perform saturating signed/unsigned left shift. There is currently a patch on Phabricator here: https://reviews.llvm.org/D83216 The intrinsics are of the form i32 @llvm.sshl.sat.i32(i32, i32) i32 @llvm.ushl.sat.i32(i32, i32) <4 x i32> @llvm.sshl.sat.v4i32(<4 x i32>, <4 x i32>) <4 x i32> @llvm.ushl.sat.v4i32(<4 x i32>, <4 x i32>) and are overloaded with a single type which can be either an integer type or a vector of integers. The value(s) provided in the first operand are shifted left by the amount(s) given by the second operand. As with regular left shift instructions, the second operand is an unsigned quantity and must be less than the integer bitwidth. If the true result of the operation (given infinite precision) lies outside of the maximum or minimum representable value of the signed/unsigned integer, the result saturates to the maximum or minimum depending on the sign of the shifted value. These are useful for implementing the Embedded-C fixed-point arithmetic support in Clang, as previously detailed and discussed here: http://lists.llvm.org/pipermail/llvm-dev/2018-August/125433.html http://lists.llvm.org/pipermail/cfe-dev/2018-May/058019.html It is of course possible to emit these shifts as regular IR instructions, but targets which support saturating shifts might have difficulties efficiently selecting native instructions if the optimizer undoes the particular expected instruction pattern that the shifts would be selected on. / Bevin -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200708/1c67fe84/attachment.html>
Roman Lebedev via llvm-dev
2020-Jul-08 15:50 UTC
[llvm-dev] [RFC] Saturating left shift intrinsics
+1. I think this makes sense. The inconsistency (lack of these intrinsics, also missing: mul.sat and shift.overflow) didn't make much sense to me. For reference, here's alive2 support: https://github.com/AliveToolkit/alive2/pull/448 Roman. On Wed, Jul 8, 2020 at 6:31 PM Bevin Hansson via llvm-dev <llvm-dev at lists.llvm.org> wrote:> > Hello, > > > > This is an RFC for adding intrinsics which perform saturating signed/unsigned left shift. > > There is currently a patch on Phabricator here: > > https://reviews.llvm.org/D83216 > > > > The intrinsics are of the form > > > > i32 @llvm.sshl.sat.i32(i32, i32) > > i32 @llvm.ushl.sat.i32(i32, i32) > > <4 x i32> @llvm.sshl.sat.v4i32(<4 x i32>, <4 x i32>) > > <4 x i32> @llvm.ushl.sat.v4i32(<4 x i32>, <4 x i32>) > > > > and are overloaded with a single type which can be either an integer type or a vector of integers. The value(s) provided in the first operand are shifted left by the amount(s) given by the second operand. As with regular left shift instructions, the second operand is an unsigned quantity and must be less than the integer bitwidth. > > > > If the true result of the operation (given infinite precision) lies outside of the maximum or minimum representable value of the signed/unsigned integer, the result saturates to the maximum or minimum depending on the sign of the shifted value. > > > > These are useful for implementing the Embedded-C fixed-point arithmetic support in Clang, as previously detailed and discussed here: > > http://lists.llvm.org/pipermail/llvm-dev/2018-August/125433.html > > http://lists.llvm.org/pipermail/cfe-dev/2018-May/058019.html > > > > It is of course possible to emit these shifts as regular IR instructions, but targets which support saturating shifts might have difficulties efficiently selecting native instructions if the optimizer undoes the particular expected instruction pattern that the shifts would be selected on. > > > > / Bevin > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Bevin Hansson via llvm-dev
2020-Jul-09 09:51 UTC
[llvm-dev] [RFC] Saturating left shift intrinsics
Actually, mul.sat sort of exists. If you use an llvm.[su]mul.fix.sat with a scale of zero, you almost have saturating integer multiplication. There's always the possibility that it will end up rounding differently than a real integer multiplication would, though. / Bevin -----Original Message----- From: Roman Lebedev <lebedev.ri at gmail.com> Sent: July 08, 2020 5:50 PM To: llvm-dev at lists.llvm.org Cc: Bevin Hansson <bevin.hansson at ericsson.com>; Chris Lattner <clattner at nondot.org>; Nikita Popov <nikita.ppv at gmail.com> Subject: Re: [llvm-dev] [RFC] Saturating left shift intrinsics +1. I think this makes sense. The inconsistency (lack of these +intrinsics, also missing: mul.sat and shift.overflow) didn't make much sense to me. For reference, here's alive2 support: https://protect2.fireeye.com/v1/url?k=e2a45020-bc04ea4e-e2a410bb-86b1886cfa64-9b120237c63590df&q=1&e=90eb055c-3695-4130-bb21-70e8de83fce3&u=https%3A%2F%2Fgithub.com%2FAliveToolkit%2Falive2%2Fpull%2F448 Roman. On Wed, Jul 8, 2020 at 6:31 PM Bevin Hansson via llvm-dev <llvm-dev at lists.llvm.org> wrote:> > Hello, > > > > This is an RFC for adding intrinsics which perform saturating signed/unsigned left shift. > > There is currently a patch on Phabricator here: > > https://protect2.fireeye.com/v1/url?k=4437fc4f-1a974621-4437bcd4-86b18 > 86cfa64-d1fec53f1bc0eaa9&q=1&e=90eb055c-3695-4130-bb21-70e8de83fce3&u> https%3A%2F%2Freviews.llvm.org%2FD83216 > > > > The intrinsics are of the form > > > > i32 @llvm.sshl.sat.i32(i32, i32) > > i32 @llvm.ushl.sat.i32(i32, i32) > > <4 x i32> @llvm.sshl.sat.v4i32(<4 x i32>, <4 x i32>) > > <4 x i32> @llvm.ushl.sat.v4i32(<4 x i32>, <4 x i32>) > > > > and are overloaded with a single type which can be either an integer type or a vector of integers. The value(s) provided in the first operand are shifted left by the amount(s) given by the second operand. As with regular left shift instructions, the second operand is an unsigned quantity and must be less than the integer bitwidth. > > > > If the true result of the operation (given infinite precision) lies outside of the maximum or minimum representable value of the signed/unsigned integer, the result saturates to the maximum or minimum depending on the sign of the shifted value. > > > > These are useful for implementing the Embedded-C fixed-point arithmetic support in Clang, as previously detailed and discussed here: > > https://protect2.fireeye.com/v1/url?k=7a90f440-24304e2e-7a90b4db-86b18 > 86cfa64-2eac3424697005d8&q=1&e=90eb055c-3695-4130-bb21-70e8de83fce3&u> http%3A%2F%2Flists.llvm.org%2Fpipermail%2Fllvm-dev%2F2018-August%2F125 > 433.html > > https://protect2.fireeye.com/v1/url?k=845b06d8-dafbbcb6-845b4643-86b18 > 86cfa64-c826beb711de0a13&q=1&e=90eb055c-3695-4130-bb21-70e8de83fce3&u> http%3A%2F%2Flists.llvm.org%2Fpipermail%2Fcfe-dev%2F2018-May%2F058019. > html > > > > It is of course possible to emit these shifts as regular IR instructions, but targets which support saturating shifts might have difficulties efficiently selecting native instructions if the optimizer undoes the particular expected instruction pattern that the shifts would be selected on. > > > > / Bevin > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://protect2.fireeye.com/v1/url?k=3dacbf84-630c05ea-3dacff1f-86b18 > 86cfa64-9d631db88d39b9be&q=1&e=90eb055c-3695-4130-bb21-70e8de83fce3&u> https%3A%2F%2Flists.llvm.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fllvm-dev
Nikita Popov via llvm-dev
2020-Jul-16 20:30 UTC
[llvm-dev] [RFC] Saturating left shift intrinsics
On Wed, Jul 8, 2020 at 5:31 PM Bevin Hansson via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Hello, > > > > This is an RFC for adding intrinsics which perform saturating > signed/unsigned left shift. > > There is currently a patch on Phabricator here: > > https://reviews.llvm.org/D83216 > > > > The intrinsics are of the form > > > > i32 @llvm.sshl.sat.i32(i32, i32) > > i32 @llvm.ushl.sat.i32(i32, i32) > > <4 x i32> @llvm.sshl.sat.v4i32(<4 x i32>, <4 x i32>) > > <4 x i32> @llvm.ushl.sat.v4i32(<4 x i32>, <4 x i32>) > > > > and are overloaded with a single type which can be either an integer type > or a vector of integers. The value(s) provided in the first operand are > shifted left by the amount(s) given by the second operand. As with regular > left shift instructions, the second operand is an unsigned quantity and > must be less than the integer bitwidth. > > > > If the true result of the operation (given infinite precision) lies > outside of the maximum or minimum representable value of the > signed/unsigned integer, the result saturates to the maximum or minimum > depending on the sign of the shifted value. > > > > These are useful for implementing the Embedded-C fixed-point arithmetic > support in Clang, as previously detailed and discussed here: > > http://lists.llvm.org/pipermail/llvm-dev/2018-August/125433.html > > http://lists.llvm.org/pipermail/cfe-dev/2018-May/058019.html > > > > It is of course possible to emit these shifts as regular IR instructions, > but targets which support saturating shifts might have difficulties > efficiently selecting native instructions if the optimizer undoes the > particular expected instruction pattern that the shifts would be selected > on. >These generally look reasonable to me, and fit in with the existing saturating arithmetic intrinsics. My only question here would be what kind of support these intrinsics are targeting. Are you planning to work on high-quality middle end support for them, with an eventual goal of canonicality (as is the case for the existing saturating arithmetic intrinsics), or are these intended to be target intrinsics in all but name (as is the case for the existing fixed-point intrinsics)? Regards, Nikita -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200716/a12d3b0d/attachment.html>
Bevin Hansson via llvm-dev
2020-Jul-17 11:22 UTC
[llvm-dev] [RFC] Saturating left shift intrinsics
My idea is definitely to add support in the optimizer for them, but I don’t know quite yet to what extent. Constant folding and simplification of known (non-)saturating operations seems reasonable to add. I’m also not sure when I will get to it; I would like to get the Clang patches in first, but those are a bit blocked by other refactorings at the moment. From: Nikita Popov <nikita.ppv at gmail.com> Sent: July 16, 2020 22:31 To: Bevin Hansson <bevin.hansson at ericsson.com> Cc: llvm-dev at lists.llvm.org Subject: Re: [llvm-dev] [RFC] Saturating left shift intrinsics On Wed, Jul 8, 2020 at 5:31 PM Bevin Hansson via llvm-dev <llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote: Hello, This is an RFC for adding intrinsics which perform saturating signed/unsigned left shift. There is currently a patch on Phabricator here: https://reviews.llvm.org/D83216 The intrinsics are of the form i32 @llvm.sshl.sat.i32(i32, i32) i32 @llvm.ushl.sat.i32(i32, i32) <4 x i32> @llvm.sshl.sat.v4i32(<4 x i32>, <4 x i32>) <4 x i32> @llvm.ushl.sat.v4i32(<4 x i32>, <4 x i32>) and are overloaded with a single type which can be either an integer type or a vector of integers. The value(s) provided in the first operand are shifted left by the amount(s) given by the second operand. As with regular left shift instructions, the second operand is an unsigned quantity and must be less than the integer bitwidth. If the true result of the operation (given infinite precision) lies outside of the maximum or minimum representable value of the signed/unsigned integer, the result saturates to the maximum or minimum depending on the sign of the shifted value. These are useful for implementing the Embedded-C fixed-point arithmetic support in Clang, as previously detailed and discussed here: http://lists.llvm.org/pipermail/llvm-dev/2018-August/125433.html http://lists.llvm.org/pipermail/cfe-dev/2018-May/058019.html It is of course possible to emit these shifts as regular IR instructions, but targets which support saturating shifts might have difficulties efficiently selecting native instructions if the optimizer undoes the particular expected instruction pattern that the shifts would be selected on. These generally look reasonable to me, and fit in with the existing saturating arithmetic intrinsics. My only question here would be what kind of support these intrinsics are targeting. Are you planning to work on high-quality middle end support for them, with an eventual goal of canonicality (as is the case for the existing saturating arithmetic intrinsics), or are these intended to be target intrinsics in all but name (as is the case for the existing fixed-point intrinsics)? Regards, Nikita -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200717/0cf64645/attachment.html>