[llvm-dev] The undef story

Peter Lawrence via llvm-dev llvm-dev at lists.llvm.org
Thu Jul 6 14:22:34 PDT 2017

> On Jul 1, 2017, at 12:14 PM, Hal Finkel <hfinkel at anl.gov> wrote:
> On 06/30/2017 11:16 AM, Peter Lawrence wrote:
>>> On Jun 29, 2017, at 5:48 PM, Hal Finkel <hfinkel at anl.gov <mailto:hfinkel at anl.gov>> wrote:
>>> On 06/29/2017 07:26 PM, Peter Lawrence wrote:
>>>> Hal,
>>>>       Mehdi points out I mis-quoted you, I apologize sincerely.
>>>> Mehdi,
>>>>            Thank you for forcing me to go back and re-read what Hal wrote,
>>>> I could have sworn Hal and I were in agreement at the time I wrote you,
>>>> Must have been asleep at the wheel, not enough sleep last night
>>>> However my request for a more concrete example stands
>>>> Here’s what I said
>>>>> This doesn’t make sense to me, a shift amount of 48 is “undefined” for unsigned char,
>>>>> How do we know this isn’t a source code bug,
>>>>> What makes us think the the user intended the result to be “0”.
>>>> Here’s what Hal said in response
>>>> > As I said, this is representation of what the real code did, and looked like, after other 
>>>> > inlining had taken place, etc. In the original form, the user's intent was 
>>>> > clear. That code is never executed when T is a small integer type.
>>>> The problem is I don’t know how to interpret what Hal said here,
>>>> I can’t construct the “real” example from the “representative” example
>>>> given his advise.
>>> Hopefully, the description I later provided helps. I can't share the "real" code, but I reconstructed this example from my memory of the original code plus some of the intermediate IR I'd looked at.
>> Hal,
>>       I’d like to see if I understand you, here’s what I think, let me know if this is correct
>> 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
> That's correct. […]
>  -Hal

Great, so it seems like this definition enables us to lift ourselves
out of our current dilemma of only being able to discuss this rhetorically
to now being able to discuss this objectively.

It is also incredibly practical, for example now I can write my own program that 
shows why it could be beneficial to define branch-on-undef to be “undefined 
behavior” rather than a binary choice.

And finally, with this objective definition we can decide which issues that
are nagging us can be decided on technical grounds and which ones cannot.

An example of one that is not decidable on technical grounds is the question
of whether these optimizations are legal [*], rather this is a philosophical question.

* finding the right wording here is a struggle, perhaps “justified”,
  “ethical”, “desirable”, or some other word, works better. The sense of
  the issue even if imperfectly worded is this, that the alternative which
  is to replace undefined behavior with a run-time trap has equally compelling
  arguments in its favor.

Perhaps this philosophical question can’t even be decided within the llvm
community, rather the discussion might have play out in places like standards
committees and in publications like Communications of the ACM.

Thoughts ?
Comments ?
Questions ?

Peter Lawrence.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170706/a517df8d/attachment.html>

More information about the llvm-dev mailing list