Re: Optimization techniques and undefined behavior

Bart <bc@freeuk.com>
Wed, 1 May 2019 12:40:08 +0100

          From comp.compilers

Related articles
[4 earlier articles]
Re: Optimization techniques and undefined behavior bc@freeuk.com (Bart) (2019-04-29)
Re: Optimization techniques and undefined behavior david.brown@hesbynett.no (David Brown) (2019-04-29)
Re: Optimization techniques and undefined behavior auriocus@gmx.de (Christian Gollwitzer) (2019-04-29)
Re: Optimization techniques and undefined behavior bc@freeuk.com (Bart) (2019-04-29)
Re: Optimization techniques and undefined behavior david.brown@hesbynett.no (David Brown) (2019-04-30)
Re: Optimization techniques and undefined behavior david.brown@hesbynett.no (David Brown) (2019-04-30)
Re: Optimization techniques and undefined behavior bc@freeuk.com (Bart) (2019-05-01)
Re: Optimization techniques and undefined behavior bc@freeuk.com (Bart) (2019-05-01)
Re: Optimization techniques and undefined behavior anw@cuboid.co.uk (Andy Walker) (2019-05-02)
Re: Optimization techniques and undefined behavior martin@gkc.org.uk (Martin Ward) (2019-05-02)
Re: Optimization techniques and undefined behavior david.brown@hesbynett.no (David Brown) (2019-05-02)
Re: Optimization techniques and undefined behavior david.brown@hesbynett.no (David Brown) (2019-05-02)
Re: Optimization techniques and undefined behavior 847-115-0292@kylheku.com (Kaz Kylheku) (2019-05-02)
[23 later articles]
| List of all articles for this month |

From: Bart <bc@freeuk.com>
Newsgroups: comp.compilers
Date: Wed, 1 May 2019 12:40:08 +0100
Organization: virginmedia.com
References: <72d208c9-169f-155c-5e73-9ca74f78e390@gkc.org.uk> 19-04-021 19-04-023 19-04-037 19-04-039 19-04-042 19-04-045 19-04-049
Injection-Info: gal.iecc.com; posting-host="news.iecc.com:2001:470:1f07:1126:0:676f:7373:6970"; logging-data="54093"; mail-complaints-to="abuse@iecc.com"
Keywords: standards, arithmetic
Posted-Date: 01 May 2019 21:32:14 EDT
Content-Language: en-GB

On 30/04/2019 14:48, David Brown wrote:
> On 29/04/2019 19:15, Bart wrote:
>> On 29/04/2019 16:08, David Brown wrote:
>>> On 29/04/2019 01:31, Bart wrote:
>>
>>>> then you don't want the compiler being clever about overflow.
>>>
>>> I /do/ want a result consistent with a single expression, or splitting
>>> up the expression.
>>
>> Then the choice is between both ways giving you 1500000000, or both
>> giving you -647483648.
>
> Let me repeat - I do not care what the results are here.  I don't care
> if they are consistent with each other.  I don't care if they change
> between runs of the compiler.  I don't care if the result is a pink
> umbrella.


So, there's a bug in the program, an inadvertent overflow. But rather
than help in discovering that bug (such as giving the wrong results)
gcc (and its clone Clang) conveniently pretend that such bugs cannot
exist, and use that to give their code an unfair advantage:


          #include <stdio.h>


          int main(void) {
                  int x,y,z;


                  x=1000000000;
                  z=0;


                  for (int i=0; i<1000000000; ++i) {
                          y=x*3/3;
                          z+=y;
                          ++x;
                  }


                  printf("%d\n",x);
                  printf("%d\n",y);
                  printf("%d\n",z);
          }


Optimising compilers that don't take advantage of that undefined
behaviour give timings here of 1.25 seconds (msvc) and 1.9 seconds
(pelles c), with some taking much longer.


The two that do, give timings of 0.22 seconds (gcc) and 0.05 seconds
(clang).


However, there are a couple of problems: (1) they give different
results; (2) they cheated by not doing a billion multiplies and divides.


Note this example also includes UB due to z+=y line, but I'm only
interested in the bottom 32 bits, albeit signed, as a kind of checksum
to compare with other compilers.


For that purpose, I need the final z value to be -101627306, which will
match the same 32-bit arithmetic across languages** and in assembly.


I don't need it to be the mathematically correct 1499999999500000000,
which seems to me what you'd like it to be. gcc/clang-O3 give me
1565039360 which is neither one nor the other.


-------------------------------


(** This is the above program auto-translated from C to one of my
languages, which is sort of interesting, this being a compiler group.


Normally this is just for to help in viewing torturous C source code as
the C semantics are not translated. But tweaked with the int32() cast to
match C's intermediate calculations (usually 64-bit here), this actually
works:


          import clib


          global function main()int32 =
                  var int32 x
                  var int32 y
                  var int32 z
                  var int32 i


                  x := 1000000000
                  z := 0
                  i := 0
                  while i<1000000000 do
                          y := int32(x*3)/3
                          z +:= y
                          ++x
                          ++i
                  od
                  printf("%d\n",x)
                  printf("%d\n",y)
                  printf("%d\n",z)
                  return 0
          end


          proc start =
                  stop main()
          end


The results match those of the non-gcc/non-clang C compilers (apart from
speed which is poor).)


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.