Anastasiya Ruzhanskaya via llvm-dev
2017-Jul-31 08:56 UTC
[llvm-dev] unsigned operations with negative numbers
Hello, I want to know, if I can always assume that when I do unsigned operations like udiv, urem I will get the both operands converted to unsigned values? with under optimized version of code I sometimes receive these lines: unsigned a = 123; int b = -2; int c = a / b; -> %1 = udiv i32 123, -2 and get the result 0. Will it always be zero? or is it undefined? Somewhere I have read that it may produce garbage. will it be zero in this case : %1 = udiv i32 -123, 2? However, when I set only the result as unsigned, then : int a = 123; int b = -2; unsigned int c = a / b; -> %1 = sdiv i32 123, -2 the result seems to be correct. So one operand (not the result variable) needs to be unsigned in order the result was unsigned too? What should I expect from sign of the operand if I get the line: %1 = udiv i32 %a.o, 2. Can it in this case be negative. Or this situation is only the result of under optimization and zero value is ok? These questions may be related mostly to c, but still, perhaps llvm has some additional rules that I didn't find. The general thing I wanted to know what to expect from sign of value when I get urem/udiv ops in final code? Thank you in advance for the answer. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170731/ed17c7bf/attachment.html>
Bruce Hoult via llvm-dev
2017-Jul-31 09:02 UTC
[llvm-dev] unsigned operations with negative numbers
I'm surprised llvm (or clang) is emitting that -2 without a cast. But I'm sure it is treating it as MAXUINT-1 i.e. 0xfffffffe = 4294967294 on a 32 bit machine. On Mon, Jul 31, 2017 at 11:56 AM, Anastasiya Ruzhanskaya via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Hello, > I want to know, if I can always assume that when I do unsigned operations > like > > udiv, urem > > I will get the both operands converted to unsigned values? with under > optimized version of code I sometimes receive these lines: > unsigned a = 123; > int b = -2; > int c = a / b; > -> %1 = udiv i32 123, -2 > > and get the result 0. Will it always be zero? or is it undefined? > Somewhere I have read that it may produce garbage. > will it be zero in this case : %1 = udiv i32 -123, 2? > > However, when I set only the result as unsigned, then : > int a = 123; > int b = -2; > unsigned int c = a / b; > -> %1 = sdiv i32 123, -2 > the result seems to be correct. So one operand (not the result variable) > needs to be unsigned in order the result was unsigned too? > > What should I expect from sign of the operand if I get the line: > %1 = udiv i32 %a.o, 2. Can it in this case be negative. Or this situation > is only the result of under optimization and zero value is ok? > > These questions may be related mostly to c, but still, perhaps llvm has > some additional rules that I didn't find. The general thing I wanted to > know what to expect from sign of value when I get urem/udiv ops in final > code? > > Thank you in advance for the answer. > > _______________________________________________ > 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/20170731/55e332e2/attachment.html>
Anastasiya Ruzhanskaya via llvm-dev
2017-Jul-31 09:08 UTC
[llvm-dev] unsigned operations with negative numbers
I get this result by applying only these transformations -mem2reg -lcssa -simplifycfg, maybe they are sufficient, -reassociate helps and returns 0. So, if it MAXUINT-1, it is clear why it is zero or a big number when the first operand is negative. 2017-07-31 11:02 GMT+02:00 Bruce Hoult <bruce at hoult.org>:> I'm surprised llvm (or clang) is emitting that -2 without a cast. But I'm > sure it is treating it as MAXUINT-1 i.e. 0xfffffffe = 4294967294 on a 32 > bit machine. > > > On Mon, Jul 31, 2017 at 11:56 AM, Anastasiya Ruzhanskaya via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > >> Hello, >> I want to know, if I can always assume that when I do unsigned operations >> like >> >> udiv, urem >> >> I will get the both operands converted to unsigned values? with under >> optimized version of code I sometimes receive these lines: >> unsigned a = 123; >> int b = -2; >> int c = a / b; >> -> %1 = udiv i32 123, -2 >> >> and get the result 0. Will it always be zero? or is it undefined? >> Somewhere I have read that it may produce garbage. >> will it be zero in this case : %1 = udiv i32 -123, 2? >> >> However, when I set only the result as unsigned, then : >> int a = 123; >> int b = -2; >> unsigned int c = a / b; >> -> %1 = sdiv i32 123, -2 >> the result seems to be correct. So one operand (not the result variable) >> needs to be unsigned in order the result was unsigned too? >> >> What should I expect from sign of the operand if I get the line: >> %1 = udiv i32 %a.o, 2. Can it in this case be negative. Or this situation >> is only the result of under optimization and zero value is ok? >> >> These questions may be related mostly to c, but still, perhaps llvm has >> some additional rules that I didn't find. The general thing I wanted to >> know what to expect from sign of value when I get urem/udiv ops in final >> code? >> >> Thank you in advance for the answer. >> >> _______________________________________________ >> 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/20170731/0e6c6f99/attachment.html>
Tim Northover via llvm-dev
2017-Jul-31 13:59 UTC
[llvm-dev] unsigned operations with negative numbers
On 31 July 2017 at 01:56, Anastasiya Ruzhanskaya via llvm-dev <llvm-dev at lists.llvm.org> wrote:> What should I expect from sign of the operand if I get the line: > %1 = udiv i32 %a.o, 2. Can it in this case be negative.LLVM integers don't really have a sign and are just bags of bits. It's the operations that interpret those as signed or unsigned integers and udiv's arguments are unsigned. They're printed as signed numbers purely for convenience (-2 is a lot more recognisable than 4294967294)> Or this situation is > only the result of under optimization and zero value is ok?I'm not sure what you mean by zero here. The result of your first division example will be 0. Cheers. Tim.
Alexandre Isoard via llvm-dev
2017-Jul-31 14:40 UTC
[llvm-dev] unsigned operations with negative numbers
Hello, On Mon, Jul 31, 2017 at 9:56 AM, Anastasiya Ruzhanskaya via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Hello, > I want to know, if I can always assume that when I do unsigned operations > like > > udiv, urem > > I will get the both operands converted to unsigned values? >Signed-ness in LLVM is not stored into the integer, it is left to interpretation to the instruction that use them. udiv / urem will interpret both their operands as unsigned integer. (and the behavior is straight forward) sdiv / srem will interpret both their operands as signed integers stored with 2's complement. (and the behavior match the "crappy" behavior of C)> with under optimized version of code I sometimes receive these lines: > unsigned a = 123; > int b = -2; > int c = a / b; > -> %1 = udiv i32 123, -2 > > and get the result 0. Will it always be zero? >Yes. We decided that LLVM IR, when printed for human consumption, would print literal constants as signed integers. Here it is -2, but it actually means 4294967294. This number is indubitably bigger than 123. udiv i32 -2, -2 udiv i32 -1, -2 Are the only ones that will return a non null result, in both cases the result will be 1. or is it undefined? Somewhere I have read that it may produce garbage.> will it be zero in this case : %1 = udiv i32 -123, 2? >No. %1 = udiv i32 -123, 2 = udiv i32 4294967173, 2 = 2147483586> However, when I set only the result as unsigned, then : > int a = 123; > int b = -2; > unsigned int c = a / b; > -> %1 = sdiv i32 123, -2 > the result seems to be correct. So one operand (not the result variable) > needs to be unsigned in order the result was unsigned too? >That is a C semantic. From what I remember, if one of the operand is unsigned, then the computation will be unsigned. The return value type does not influence the type of the operation. But it might introduce a final cast.> What should I expect from sign of the operand if I get the line: > %1 = udiv i32 %a.o, 2. Can it in this case be negative. Or this situation > is only the result of under optimization and zero value is ok? >The result cannot be "negative". Because negative numbers start with a 1, and a udiv by 2 is equal to a logical shift right by 1 bit, which introduce a 0 as first bit. Which means that if a later operand interpret %1 as a signed integer, it will still be a positive value. It can be zero if %a.o is 0 or 1. Note that if %a.o was produced by a "signed" operation, and you see the result as a negative number, %a.o can grow in size (because the number will now become positive if interpreted as signed number).> These questions may be related mostly to c, but still, perhaps llvm has > some additional rules that I didn't find. The general thing I wanted to > know what to expect from sign of value when I get urem/udiv ops in final > code? >It depends what you mean by "sign of value". Again, in llvm, integer data do not have a sign. You will see that there is no sign-cast instruction. Some instruction like add/sub/mul/etc... are sign-oblivious and do not need to distinguish between signed/unsigned kind. While udiv/sdiv, urem/srem, etc... are different depending if you take into account a signed-ness of their operands or not. In LLVM, sign of numbers interpreted as signed values follow 2's complement. (0 is positive, and there the number of maximum absolute value is negative and do not have a positive equivalent, which is annoying when considering signed division by -1).> Thank you in advance for the answer. > > _______________________________________________ > 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/20170731/4ee0170f/attachment.html>