aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2021-11-03 11:10:19 +0100
committerRichard Biener <rguenther@suse.de>2021-11-03 11:12:46 +0100
commitc081d0a3b0291297f04a05c833d2ffa8de3a7a1a (patch)
treedb558f5c00a7af1a531c327e355bb0cf8cf18566 /gcc
parentea2ab805acdd023f1c43302723c1fa1349be9cca (diff)
downloadgcc-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.c29
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. */