On 15.10.2008, at 14.01, Pertti Kellomäki wrote:> Tatu Vaajalahti wrote: >> With this program llvm-gcc -O2 optimizes test2 away even though it's >> address is taken in program (gcc-4.2 does not, neither does llvm-gcc >> with -O or -O0): >> >> >> #include <stdio.h> >> >> static const char test1 = 'x'; >> static const char test2 = 'x'; >> >> int main(int argc, char **argv) >> { >> printf("%p\n", &test1); >> printf("%p\n", &test2); >> >> return 0; >> } > > Seems to me that it is perfectly legitimate for the compiler to fold > the > two char constants together. Since they are both static and const, > they cannot be changed from outside the compilation unit, and the > compiler sees that they are not changed within the unit.True, but note that it is the address of a variable that is used, not the value. What is more troublesome is that llvm-gcc combines these also across files with -O4: test.c: #include <stdio.h> static const char test1 = 'a'; static const char test2 = 'a'; void testf(); int main(int argc, char **argv) { printf("%p\n", &test1); printf("%p\n", &test2); testf(); return 0; } test2.c: #include <stdio.h> static const char test1 = 'a'; static const char test2 = 'a'; void testf(void) { printf("%p\n", &test1); printf("%p\n", &test2); } llvm-gcc -O3 test.c test2.c : 0x1ffd 0x1ffd 0x1ffe 0x1ffe llvm-gcc -O4 test.c test2.c : 0x1ffd 0x1ffd 0x1ffd 0x1ffd --- Tatu Vaajalahti Tampere, Finland
> True, but note that it is the address of a variable that is used, not > the value.Yes, but why do you think they should get a different address? I can understand that it is surprising that they do, but determining whether this is legal or not requires reading the language standard. Hopefully a language lawyer can chime in and say whether this transform is valid or not. Ciao, Duncan.
On 15.10.2008, at 16.43, Duncan Sands wrote:>> True, but note that it is the address of a variable that is used, not >> the value. > > Yes, but why do you think they should get a different address? I can > understand that it is surprising that they do, but determining whether > this is legal or not requires reading the language standard. > Hopefully > a language lawyer can chime in and say whether this transform is valid > or not.I agree the whole construction is a litle bit strange (stupid even). It is however common way to specify context identity in one Objective- C pattern (although I don't think anyone actually uses initialized const variables, I was just playing with them to see how compilers put stuff in segments). I do think however that it's bit dangerous to combine static constants across compilation units. --- Tatu Vaajalahti Tampere, Finland
On 15.10.2008, at 17.31, Pertti Kellomäki wrote:> Tatu Vaajalahti wrote: >> On 15.10.2008, at 14.01, Pertti Kellomäki wrote: >>> Seems to me that it is perfectly legitimate for the compiler to fold >>> the two char constants together. >> True, but note that it is the address of a variable that is used, not >> the value. > > ... But I'm out of my depth here so > maybe some language lawyer could chime in.Me too :) --- Tatu Vaajalahti Tampere, Finland
Tatu Vaajalahti wrote:> On 15.10.2008, at 14.01, Pertti Kellomäki wrote: >> Seems to me that it is perfectly legitimate for the compiler to fold >> the two char constants together. > True, but note that it is the address of a variable that is used, not > the value.I don't have the C standard handy, but I would be somewhat surprised if the standard would explicitly require two const char variables to occupy distinct memory locations even if their contents are equivalent. But I'm out of my depth here so maybe some language lawyer could chime in. -- Pertti
Duncan Sands wrote:>> True, but note that it is the address of a variable that is used, not >> the value. > > Yes, but why do you think they should get a different address? I can > understand that it is surprising that they do, but determining whether > this is legal or not requires reading the language standard. Hopefully > a language lawyer can chime in and say whether this transform is valid > or not.Change the return statement to: return test1 == test2; LLVM will constant-fold that to false, which is inconsistent with the other optimization. Nick> > Ciao, > > Duncan. > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
On Oct 15, 2008, at 9:43 AM, Duncan Sands wrote:>> True, but note that it is the address of a variable that is used, not >> the value. > > Yes, but why do you think they should get a different address? I can > understand that it is surprising that they do, but determining whether > this is legal or not requires reading the language standard. > Hopefully > a language lawyer can chime in and say whether this transform is valid > or not.FWIW, I've been discussing this with some of my colleagues (who may well be the foremost experts on this topic), and so far we don't have a definite answer (we're looking at C99 and C++). We do think that a strict reading of the standard allows the optimization, but there is also some suspicion that that is unintended (at least in C++). Daveed