On Mon, Jan 17, 2022 at 09:08:22PM -0800, Andrew Pinski wrote: > > Perhaps even > > /* Check builtins that prevent splitting. */ > > if (gimple_code (stmt) == GIMPLE_CALL) > > if (tree decl = gimple_call_fndecl (stmt)) > > { > > if (fndecl_built_in_p (decl, BUILT_IN_NORMAL)) > > ... > > if (lookup_attribute || lookup_attribute) > > ... > > } > > ? > > Yes that looks good, I am just finished up the patch and going to run > a full bootstrap/test to make sure I didn't mess up. > I had originally trying not to reindent the code to make it easier to > see what was being added but I think re-indentation is correct after > all.
Here is what I've bootstrapped/regtested successfully on x86_64-linux and i686-linux. Note, besides the reformatting I've changed the wording of the added comment. 2022-01-18 Andrew Pinski <apin...@marvell.com> PR tree-optimization/101941 * ipa-split.c (visit_bb): Disallow function calls where the function has either error or warning attribute. * gcc.c-torture/compile/pr101941.c: New test. * gcc.dg/tree-ssa/pr101941.c: New test. --- gcc/ipa-split.c.jj 2022-01-11 23:11:22.664286304 +0100 +++ gcc/ipa-split.c 2022-01-17 19:40:23.837234404 +0100 @@ -873,7 +873,6 @@ visit_bb (basic_block bb, basic_block re gimple *stmt = gsi_stmt (bsi); tree op; ssa_op_iter iter; - tree decl; if (is_gimple_debug (stmt)) continue; @@ -900,31 +899,45 @@ visit_bb (basic_block bb, basic_block re } /* Check builtins that prevent splitting. */ - if (gimple_code (stmt) == GIMPLE_CALL - && (decl = gimple_call_fndecl (stmt)) != NULL_TREE - && fndecl_built_in_p (decl, BUILT_IN_NORMAL)) - switch (DECL_FUNCTION_CODE (decl)) + if (gimple_code (stmt) == GIMPLE_CALL) + if (tree decl = gimple_call_fndecl (stmt)) { - /* FIXME: once we will allow passing non-parm values to split part, - we need to be sure to handle correct builtin_stack_save and - builtin_stack_restore. At the moment we are safe; there is no - way to store builtin_stack_save result in non-SSA variable - since all calls to those are compiler generated. */ - case BUILT_IN_APPLY: - case BUILT_IN_APPLY_ARGS: - case BUILT_IN_VA_START: - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, - "Cannot split: builtin_apply and va_start.\n"); - can_split = false; - break; - case BUILT_IN_EH_POINTER: - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "Cannot split: builtin_eh_pointer.\n"); - can_split = false; - break; - default: - break; + if (fndecl_built_in_p (decl, BUILT_IN_NORMAL)) + switch (DECL_FUNCTION_CODE (decl)) + { + /* FIXME: once we will allow passing non-parm values to + split part, we need to be sure to handle correct + builtin_stack_save and builtin_stack_restore. At the + moment we are safe; there is no way to store + builtin_stack_save result in non-SSA variable + since all calls to those are compiler generated. */ + case BUILT_IN_APPLY: + case BUILT_IN_APPLY_ARGS: + case BUILT_IN_VA_START: + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + "Cannot split: builtin_apply and va_start.\n"); + can_split = false; + break; + case BUILT_IN_EH_POINTER: + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Cannot split: builtin_eh_pointer.\n"); + can_split = false; + break; + default: + break; + } + + /* If there is a function call and that function has either the + warning or error attribute on it, don't split. */ + if (lookup_attribute ("warning", DECL_ATTRIBUTES (decl)) + || lookup_attribute ("error", DECL_ATTRIBUTES (decl))) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Cannot split: warning or error " + "attribute.\n"); + can_split = false; + } } FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF) --- gcc/testsuite/gcc.dg/tree-ssa/pr101941.c.jj 2022-01-17 19:37:01.609066831 +0100 +++ gcc/testsuite/gcc.dg/tree-ssa/pr101941.c 2022-01-17 19:37:01.609066831 +0100 @@ -0,0 +1,48 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fconserve-stack -fdump-tree-optimized" } */ +struct crypto_aes_ctx { + char key_dec[128]; +}; + +int rfc4106_set_hash_subkey_hash_subkey; + +void __write_overflow(void)__attribute__((__error__(""))); +void __write_overflow1(void); +void aes_encrypt(void*); + +void fortify_panic(const char*) __attribute__((__noreturn__)) ; + +char *rfc4106_set_hash_subkey(struct crypto_aes_ctx *ctx) { + void *a = &ctx->key_dec[0]; + unsigned p_size = __builtin_object_size(a, 0); +#ifdef __OPTIMIZE__ + if (p_size < 16) { + __write_overflow1(); + fortify_panic(__func__); + } + if (p_size < 32) { + __write_overflow(); + fortify_panic(__func__); + } +#endif + aes_encrypt(ctx); + return ctx->key_dec; +} + +char *(*gg)(struct crypto_aes_ctx *) = rfc4106_set_hash_subkey; + +void a(void) +{ + struct crypto_aes_ctx ctx; + rfc4106_set_hash_subkey(&ctx); +} +void b(void) +{ + struct crypto_aes_ctx ctx; + ctx.key_dec[0] = 0; + rfc4106_set_hash_subkey(&ctx); +} + +/* This testcase should still split out one of the above basic blocks dealing + with __write_overflow. */ +/* { dg-final { scan-tree-dump-times "Function rfc4106_set_hash_subkey.part" 1 "optimized" } } */ --- gcc/testsuite/gcc.c-torture/compile/pr101941.c.jj 2022-01-17 19:37:01.609066831 +0100 +++ gcc/testsuite/gcc.c-torture/compile/pr101941.c 2022-01-17 19:37:01.609066831 +0100 @@ -0,0 +1,43 @@ +/* { dg-additional-options "-fconserve-stack" } */ +struct crypto_aes_ctx { + char key_dec[128]; +}; + +int rfc4106_set_hash_subkey_hash_subkey; + +void __write_overflow(void)__attribute__((__error__(""))); +void __write_overflow1(void); +void aes_encrypt(void*); + +void fortify_panic(const char*) __attribute__((__noreturn__)) ; + +char *rfc4106_set_hash_subkey(struct crypto_aes_ctx *ctx) { + void *a = &ctx->key_dec[0]; + unsigned p_size = __builtin_object_size(a, 0); +#ifdef __OPTIMIZE__ + if (p_size < 16) { + __write_overflow1(); + fortify_panic(__func__); + } + if (p_size < 32) { + __write_overflow(); + fortify_panic(__func__); + } +#endif + aes_encrypt(ctx); + return ctx->key_dec; +} + +char *(*gg)(struct crypto_aes_ctx *) = rfc4106_set_hash_subkey; + +void a(void) +{ + struct crypto_aes_ctx ctx; + rfc4106_set_hash_subkey(&ctx); +} +void b(void) +{ + struct crypto_aes_ctx ctx; + ctx.key_dec[0] = 0; + rfc4106_set_hash_subkey(&ctx); +} Jakub