On Jun 4, 2013, at 4:42 PM, Tyler Hardin <tghardin1 at catamount.wcu.edu> wrote:> I was suggesting to add it to the function, like > volatile void func(..); > Theoretically, this would tell the compiler not to omit seemingly superfluous calls to func.'volatile' can't apply to a function, so I'm not sure what you mean. In your example, 'volatile' modifies the 'void'. So I think "theoretically", it doesn't do anything at all. -- Carl
I tried the "extern" specifier, which (I guess) you should use if the definition isn't in the file; and it worked with -O3. Input code: extern void external(void); void test(char *x) { x--; if (!x) { external(); } } Command: clang -S -o volatile-test.s -O3 test.c Output attached. The only line of interest is probably: jmp external # TAILCALL -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130604/fcb995e2/attachment.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: extern-test.s Type: application/octet-stream Size: 326 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130604/fcb995e2/attachment.obj>
On Jun 4, 2013, at 5:20 PM, Tyler Hardin <tghardin1 at catamount.wcu.edu> wrote:> I tried the "extern" specifier, which (I guess) you should use if the definition isn't in the file; and it worked with -O3.That 'extern' doesn't do anything - it's implicit. Did you try without it and get different results? In my test here with the Mac OS X dev tools version of clang, I got the expected results, both for x86 and for ARM. I guess it's possible it's ARM related. What version of clang/llvm did you use for your test? -- Carl> Input code: > extern void external(void); > void test(char *x) > { > x--; > if (!x) > { > external(); > } > } > > Command: > clang -S -o volatile-test.s -O3 test.c > > Output attached. > > The only line of interest is probably: > jmp external # TAILCALL > <extern-test.s>
Hi Carl, I don't know much about the specifics of any given optimisation, but if you do something like the following, you can at least see which optimisation pass is responsible. At the very least perhaps that can point to the next place to investigate. (also interesting to note Apple's shipped clang doesn't exhibit this behaviour, I had to use my own recent svn tree) $ clang -arch arm -emit-llvm -S -O0 example.c -o arm.bc $ opt -print-after-all -O1 arm.bc I can see where the branch test is whittled down to an 'if true' and then eliminated, but cannot comment as to why this might be. Cheers, -DavidM On 05/06/2013, at 9:50 AM, Carl Norum <carl at lytro.com> wrote:> > On Jun 4, 2013, at 4:42 PM, Tyler Hardin <tghardin1 at catamount.wcu.edu> wrote: >> I was suggesting to add it to the function, like >> volatile void func(..); >> Theoretically, this would tell the compiler not to omit seemingly superfluous calls to func. > > 'volatile' can't apply to a function, so I'm not sure what you mean. In your example, 'volatile' modifies the 'void'. So I think "theoretically", it doesn't do anything at all. > > -- Carl > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
On 6/4/2013 7:31 PM, David Mirabito wrote:> Hi Carl, > > I don't know much about the specifics of any given optimisation, but if you do something like the following, you can at least see which optimisation pass is responsible. > At the very least perhaps that can point to the next place to investigate. (also interesting to note Apple's shipped clang doesn't exhibit this behaviour, I had to use my own recent svn tree) > > $ clang -arch arm -emit-llvm -S -O0 example.c -o arm.bc > $ opt -print-after-all -O1 arm.bc > > I can see where the branch test is whittled down to an 'if true' and then eliminated, but cannot comment as to why this might be. >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. -- Joshua Cranmer Thunderbird and DXR developer Source code archæologist
On Jun 4, 2013, at 5:31 PM, David Mirabito <david.mirabito at gmail.com> wrote:> Hi Carl, > > I don't know much about the specifics of any given optimisation, but if you do something like the following, you can at least see which optimisation pass is responsible.Thanks for the example; it's going to take me a while to figure out what the output really means, though!> At the very least perhaps that can point to the next place to investigate. (also interesting to note Apple's shipped clang doesn't exhibit this behaviour, I had to use my own recent svn tree)Yeah, I noticed that as well, so it's definitely a behaviour change.> $ clang -arch arm -emit-llvm -S -O0 example.c -o arm.bc > $ opt -print-after-all -O1 arm.bc > > I can see where the branch test is whittled down to an 'if true' and then eliminated, but cannot comment as to why this might be.I think I see that too. I'll have to stare at that output some more to see if it yields any insight. -- Carl> Cheers, > -DavidM > > On 05/06/2013, at 9:50 AM, Carl Norum <carl at lytro.com> wrote: > >> >> On Jun 4, 2013, at 4:42 PM, Tyler Hardin <tghardin1 at catamount.wcu.edu> wrote: >>> I was suggesting to add it to the function, like >>> volatile void func(..); >>> Theoretically, this would tell the compiler not to omit seemingly superfluous calls to func. >> >> 'volatile' can't apply to a function, so I'm not sure what you mean. In your example, 'volatile' modifies the 'void'. So I think "theoretically", it doesn't do anything at all. >> >> -- Carl >> >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >