Richard Biener <richard.guent...@gmail.com> writes: > On Mon, Nov 20, 2017 at 12:31 PM, Bin.Cheng <amker.ch...@gmail.com> wrote: >> On Fri, Nov 17, 2017 at 3:03 PM, Richard Sandiford >> <richard.sandif...@linaro.org> wrote: >>> ivopts previously treated pointer arguments to internal functions >>> like IFN_MASK_LOAD and IFN_MASK_STORE as normal gimple values. >>> This patch makes it treat them as addresses instead. This makes >>> a significant difference to the code quality for SVE loops, >>> since we can then use loads and stores with scaled indices. >> Thanks for working on this. This can be extended to other internal >> functions which eventually >> are expanded into memory references. I believe (at least) both x86 >> and AArch64 has such >> requirement. > > In addition to Bins comments I only have a single one (the rest of the > middle-end > changes look OK). The alias type of MEM_REFs and TARGET_MEM_REFs > in ADDR_EXPR context is meaningless so you don't need to jump through hoops > to get at it or preserve it in any way, likewise for CLIQUE/BASE if it > were present.
Ah, OK. > Maybe you can simplify code with this. In the end it didn't really simplify the code, since internal-fn.c uses the address to build a (TARGET_)MEM_REF, and the alias information of that ref needs to be correct, since it gets carried across to the MEM rtx. But it does mean that the alias_ptr_type check in the previous: if (TREE_CODE (mem) == TARGET_MEM_REF && types_compatible_p (TREE_TYPE (mem), type) && alias_ptr_type == TREE_TYPE (TMR_OFFSET (mem)) && integer_zerop (TMR_OFFSET (mem))) return mem; made no sense: we should simply replace the TMR_OFFSET if it has the wrong type. > As you're introducing &TARGET_MEM_REF as a valid construct (it weren't > before) you'll run into missing / misguided foldings eventually. So > be prepared to fix up fallout. OK :-) I haven't hit any new places yet, but like you say, I'll be on the lookout. Is the version below OK? Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu. Richard 2018-01-09 Richard Sandiford <richard.sandif...@linaro.org> Alan Hayward <alan.hayw...@arm.com> David Sherwood <david.sherw...@arm.com> gcc/ * expr.c (expand_expr_addr_expr_1): Handle ADDR_EXPRs of TARGET_MEM_REFs. * gimple-expr.h (is_gimple_addressable: Likewise. * gimple-expr.c (is_gimple_address): Likewise. * internal-fn.c (expand_call_mem_ref): New function. (expand_mask_load_optab_fn): Use it. (expand_mask_store_optab_fn): Likewise. Index: gcc/expr.c =================================================================== --- gcc/expr.c 2018-01-09 15:13:32.603106251 +0000 +++ gcc/expr.c 2018-01-09 15:13:32.784098242 +0000 @@ -7885,6 +7885,9 @@ expand_expr_addr_expr_1 (tree exp, rtx t return expand_expr (tem, target, tmode, modifier); } + case TARGET_MEM_REF: + return addr_for_mem_ref (exp, as, true); + case CONST_DECL: /* Expand the initializer like constants above. */ result = XEXP (expand_expr_constant (DECL_INITIAL (exp), Index: gcc/gimple-expr.h =================================================================== --- gcc/gimple-expr.h 2018-01-09 15:13:32.603106251 +0000 +++ gcc/gimple-expr.h 2018-01-09 15:13:32.785098198 +0000 @@ -119,6 +119,7 @@ virtual_operand_p (tree op) is_gimple_addressable (tree t) { return (is_gimple_id (t) || handled_component_p (t) + || TREE_CODE (t) == TARGET_MEM_REF || TREE_CODE (t) == MEM_REF); } Index: gcc/gimple-expr.c =================================================================== --- gcc/gimple-expr.c 2018-01-09 15:13:32.603106251 +0000 +++ gcc/gimple-expr.c 2018-01-09 15:13:32.784098242 +0000 @@ -631,7 +631,9 @@ is_gimple_address (const_tree t) op = TREE_OPERAND (op, 0); } - if (CONSTANT_CLASS_P (op) || TREE_CODE (op) == MEM_REF) + if (CONSTANT_CLASS_P (op) + || TREE_CODE (op) == TARGET_MEM_REF + || TREE_CODE (op) == MEM_REF) return true; switch (TREE_CODE (op)) Index: gcc/internal-fn.c =================================================================== --- gcc/internal-fn.c 2018-01-09 15:13:32.603106251 +0000 +++ gcc/internal-fn.c 2018-01-09 15:13:32.785098198 +0000 @@ -2412,15 +2412,53 @@ expand_LOOP_DIST_ALIAS (internal_fn, gca gcc_unreachable (); } +/* Return a memory reference of type TYPE for argument INDEX of STMT. + Use argument INDEX + 1 to derive the second (TBAA) operand. */ + +static tree +expand_call_mem_ref (tree type, gcall *stmt, int index) +{ + tree addr = gimple_call_arg (stmt, index); + tree alias_ptr_type = TREE_TYPE (gimple_call_arg (stmt, index + 1)); + unsigned int align = tree_to_shwi (gimple_call_arg (stmt, index + 1)); + if (TYPE_ALIGN (type) != align) + type = build_aligned_type (type, align); + + tree tmp = addr; + if (TREE_CODE (tmp) == SSA_NAME) + { + gimple *def = SSA_NAME_DEF_STMT (tmp); + if (gimple_assign_single_p (def)) + tmp = gimple_assign_rhs1 (def); + } + + if (TREE_CODE (tmp) == ADDR_EXPR) + { + tree mem = TREE_OPERAND (tmp, 0); + if (TREE_CODE (mem) == TARGET_MEM_REF + && types_compatible_p (TREE_TYPE (mem), type) + && integer_zerop (TMR_OFFSET (mem))) + { + if (alias_ptr_type != TREE_TYPE (TMR_OFFSET (mem))) + { + mem = copy_node (mem); + TMR_OFFSET (mem) = build_int_cst (alias_ptr_type, 0); + } + return mem; + } + } + + return fold_build2 (MEM_REF, type, addr, build_int_cst (alias_ptr_type, 0)); +} + /* Expand MASK_LOAD{,_LANES} call STMT using optab OPTAB. */ static void expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab) { struct expand_operand ops[3]; - tree type, lhs, rhs, maskt, ptr; + tree type, lhs, rhs, maskt; rtx mem, target, mask; - unsigned align; insn_code icode; maskt = gimple_call_arg (stmt, 2); @@ -2428,11 +2466,7 @@ expand_mask_load_optab_fn (internal_fn, if (lhs == NULL_TREE) return; type = TREE_TYPE (lhs); - ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0); - align = tree_to_shwi (gimple_call_arg (stmt, 1)); - if (TYPE_ALIGN (type) != align) - type = build_aligned_type (type, align); - rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr); + rhs = expand_call_mem_ref (type, stmt, 0); if (optab == vec_mask_load_lanes_optab) icode = get_multi_vector_move (type, optab); @@ -2458,19 +2492,14 @@ #define expand_mask_load_lanes_optab_fn expand_mask_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab) { struct expand_operand ops[3]; - tree type, lhs, rhs, maskt, ptr; + tree type, lhs, rhs, maskt; rtx mem, reg, mask; - unsigned align; insn_code icode; maskt = gimple_call_arg (stmt, 2); rhs = gimple_call_arg (stmt, 3); type = TREE_TYPE (rhs); - ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0); - align = tree_to_shwi (gimple_call_arg (stmt, 1)); - if (TYPE_ALIGN (type) != align) - type = build_aligned_type (type, align); - lhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr); + lhs = expand_call_mem_ref (type, stmt, 0); if (optab == vec_mask_store_lanes_optab) icode = get_multi_vector_move (type, optab);