diff options
Diffstat (limited to 'gcc/config/aarch64/aarch64-sve-builtins.cc')
-rw-r--r-- | gcc/config/aarch64/aarch64-sve-builtins.cc | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc index 3651926..e394c9a 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins.cc @@ -47,6 +47,8 @@ #include "langhooks.h" #include "stringpool.h" #include "attribs.h" +#include "value-range.h" +#include "tree-ssanames.h" #include "aarch64-sve-builtins.h" #include "aarch64-sve-builtins-base.h" #include "aarch64-sve-builtins-sve2.h" @@ -3664,7 +3666,8 @@ gimple_folder::fold_pfalse () /* Convert the lhs and all non-boolean vector-type operands to TYPE. Pass the converted variables to the callback FP, and finally convert the result back to the original type. Add the necessary conversion statements. - Return the new call. */ + Return the new call. Note the tree argument to the callback FP, can only + be set once; it will always be a SSA_NAME. */ gimple * gimple_folder::convert_and_fold (tree type, gimple *(*fp) (gimple_folder &, @@ -3675,7 +3678,7 @@ gimple_folder::convert_and_fold (tree type, tree old_ty = TREE_TYPE (lhs); gimple_seq stmts = NULL; bool convert_lhs_p = !useless_type_conversion_p (type, old_ty); - tree lhs_conv = convert_lhs_p ? create_tmp_var (type) : lhs; + tree lhs_conv = convert_lhs_p ? make_ssa_name (type) : lhs; unsigned int num_args = gimple_call_num_args (call); auto_vec<tree, 16> args_conv; args_conv.safe_grow (num_args); @@ -4001,7 +4004,8 @@ rtx function_expander::get_reg_target () { machine_mode target_mode = result_mode (); - if (!possible_target || GET_MODE (possible_target) != target_mode) + if (!possible_target + || !register_operand (possible_target, target_mode)) possible_target = gen_reg_rtx (target_mode); return possible_target; } @@ -4589,7 +4593,27 @@ function_expander::expand () gcc_assert (args.last ()->mode == DImode); emit_move_insn (gen_rtx_REG (DImode, FPM_REGNUM), args.last ()); } - return base->expand (*this); + rtx result = base->expand (*this); + if (function_returns_void_p ()) + gcc_assert (result == const0_rtx); + else + { + auto expected_mode = result_mode (); + if (GET_MODE_CLASS (expected_mode) == MODE_INT) + /* Scalar integer constants don't store a mode. + + It's OK for a variable result to have a different mode from the + function return type. In particular, some functions that return int + expand into instructions that have a DImode result, with all 64 bits + of the DImode being well-defined (usually zero). */ + gcc_assert (CONST_SCALAR_INT_P (result) + || GET_MODE_CLASS (GET_MODE (result)) == MODE_INT); + else + /* In other cases, the return value should have the same mode + as the return type. */ + gcc_assert (GET_MODE (result) == expected_mode); + } + return result; } /* Return a structure type that contains a single field of type FIELD_TYPE. |