> On Jun 29, 2017, at 5:48 PM, Hal Finkel <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 Peter Lawrence. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170630/564f3f12/attachment.html>
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 > informationThat's correct. (And, as Sanjoy has said, you might end up with these situations in IR generated from source-level-safe languages where some combination of how the IR is generated by the frontend, and how the runtime works, guarantees that the IR-level UB is dynamically unreachable.) -Hal> > > Peter Lawrence. > > > > > > > >-- Hal Finkel Lead, Compiler Technology and Programming Languages Leadership Computing Facility Argonne National Laboratory -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170701/d2742071/attachment.html>
> 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. […] > > -HalGreat, 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>