Vyacheslav Egorov <vegorov@xxxxxxxxxxxx> writes: >>ÂTherefore, the compiler knows that the assignments to p[0] and p[1] can not modify >> result. > > I understand this part. I would understand if say compiler reordered > reads from result variable and stores to p[0] and p[1]. > But I do not understand what allows compiler to consider these stores > as dead --- they have to modify _something_ in the memory to which p > points. Sure, but the compiler can prove 1) p points to a local variable and 2) the local variable is not used. So any store through p is dead and can be eliminated. Obviously the second point is the trickier one. It's a consequence of the representation that the compiler uses for alias analysis. The compiler has to effectively invent a local variable to be the target of the uint32_t stores, since there is no existing local variable. Then that invented local variable is not used, is discarded, and the stores are dead, and are discarded. > In general compiler can't say anything about that location > especially if it sees only body of > init [lets consider non-inlined case to reduce amount of information > available to compiler]. Maybe init was called like: > > uint32_t x[2]; > init(reinterpret_cast<uint64_t*>(x), hi, lo); > use(x[0]); > use(x[1]); > > Is it also a violation of strict aliasing rules? We load and store > values through uint32_t* pointers. But uint32_t* pointers are passed > around hidden as a pointer of incompatible type uint64_t*. This code is OK. You are permitted to cast a pointer to another type, as long as you cast it back before you actually use it. What matters is that every access to an object uses the same type (or is accessed via a pointer to a char type). > That is what happens in V8 all the time: we read and store values > through pointers of type Object** (each object in heap is essentially > an array of pointer to other objects), but we "hide" this Object** > pointers inside pointers of type Foo*, where Foo is some type with > nicely typed getters/setters which essentially cast this pointer to > Object** pointer. Again what matters is that all accesses to a particular object use the same type. Casting to other pointers doesn't matter as long as you don't actually use those pointers. In this case I don't know whether you use them or not. I assume there are no virtual functions here. If you have an Object* po, and you cast it to a Foo* pf, and you then say pf->x, that should be OK with regard to the aliasing rules. Ian