[llvm-dev] The undef story

Mehdi AMINI via llvm-dev llvm-dev at lists.llvm.org
Thu Jun 29 12:35:26 PDT 2017


2017-06-29 10:43 GMT-07:00 Peter Lawrence via llvm-dev <
llvm-dev at lists.llvm.org>:

>
> On Jun 29, 2017, at 9:32 AM, Hal Finkel <hfinkel at anl.gov> wrote:
>
>
> On 06/29/2017 10:41 AM, Peter Lawrence wrote:
>
>
> On Jun 29, 2017, at 4:39 AM, Hal Finkel <hfinkel at anl.gov> wrote:
>
> On 06/28/2017 05:33 PM, Peter Lawrence wrote:
>
> Chandler,
>                where we disagree is in whether the current project is
> moving the issue
> forward.  It is not.  It is making the compiler more complex for no
> additional value.
>
> The current project is not based in evidence, I have asked for any SPEC
> benchmark
> that shows performance gain by the compiler taking advantage of “undefined
> behavior”
> and no one can show that.
>
>
> I can't comment on SPEC, but this does remind me of code I was working on
> recently. To abstract the relevant parts, it looked something like this:
>
> template <typename T>
> int do_something(T mask, bool cond) {
>   if (mask & 2)
>     return 1;
>
>   if (cond) {
>     T high_mask = mask >> 48;
>     if (high_mask > 5)
>       do_something_1(high_mask);
>     else if (high_mask > 3)
>       do_something_2();
>   }
>
>   return 0;
> }
>
> This function ended up being instantiated on different types T (e.g.
> unsigned char, unsigned int, unsigned long, etc.) and, dynamically, cond
> was always false when T was char. The question is: Can the compiler
> eliminate all of the code predicated on cond for the smaller types? In this
> case, this code was hot, and moreover, performance depended on the fact
> that, for T = unsigned char, the function was inlined and the branch on
> cond was eliminated. In the relevant translation unit, however, the
> compiler would never see how cond was set.
>
> Luckily, we do the right thing here currently. In the case where T =
> unsigned char, we end up folding both of the high_mask tests as though they
> were false. That entire part of the code is eliminated, the function is
> inlined, and everyone is happy.
>
> Why was I looking at this? As it turns out, if the 'else if' in this
> example is just 'else', we don't actually eliminate both sides of the
> branch. The same is true for many other variants of the conditionals (i.e.
> we don't recognize all of the code as dead).
>
>
>
> I apologize in advance if I have missed something here and am misreading
> your example...
>
> 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”.
>
>
> 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.
>
>
>
> I will still have a hard time believing this until I see a real example,
> can you fill in the details ?
>


Hal gave you a real example, have you tried? I feel like you're asking more
effort from others than you are ready to put in: it took me less than 5
minutes to reproduce what Hal was describing using his snippet:

See the difference between https://godbolt.org/g/YYtsxB and
https://godbolt.org/g/dTBBDq

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


More information about the llvm-dev mailing list