David,
Here is the definition accepted by Hal of what we’re doing
> 1. Sometimes there are abstraction penalties in C++ code
> 2. That can be optimized away after template instantiation, function
inlining, etc
> 3. When they for example exhibit this pattern
> if (A) {
> stuff;
> } else {
> other stuff including “undefined behavior”;
> }
> 4. Where the compiler assumes “undefined behavior” doesn’t actually happen
because
> In the C language standard it is the users responsibility to avoid it
> 5. Therefore in this example the compiler can a) delete the else-clause
> b) delete the if-cond, c) assume A is true and propagate that
information
We are actively deleting undefined behavior, and the question is why
given that doing so potentially masks a real source code bug.
At the very least deleting undefined behavior should not be the default.
Peter Lawrence.
> On Jul 12, 2017, at 2:24 AM, David Chisnall <David.Chisnall at
cl.cam.ac.uk> wrote:
>
> On 10 Jul 2017, at 19:36, Peter Lawrence via llvm-dev <llvm-dev at
lists.llvm.org> wrote:
>>
>> why should we ever optimize / delete any UB at all ?
>
> No one has addressed this yet, which may be why you are still under the
impression that it’s under discussion. You seem to have some misconceptions
about UB. There are two major reasons for UB in a language such as C:
>
> 1. The safe version may be prohibitively expensive on some architectures.
For example, division by zero will give a trap on some architectures or an
unspecified value on others. If the C specification stated that it gave an
unspecified value, then on architectures that trap every division would have to
be wrapped in a branch that tested if the divisor was zero and branched over the
divide instruction if so. This would lead to very inefficient code on these
architectures, so the C standard says that anything is allowed to happen.
>
> 2. Some properties are effectively impossible to verify statically[1]. For
example, it is undefined behaviour in C to use a pointer to a deallocated
object[2]. If C required well-defined behaviour here then it would effectively
be mandating some form of garbage collector: you’d need to either find all
pointers to an object and null them on free, or you’d need to mark the object,
check the mark on every load, and not reuse the memory until later. This would
be unacceptable overhead for a C implementation. A lot of other things are in
this category.
>
> Many things are a mixture of these. Most optimisations that rely on
undefined behaviour are not saying ‘aha, we’ve spotted that the program invokes
undefined behaviour, we can replace the whole thing with a trap instruction!’,
they’re saying ‘this program does either X or Y, X would be undefined behaviour
and so we can assume that it does Y’. Not being able to do the latter would
mean that they’d need to insert run-time checks each time, which would negate
the optimisation and *in well-written code would never be hit*.
>
> The cases where the compiler can statically prove that undefined behaviour
is present are comparatively rare.
>
> David
>
> [1] Note: Some of these are possible with whole-program analysis, so if
you’re happy without shared libraries and with week-long compile times then it’s
possible.
>
> [2] The wording of this actually means that it’s impossible to implement
malloc() in ISO C, because as soon as the pointer has been passed to free then
it becomes invalid and using it to put the object on a free list invokes
undefined behaviour.
Chandler Carruth via llvm-dev
2017-Jul-13 21:15 UTC
[llvm-dev] GEP with a null pointer base
On Thu, Jul 13, 2017 at 5:13 PM Peter Lawrence via llvm-dev < llvm-dev at lists.llvm.org> wrote:> David, > Here is the definition accepted by Hal of what we’re doing > > > 1. Sometimes there are abstraction penalties in C++ code > > 2. That can be optimized away after template instantiation, function > inlining, etc > > 3. When they for example exhibit this pattern > > if (A) { > > stuff; > > } else { > > other stuff including “undefined behavior”; > > } > > 4. Where the compiler assumes “undefined behavior” doesn’t actually > happen because > > In the C language standard it is the users responsibility to avoid it > > 5. Therefore in this example the compiler can a) delete the else-clause > > b) delete the if-cond, c) assume A is true and propagate that > information > > > > We are actively deleting undefined behavior, and the question is why > given that doing so potentially masks a real source code bug. > At the very least deleting undefined behavior should not be the default. >You are asserting this (again), but others have clearly stated that they disagree. David gave detailed and clear reasons why. Continuing to re-state positions is not productive. -Chandler -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170713/be2c95ed/attachment.html>
2017-07-12 11:17 GMT-07:00 Peter Lawrence via llvm-dev < llvm-dev at lists.llvm.org>:> David, > Here is the definition accepted by Hal of what we’re doing > > > 1. Sometimes there are abstraction penalties in C++ code > > 2. That can be optimized away after template instantiation, function > inlining, etc > > 3. When they for example exhibit this pattern > > if (A) { > > stuff; > > } else { > > other stuff including “undefined behavior”; > > } > > 4. Where the compiler assumes “undefined behavior” doesn’t actually > happen because > > In the C language standard it is the users responsibility to avoid it > > 5. Therefore in this example the compiler can a) delete the else-clause > > b) delete the if-cond, c) assume A is true and propagate that > information > > > > We are actively deleting undefined behavior, and the question is why > given that doing so potentially masks a real source code bug. > At the very least deleting undefined behavior should not be the default. >I don't believe it is the default today: optimizations aren't turned on unless you opt-in. -- Mehdi -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170713/daa92db7/attachment.html>
Chandler,
The only thing David made clear that wasn’t already clear
is that he believes UB to be “comparatively rare”, which is in agreement
with what Hal already said which is that he does not expect deleting
UB will be of benefit to for example SPEC benchmarks.
Given that it is “comparatively rare”, why all the effort to delete it ?
And why make deleting it the default rather than warning about it ?
Peter
> On Jul 13, 2017, at 2:15 PM, Chandler Carruth <chandlerc at
gmail.com> wrote:
>
> On Thu, Jul 13, 2017 at 5:13 PM Peter Lawrence via llvm-dev <llvm-dev at
lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote:
> David,
> Here is the definition accepted by Hal of what we’re doing
>
> > 1. Sometimes there are abstraction penalties in C++ code
> > 2. That can be optimized away after template instantiation, function
inlining, etc
> > 3. When they for example exhibit this pattern
> > if (A) {
> > stuff;
> > } else {
> > other stuff including “undefined behavior”;
> > }
> > 4. Where the compiler assumes “undefined behavior” doesn’t actually
happen because
> > In the C language standard it is the users responsibility to avoid
it
> > 5. Therefore in this example the compiler can a) delete the
else-clause
> > b) delete the if-cond, c) assume A is true and propagate that
information
>
>
>
> We are actively deleting undefined behavior, and the question is why
> given that doing so potentially masks a real source code bug.
> At the very least deleting undefined behavior should not be the default.
>
> You are asserting this (again), but others have clearly stated that they
disagree. David gave detailed and clear reasons why. Continuing to re-state
positions is not productive.
>
> -Chandler
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20170719/867bf94f/attachment.html>