diff options
Diffstat (limited to 'gcc/internal-fn.cc')
-rw-r--r-- | gcc/internal-fn.cc | 151 |
1 files changed, 122 insertions, 29 deletions
diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index ed6ef0e..bf2fac8 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -3442,25 +3442,23 @@ expand_DEFERRED_INIT (internal_fn, gcall *stmt) } /* Expand the IFN_ACCESS_WITH_SIZE function: - ACCESS_WITH_SIZE (REF_TO_OBJ, REF_TO_SIZE, CLASS_OF_SIZE, - TYPE_OF_SIZE, ACCESS_MODE) + ACCESS_WITH_SIZE (REF_TO_OBJ, REF_TO_SIZE, + TYPE_OF_SIZE + ACCESS_MODE, TYPE_SIZE_UNIT for element) which returns the REF_TO_OBJ same as the 1st argument; 1st argument REF_TO_OBJ: The reference to the object; 2nd argument REF_TO_SIZE: The reference to the size of the object, - 3rd argument CLASS_OF_SIZE: The size referenced by the REF_TO_SIZE represents - 0: the number of bytes. - 1: the number of the elements of the object type; - 4th argument TYPE_OF_SIZE: A constant 0 with its TYPE being the same as the TYPE - of the object referenced by REF_TO_SIZE - 5th argument ACCESS_MODE: - -1: Unknown access semantics - 0: none - 1: read_only - 2: write_only - 3: read_write - 6th argument: A constant 0 with the pointer TYPE to the original flexible - array type. + 3rd argument TYPE_OF_SIZE + ACCESS_MODE: An integer constant with a pointer + TYPE. + The pointee TYPE of the pointer TYPE is the TYPE of the object referenced + by REF_TO_SIZE. + The integer constant value represents the ACCESS_MODE: + 0: none + 1: read_only + 2: write_only + 3: read_write + + 4th argument: The TYPE_SIZE_UNIT of the element TYPE of the array. Both the return type and the type of the first argument of this function have been converted from the incomplete array type to @@ -3654,8 +3652,8 @@ expand_scatter_store_optab_fn (internal_fn, gcall *stmt, direct_optab optab) internal_fn ifn = gimple_call_internal_fn (stmt); int rhs_index = internal_fn_stored_value_index (ifn); tree base = gimple_call_arg (stmt, 0); - tree offset = gimple_call_arg (stmt, 1); - tree scale = gimple_call_arg (stmt, 2); + tree offset = gimple_call_arg (stmt, internal_fn_offset_index (ifn)); + tree scale = gimple_call_arg (stmt, internal_fn_scale_index (ifn)); tree rhs = gimple_call_arg (stmt, rhs_index); rtx base_rtx = expand_normal (base); @@ -3680,12 +3678,12 @@ expand_scatter_store_optab_fn (internal_fn, gcall *stmt, direct_optab optab) /* Expand {MASK_,}GATHER_LOAD call CALL using optab OPTAB. */ static void -expand_gather_load_optab_fn (internal_fn, gcall *stmt, direct_optab optab) +expand_gather_load_optab_fn (internal_fn ifn, gcall *stmt, direct_optab optab) { tree lhs = gimple_call_lhs (stmt); tree base = gimple_call_arg (stmt, 0); - tree offset = gimple_call_arg (stmt, 1); - tree scale = gimple_call_arg (stmt, 2); + tree offset = gimple_call_arg (stmt, internal_fn_offset_index (ifn)); + tree scale = gimple_call_arg (stmt, internal_fn_scale_index (ifn)); rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE); rtx base_rtx = expand_normal (base); @@ -4550,6 +4548,33 @@ widening_fn_p (code_helper code) } } +/* Return true if this CODE describes an internal_fn that returns a vector with + elements twice as wide as the element size of the input vectors and operates + on even/odd parts of the input. */ + +bool +widening_evenodd_fn_p (code_helper code) +{ + if (!code.is_fn_code ()) + return false; + + if (!internal_fn_p ((combined_fn) code)) + return false; + + internal_fn fn = as_internal_fn ((combined_fn) code); + switch (fn) + { + #define DEF_INTERNAL_WIDENING_OPTAB_FN(NAME, F, S, SO, UO, T) \ + case IFN_##NAME##_EVEN: \ + case IFN_##NAME##_ODD: \ + return true; + #include "internal-fn.def" + + default: + return false; + } +} + /* Return true if IFN_SET_EDOM is supported. */ bool @@ -4942,11 +4967,13 @@ internal_fn_len_index (internal_fn fn) return 2; case IFN_MASK_LEN_SCATTER_STORE: + return 6; + case IFN_MASK_LEN_STRIDED_LOAD: return 5; case IFN_MASK_LEN_GATHER_LOAD: - return 6; + return 7; case IFN_COND_LEN_FMA: case IFN_COND_LEN_FMS: @@ -5050,7 +5077,7 @@ internal_fn_else_index (internal_fn fn) case IFN_MASK_GATHER_LOAD: case IFN_MASK_LEN_GATHER_LOAD: - return 5; + return 6; default: return -1; @@ -5085,7 +5112,7 @@ internal_fn_mask_index (internal_fn fn) case IFN_MASK_SCATTER_STORE: case IFN_MASK_LEN_GATHER_LOAD: case IFN_MASK_LEN_SCATTER_STORE: - return 4; + return 5; case IFN_VCOND_MASK: case IFN_VCOND_MASK_LEN: @@ -5110,10 +5137,11 @@ internal_fn_stored_value_index (internal_fn fn) case IFN_MASK_STORE: case IFN_MASK_STORE_LANES: + return 3; case IFN_SCATTER_STORE: case IFN_MASK_SCATTER_STORE: case IFN_MASK_LEN_SCATTER_STORE: - return 3; + return 4; case IFN_LEN_STORE: return 4; @@ -5127,6 +5155,75 @@ internal_fn_stored_value_index (internal_fn fn) } } +/* If FN has an alias pointer return its index, otherwise return -1. */ + +int +internal_fn_alias_ptr_index (internal_fn fn) +{ + switch (fn) + { + case IFN_MASK_LOAD: + case IFN_MASK_LEN_LOAD: + case IFN_GATHER_LOAD: + case IFN_MASK_GATHER_LOAD: + case IFN_MASK_LEN_GATHER_LOAD: + case IFN_SCATTER_STORE: + case IFN_MASK_SCATTER_STORE: + case IFN_MASK_LEN_SCATTER_STORE: + return 1; + + default: + return -1; + } +} + +/* If FN is a gather/scatter return the index of its offset argument, + otherwise return -1. */ + +int +internal_fn_offset_index (internal_fn fn) +{ + if (!internal_gather_scatter_fn_p (fn)) + return -1; + + switch (fn) + { + case IFN_GATHER_LOAD: + case IFN_MASK_GATHER_LOAD: + case IFN_MASK_LEN_GATHER_LOAD: + case IFN_SCATTER_STORE: + case IFN_MASK_SCATTER_STORE: + case IFN_MASK_LEN_SCATTER_STORE: + return 2; + + default: + return -1; + } +} + +/* If FN is a gather/scatter return the index of its scale argument, + otherwise return -1. */ + +int +internal_fn_scale_index (internal_fn fn) +{ + if (!internal_gather_scatter_fn_p (fn)) + return -1; + + switch (fn) + { + case IFN_GATHER_LOAD: + case IFN_MASK_GATHER_LOAD: + case IFN_MASK_LEN_GATHER_LOAD: + case IFN_SCATTER_STORE: + case IFN_MASK_SCATTER_STORE: + case IFN_MASK_LEN_SCATTER_STORE: + return 3; + + default: + return -1; + } +} /* Store all supported else values for the optab referred to by ICODE in ELSE_VALS. The index of the else operand must be specified in @@ -5205,13 +5302,9 @@ internal_gather_scatter_fn_supported_p (internal_fn ifn, tree vector_type, && insn_operand_matches (icode, 2 + output_ops, GEN_INT (unsigned_p)) && insn_operand_matches (icode, 3 + output_ops, GEN_INT (scale)); - /* For gather the optab's operand indices do not match the IFN's because - the latter does not have the extension operand (operand 3). It is - implicitly added during expansion so we use the IFN's else index + 1. - */ if (ok && elsvals) get_supported_else_vals - (icode, internal_fn_else_index (IFN_MASK_GATHER_LOAD) + 1, *elsvals); + (icode, internal_fn_else_index (IFN_MASK_GATHER_LOAD), *elsvals); return ok; } |