diff options
author | Richard Biener <rguenther@suse.de> | 2021-11-03 11:10:19 +0100 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2021-11-03 11:12:46 +0100 |
commit | c081d0a3b0291297f04a05c833d2ffa8de3a7a1a (patch) | |
tree | db558f5c00a7af1a531c327e355bb0cf8cf18566 /gcc | |
parent | ea2ab805acdd023f1c43302723c1fa1349be9cca (diff) | |
download | gcc-c081d0a3b0291297f04a05c833d2ffa8de3a7a1a.zip gcc-c081d0a3b0291297f04a05c833d2ffa8de3a7a1a.tar.gz gcc-c081d0a3b0291297f04a05c833d2ffa8de3a7a1a.tar.bz2 |
middle-end/103033 - drop native_interpret_expr with .DEFERRED_INIT expansion
This drops the use of native_interpret_expr which can fail even though
can_native_interpret_expr_p returns true in favor of simply folding
the VIEW_CONVERT_EXPR punning.
2021-11-03 Richard Biener <rguenther@suse.de>
PR middle-end/103033
* internal-fn.c (expand_DEFERRED_INIT): Elide the
native_interpret_expr path in favor of folding the
VIEW_CONVERT_EXPR generated when punning the RHS.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/internal-fn.c | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c index fd6cb09..0cba954 100644 --- a/gcc/internal-fn.c +++ b/gcc/internal-fn.c @@ -3070,9 +3070,11 @@ expand_DEFERRED_INIT (internal_fn, gcall *stmt) } else { - /* If this variable is in a register use expand_assignment. */ + /* If this variable is in a register use expand_assignment. + For boolean scalars force zero-init. */ tree init; - if (tree_fits_uhwi_p (var_size) + if (TREE_CODE (TREE_TYPE (lhs)) != BOOLEAN_TYPE + && tree_fits_uhwi_p (var_size) && (init_type == AUTO_INIT_PATTERN || !is_gimple_reg_type (var_type)) && int_mode_for_size (tree_to_uhwi (var_size) * BITS_PER_UNIT, @@ -3082,21 +3084,16 @@ expand_DEFERRED_INIT (internal_fn, gcall *stmt) unsigned char *buf = (unsigned char *) xmalloc (total_bytes); memset (buf, (init_type == AUTO_INIT_PATTERN ? INIT_PATTERN_VALUE : 0), total_bytes); - if (can_native_interpret_type_p (var_type)) - init = native_interpret_expr (var_type, buf, total_bytes); + tree itype = build_nonstandard_integer_type + (total_bytes * BITS_PER_UNIT, 1); + wide_int w = wi::from_buffer (buf, total_bytes); + init = wide_int_to_tree (itype, w); + /* Pun the LHS to make sure its type has constant size + unless it is an SSA name where that's already known. */ + if (TREE_CODE (lhs) != SSA_NAME) + lhs = build1 (VIEW_CONVERT_EXPR, itype, lhs); else - { - tree itype = build_nonstandard_integer_type - (total_bytes * BITS_PER_UNIT, 1); - wide_int w = wi::from_buffer (buf, total_bytes); - init = wide_int_to_tree (itype, w); - /* Pun the LHS to make sure its type has constant size - unless it is an SSA name where that's already known. */ - if (TREE_CODE (lhs) != SSA_NAME) - lhs = build1 (VIEW_CONVERT_EXPR, itype, lhs); - else - init = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lhs), init); - } + init = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lhs), init); } else /* Use zero-init also for variable-length sizes. */ |