[LLVMdev] bug or expected behaviour?

Carl Norum carl at lytro.com
Tue Jun 4 22:19:20 PDT 2013


On Jun 4, 2013, at 8:55 PM, Joshua Cranmer 🐧 <Pidgeot18 at gmail.com> wrote:
> From reading C11, I can posit a potential spec explanation:
> 
> Start with x--. Per C11:
> If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.
> 
> The optimizer can therefore conclude that if this program has well-defined behavior, then x can never point to the null pointer constant (since the null pointer constant is not part of any array object). As a result, the "if (!x)" branch would never trigger, and is dead code.
> 
> So this doesn't look like an invalid optimization per C11, but that doesn't mean that it's necessarily desired behavior in the optimizer.

Thanks Joshua,

A bit of spec reading made me think something like that was going on.  In the land of embedded systems, zero is often a valid pointer, though, so being able to avoid this kind of optimization would be nice.  That said, if that's the way clang is going to be, it's certainly possible to work around.

In this specific case, the OS vendor is doing something (IMHO) terrible - aliasing a 'char *' field of a queue structure via a #define statement to act as a recursive mutex counter.  Something like:

    #define recursive_mutex_counter some_field_not_used_by_a_mutex
    struct queue
    {
       char *some_field_not_used_by_a_mutex;
    };

    void mutexReleaseRecursive(struct queue *q)
    {
        q->recursive_mutex_counter--;

        if (q->recursive_mutex_counter == 0)
            queue_push_back(q, some_dummy_variable);
    }

Which, as I'm sure we can all agree here is heinous.  It's easily worked around without changing the vendor's funny-business overloading:

    q->recursive_mutex_counter = (char *)((uint32_t)q->recursive_mutex_counter - 1);

And I can send them a patch to that effect.  I guess what I'm looking for is either for clang to make it possible to avoid this kind of optimization, to change the optimizer so it doesn't happen in the first place, or for someone on the list to give me a canonical answer that clang is going to continue behaving this way in the future, so I have something to point to when the OS guys try to push back (I've found other standard-violating behaviour that they've declined to fix).

Any input or suggestions from the list are welcome and appreciated!

-- 
Carl Norum
carl at lytro.com





More information about the llvm-dev mailing list