From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1851) id CEF413857374; Thu, 28 Jul 2022 12:12:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CEF413857374 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Martin Liska To: gcc-cvs@gcc.gnu.org Subject: [gcc/devel/sphinx] gimple, internal-fn: Add IFN_TRAP and use it for __builtin_unreachable [PR106099] X-Act-Checkin: gcc X-Git-Author: Jakub Jelinek X-Git-Refname: refs/heads/devel/sphinx X-Git-Oldrev: a1b7908c3d4a8efee575fd9492409c93facc9000 X-Git-Newrev: 3a4cd5dc6faca8fed7fa256c4c06f4999b5a1f9c Message-Id: <20220728121219.CEF413857374@sourceware.org> Date: Thu, 28 Jul 2022 12:12:19 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 Jul 2022 12:12:19 -0000 https://gcc.gnu.org/g:3a4cd5dc6faca8fed7fa256c4c06f4999b5a1f9c commit 3a4cd5dc6faca8fed7fa256c4c06f4999b5a1f9c Author: Jakub Jelinek Date: Thu Jul 28 12:42:14 2022 +0200 gimple, internal-fn: Add IFN_TRAP and use it for __builtin_unreachable [PR106099] __builtin_unreachable and __ubsan_handle_builtin_unreachable don't use vops, they are marked const/leaf/noreturn/nothrow/cold. But __builtin_trap uses vops, isn't const, just leaf/noreturn/nothrow/cold. This is I believe so that when users explicitly use __builtin_trap in their sources they get stores visible at the trap side. -fsanitize=unreachable -fsanitize-undefined-trap-on-error used to transform __builtin_unreachable to __builtin_trap even in the past, but the sanopt pass has TODO_update_ssa, so it worked fine. Now that gimple_build_builtin_unreachable can build a __builtin_trap call right away, we can run into problems that whenever we need it we would need to either manually or through TODO_update* ensure the vops being updated. Though, as it is originally __builtin_unreachable which is just implemented as trap, I think for this case it is fine to avoid vops. For this the patch introduces IFN_TRAP, which has ECF_* flags like __builtin_unreachable and is expanded as __builtin_trap. 2022-07-28 Jakub Jelinek PR tree-optimization/106099 * internal-fn.def (TRAP): New internal fn. * internal-fn.h (expand_TRAP): Declare. * internal-fn.cc (expand_TRAP): Define. * gimple.cc (gimple_build_builtin_unreachable): For BUILT_IN_TRAP, use internal fn rather than builtin. * gcc.dg/ubsan/pr106099.c: New test. Diff: --- gcc/gimple.cc | 11 ++++++++++- gcc/internal-fn.cc | 6 ++++++ gcc/internal-fn.def | 4 ++++ gcc/internal-fn.h | 1 + gcc/testsuite/gcc.dg/ubsan/pr106099.c | 10 ++++++++++ 5 files changed, 31 insertions(+), 1 deletion(-) diff --git a/gcc/gimple.cc b/gcc/gimple.cc index 9b156399ba1..cd5ad0c718b 100644 --- a/gcc/gimple.cc +++ b/gcc/gimple.cc @@ -430,7 +430,16 @@ gimple_build_builtin_unreachable (location_t loc) { tree data = NULL_TREE; tree fn = sanitize_unreachable_fn (&data, loc); - gcall *g = gimple_build_call (fn, data != NULL_TREE, data); + gcall *g; + if (DECL_FUNCTION_CODE (fn) != BUILT_IN_TRAP) + g = gimple_build_call (fn, data != NULL_TREE, data); + else + { + /* Instead of __builtin_trap use .TRAP, so that it doesn't + need vops. */ + gcc_checking_assert (data == NULL_TREE); + g = gimple_build_call_internal (IFN_TRAP, 0); + } gimple_set_location (g, loc); return g; } diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index 28973d957fb..aa7c482e968 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -4494,3 +4494,9 @@ expand_SPACESHIP (internal_fn, gcall *stmt) if (!rtx_equal_p (target, ops[0].value)) emit_move_insn (target, ops[0].value); } + +void +expand_TRAP (internal_fn, gcall *) +{ + expand_builtin_trap (); +} diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def index 7c398baadc8..7bf661ca376 100644 --- a/gcc/internal-fn.def +++ b/gcc/internal-fn.def @@ -456,6 +456,10 @@ DEF_INTERNAL_FN (SHUFFLEVECTOR, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL) /* <=> optimization. */ DEF_INTERNAL_FN (SPACESHIP, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL) +/* __builtin_trap created from/for __builtin_unreachable. */ +DEF_INTERNAL_FN (TRAP, ECF_CONST | ECF_LEAF | ECF_NORETURN + | ECF_NOTHROW | ECF_COLD, NULL) + #undef DEF_INTERNAL_INT_FN #undef DEF_INTERNAL_FLT_FN #undef DEF_INTERNAL_FLT_FLOATN_FN diff --git a/gcc/internal-fn.h b/gcc/internal-fn.h index 23c014a963c..c4c94f80d51 100644 --- a/gcc/internal-fn.h +++ b/gcc/internal-fn.h @@ -242,6 +242,7 @@ extern void expand_internal_call (internal_fn, gcall *); extern void expand_PHI (internal_fn, gcall *); extern void expand_SHUFFLEVECTOR (internal_fn, gcall *); extern void expand_SPACESHIP (internal_fn, gcall *); +extern void expand_TRAP (internal_fn, gcall *); extern bool vectorized_internal_fn_supported_p (internal_fn, tree); diff --git a/gcc/testsuite/gcc.dg/ubsan/pr106099.c b/gcc/testsuite/gcc.dg/ubsan/pr106099.c new file mode 100644 index 00000000000..e3f17b34681 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ubsan/pr106099.c @@ -0,0 +1,10 @@ +/* PR tree-optimization/106099 */ +/* { dg-do compile } */ +/* { dg-options "-O -fsanitize=unreachable -fsanitize-undefined-trap-on-error -fno-tree-ccp -fno-tree-dominator-opts" } */ + +void +foo (void) +{ + for (unsigned i = 0; i == 0; i++) + ; +}