Hi, there are optimizations, mostly dealing with hoisting/merging common code including function calls, that breaks stack trace symbolization in a very bad way. int f(int x) { if (x == 1) report("a"); else if (x == 2) report("b"); return 0; } For example, in the above function (at -O1) both calls to report() are done from the same PC. As a result, stack trace (from inside report()) will point to the same source line no matter what branch was actually taken. In practice, these two (or more) lines may be very far from each other. This makes stack traces misleading and very hard to reason about. Mostly, we are running in this issue with sanitizers, where we care about performance (and therefore don't use -O0), but want stacktraces to be mostly sane anyway. http://llvm-reviews.chandlerc.com/D2214 http://llvm-reviews.chandlerc.com/D2215 I've prepared two patches that deal with these issues by disabling this and similar optimizations when building with sanitizers. Would it be reasonable to disable these optimizations at -O1 instead?
I'd support disabling tail merging of calls at -O1. The other CFG simplification doesn't seem like that big of a deal though for general debugging, though. On Tue, Nov 26, 2013 at 3:57 AM, Evgeniy Stepanov <eugeni.stepanov at gmail.com> wrote:> Hi, > > there are optimizations, mostly dealing with hoisting/merging common > code including function calls, that breaks stack trace symbolization > in a very bad way. > > int f(int x) { > if (x == 1) > report("a"); > else if (x == 2) > report("b"); > return 0; > } > > For example, in the above function (at -O1) both calls to report() are > done from the same PC. As a result, stack trace (from inside report()) > will point to the same source line no matter what branch was actually > taken. In practice, these two (or more) lines may be very far from > each other. This makes stack traces misleading and very hard to reason > about. > > Mostly, we are running in this issue with sanitizers, where we care > about performance (and therefore don't use -O0), but want stacktraces > to be mostly sane anyway. > > http://llvm-reviews.chandlerc.com/D2214 > http://llvm-reviews.chandlerc.com/D2215 > > I've prepared two patches that deal with these issues by disabling > this and similar optimizations when building with sanitizers. > > Would it be reasonable to disable these optimizations at -O1 instead? > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131126/a8af5eb6/attachment.html>
On Nov 26, 2013, at 8:59 AM, Reid Kleckner <rnk at google.com> wrote:> I'd support disabling tail merging of calls at -O1. The other CFG simplification doesn't seem like that big of a deal though for general debugging, though.I agree, -Chris> > > On Tue, Nov 26, 2013 at 3:57 AM, Evgeniy Stepanov <eugeni.stepanov at gmail.com> wrote: > Hi, > > there are optimizations, mostly dealing with hoisting/merging common > code including function calls, that breaks stack trace symbolization > in a very bad way. > > int f(int x) { > if (x == 1) > report("a"); > else if (x == 2) > report("b"); > return 0; > } > > For example, in the above function (at -O1) both calls to report() are > done from the same PC. As a result, stack trace (from inside report()) > will point to the same source line no matter what branch was actually > taken. In practice, these two (or more) lines may be very far from > each other. This makes stack traces misleading and very hard to reason > about. > > Mostly, we are running in this issue with sanitizers, where we care > about performance (and therefore don't use -O0), but want stacktraces > to be mostly sane anyway. > > http://llvm-reviews.chandlerc.com/D2214 > http://llvm-reviews.chandlerc.com/D2215 > > I've prepared two patches that deal with these issues by disabling > this and similar optimizations when building with sanitizers. > > Would it be reasonable to disable these optimizations at -O1 instead? > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131126/f5bc3cc9/attachment.html>
On 26 November 2013 16:59, Reid Kleckner <rnk at google.com> wrote:> I'd support disabling tail merging of calls at -O1. The other CFG > simplification doesn't seem like that big of a deal though for general > debugging, though. >So, do we have two ways of running SimplifyCFG? One for O1 and one for O2+, and selectively disabling parts of it? --renato -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131126/7aaf6025/attachment.html>
On 11/26/13 3:57 AM, Evgeniy Stepanov wrote:> Hi, > > there are optimizations, mostly dealing with hoisting/merging common > code including function calls, that breaks stack trace symbolization > in a very bad way. > > int f(int x) { > if (x == 1) > report("a"); > else if (x == 2) > report("b"); > return 0; > } > > For example, in the above function (at -O1) both calls to report() are > done from the same PC. As a result, stack trace (from inside report()) > will point to the same source line no matter what branch was actually > taken. In practice, these two (or more) lines may be very far from > each other. This makes stack traces misleading and very hard to reason > about. > > Mostly, we are running in this issue with sanitizers, where we care > about performance (and therefore don't use -O0), but want stacktraces > to be mostly sane anyway. > > http://llvm-reviews.chandlerc.com/D2214 > http://llvm-reviews.chandlerc.com/D2215 > > I've prepared two patches that deal with these issues by disabling > this and similar optimizations when building with sanitizers. > > Would it be reasonable to disable these optimizations at -O1 instead?This is a bit of a tangent, but there are other optimizations which exhibit similar problems with stack trace preservation. For example, sibling call optimizations and self tail call elimination are both problematic. As are all forms of basic block commoning. I have a use case which is similar to that of the sanitizers, but where the correctness of the stack traces is strictly required for correctness. For now, we're using an alternate mechanism, but we'd eventually like to move to relying on debug information for our stack traces. Would it make sense to separate our a flag for preserving full and exactly stack traces? Using -O1 is one option, but it would be nice to move beyond -O1 with reasonable confidence that stack traces would be preserved. Would others be interested in such a feature? Philip
On 2 December 2013 20:12, Philip Reames <listmail at philipreames.com> wrote:> Would it make sense to separate our a flag for preserving full and exactly > stack traces? Using -O1 is one option, but it would be nice to move beyond > -O1 with reasonable confidence that stack traces would be preserved. Would > others be interested in such a feature?I can't say I'm interested in that, but it shouldn't be too different than a module-level #pragma optimize (no_this, no_that), which could be supported if the table of flags has a rich enough semantics. cheers, --renato