public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jason Merrill <jason@redhat.com>
To: Jakub Jelinek <jakub@redhat.com>
Cc: gcc-patches@gcc.gnu.org, richard.guenther@gmail.com,
	jwakely.gcc@gmail.com
Subject: Re: [PATCH RFA] ubsan: default to trap on unreachable at -O0 and -Og [PR104642]
Date: Wed, 15 Jun 2022 16:38:49 -0400	[thread overview]
Message-ID: <6c78210d-f2a8-3371-5d88-74bdab399706@redhat.com> (raw)
In-Reply-To: <Yqh0oEM/A1Q5CVAL@tucnak>

On 6/14/22 07:44, Jakub Jelinek wrote:
> On Mon, Jun 13, 2022 at 03:53:13PM -0400, Jason Merrill via Gcc-patches wrote:
>> When not optimizing, we can't do anything useful with unreachability in
>> terms of code performance, so we might as well improve debugging by turning
>> __builtin_unreachable into a trap.  In the PR richi suggested introducing an
>> -funreachable-traps flag for this, but this functionality is already
>> implemented as -fsanitize=unreachable -fsanitize-undefined-trap-on-error, we
>> just need to set those flags by default.
>>
>> I think it also makes sense to do this when we're explicitly optimizing for
>> the debugging experience.
>>
>> I then needed to make options-save handle -fsanitize and
>> -fsanitize-undefined-trap-on-error; since -fsanitize is has custom parsing,
>> that meant handling it explicitly in the awk scripts.  I also noticed we
>> weren't setting it in opts_set.
>>
>> Do we still want -funreachable-traps as an alias (or separate flag) for this
>> behavior that doesn't mention the sanitizer?
> 
> I do not like doing it this way, -fsanitize-undefined-trap-on-error is
> (unfortunately for compatibility with llvm misdesign, users should have
> ways to control which of the enabled sanitizers should be handled which way,
> where the 3 ways are runtime diagnostics without abort, runtime diagnostics
> with abort and __builtin_trap ()) an all or nothing option which affects all
> the sanitizers.

Makes sense.  The first is -fsanitize-recover=, I think, the second is 
the default, and perhaps the third could be -fsanitize-trap=?

> Your patch will e.g. silently enable the sanitization
> whenever just -fsanitize-undefined-trap-on-error is passed, but that can be
> passed even when users don't really expect any sanitization, just making
> sure that if it is enabled (say for selected TUs or functions), it doesn't
> need a runtime library to report it.

I'm happy to drop that part.

> Furthermore, handling it the UBSan way means we slow down the compiler
> (enable a bunch of extra passes, like sanopt, ubsan), which is undesirable
> e.g. for -O0 compilation speed.

The ubsan pass is not enabled for unreachable|return.  sanopt does a 
single pass over the function to rewrite __builtin_unreachable, but that 
doesn't seem like much overhead.

> So, I think -funreachable-traps should be a separate flag and not an alias,
> enabled by default for -O0 and -Og, which would be handled elsewhere
> (I'd say e.g. in fold_builtin_0 and perhaps gimple_fold_builtin too to
> avoid allocating trees unnecessary)

I tried this approach, but it misses some __builtin_unreachable calls 
added by e.g. execute_fixup_cfg; it seems they never get folded by any 
subsequent pass.

It seems to me that we want -funreachable-traps (or whatever spelling) 
to have exactly the same effect as the current 
-fsanitize=unreachable,return -fsanitize-undefined-trap-on-error, so 
using an entirely novel implementation strategy seems wrong.

OTOH, maybe the sanitizer should also hook into fold_builtin_0 to 
rewrite many of the calls before any of the optimizers run, so we don't 
need to explicitly check SANITIZE_UNREACHABLE in e.g. 
optimize_unreachable.  And I notice that we currently optimize away the 
call to f() in

bool b;
int f() {
   if (b) return 42;
   __builtin_unreachable ();
} 

int main() { f(); }

with -fsanitize=unreachable -O, so the test exits normally.

> and would be done if
> flag_unreachable_traps && !sanitize_flag_p (SANITIZE_UNREACHABLE),
> just replacing that __builtin_unreachable call with __builtin_trap.
> For the function ends in fact under those conditions we could emit
> __builtin_trap right away instead of emitting __builtin_unreachable
> and waiting on folding it later to __builtin_trap.

Sure, but I generally prefer to change fewer places.

Jason


  reply	other threads:[~2022-06-15 20:38 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-13 19:53 Jason Merrill
2022-06-14 11:44 ` Jakub Jelinek
2022-06-15 20:38   ` Jason Merrill [this message]
2022-06-16 13:14     ` Jakub Jelinek
2022-06-20 20:30       ` Jason Merrill
2022-06-21 11:17         ` Jakub Jelinek
2022-06-22  3:59           ` Jason Merrill
2022-06-22  8:05             ` Jakub Jelinek
2022-06-16 20:32   ` Jonathan Wakely
2022-06-16 20:53     ` Jakub Jelinek
2022-06-17 15:34     ` [PATCH] ubsan: Add -fsanitize-trap= support Jakub Jelinek
2022-06-17 18:21       ` Jason Merrill

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6c78210d-f2a8-3371-5d88-74bdab399706@redhat.com \
    --to=jason@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@redhat.com \
    --cc=jwakely.gcc@gmail.com \
    --cc=richard.guenther@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).