From 14b7950f126f84fa585e3a057940ff10d4c5b3f8 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 22 Aug 2019 23:09:26 +0000 Subject: PR middle-end/91490 - bogus argument missing terminating nul warning on strlen of a flexible array member gcc/c-family/ChangeLog: PR middle-end/91490 * c-common.c (braced_list_to_string): Add argument and overload. Handle flexible length arrays and unions. gcc/testsuite/ChangeLog: PR middle-end/91490 * c-c++-common/Warray-bounds-7.c: New test. * gcc.dg/Warray-bounds-39.c: Expect either -Warray-bounds or -Wstringop-overflow. * gcc.dg/strlenopt-78.c: New test. gcc/ChangeLog: PR middle-end/91490 * builtins.c (c_strlen): Rename argument and introduce new local. Set no-warning bit on original argument. * expr.c (string_constant): Pass argument type to fold_ctor_reference. Fold empty and zero constructors into empty strings. * gimple-fold.c (fold_nonarray_ctor_reference): Return a STRING_CST for missing initializers. * tree.c (build_string_literal): Handle optional argument. * tree.h (build_string_literal): Add defaulted argument. * gimple-ssa-warn-restrict.c (maybe_diag_access_bounds): Check no-warning bit on original expression. From-SVN: r274837 --- gcc/expr.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 15 deletions(-) (limited to 'gcc/expr.c') diff --git a/gcc/expr.c b/gcc/expr.c index 9297928..5ca0e20 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -11402,6 +11402,15 @@ is_aligning_offset (const_tree offset, const_tree exp) tree string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl) { + tree dummy = NULL_TREE;; + if (!mem_size) + mem_size = &dummy; + + /* Store the type of the original expression before conversions + via NOP_EXPR or POINTER_PLUS_EXPR to other types have been + removed. */ + tree argtype = TREE_TYPE (arg); + tree array; STRIP_NOPS (arg); @@ -11464,7 +11473,7 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl) && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == ARRAY_TYPE && !(decl && !*decl) && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl)) - && mem_size && tree_fits_uhwi_p (*mem_size) + && tree_fits_uhwi_p (*mem_size) && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl)))) return NULL_TREE; @@ -11496,7 +11505,7 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl) && TREE_CODE (TREE_TYPE (TREE_TYPE (rhs1))) == ARRAY_TYPE && !(decl && !*decl) && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl)) - && mem_size && tree_fits_uhwi_p (*mem_size) + && tree_fits_uhwi_p (*mem_size) && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl)))) return NULL_TREE; @@ -11530,8 +11539,7 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl) if (TREE_CODE (array) == STRING_CST) { *ptr_offset = fold_convert (sizetype, offset); - if (mem_size) - *mem_size = TYPE_SIZE_UNIT (TREE_TYPE (array)); + *mem_size = TYPE_SIZE_UNIT (TREE_TYPE (array)); if (decl) *decl = NULL_TREE; gcc_checking_assert (tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (array))) @@ -11561,7 +11569,7 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl) base_off = wioff.to_uhwi (); unsigned HOST_WIDE_INT fieldoff = 0; - init = fold_ctor_reference (NULL_TREE, init, base_off, 0, array, + init = fold_ctor_reference (TREE_TYPE (arg), init, base_off, 0, array, &fieldoff); HOST_WIDE_INT cstoff; if (!base_off.is_constant (&cstoff)) @@ -11580,17 +11588,11 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl) *ptr_offset = offset; - tree eltype = TREE_TYPE (init); - tree initsize = TYPE_SIZE_UNIT (eltype); - if (mem_size) - *mem_size = initsize; - - if (decl) - *decl = array; + tree inittype = TREE_TYPE (init); if (TREE_CODE (init) == INTEGER_CST && (TREE_CODE (TREE_TYPE (array)) == INTEGER_TYPE - || TYPE_MAIN_VARIANT (eltype) == char_type_node)) + || TYPE_MAIN_VARIANT (inittype) == char_type_node)) { /* For a reference to (address of) a single constant character, store the native representation of the character in CHARBUF. @@ -11602,17 +11604,49 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl) int len = native_encode_expr (init, charbuf, sizeof charbuf, 0); if (len > 0) { - /* Construct a string literal with elements of ELTYPE and + /* Construct a string literal with elements of INITTYPE and the representation above. Then strip the ADDR_EXPR (ARRAY_REF (...)) around the STRING_CST. */ - init = build_string_literal (len, (char *)charbuf, eltype); + init = build_string_literal (len, (char *)charbuf, inittype); init = TREE_OPERAND (TREE_OPERAND (init, 0), 0); } } + tree initsize = TYPE_SIZE_UNIT (inittype); + + if (TREE_CODE (init) == CONSTRUCTOR && initializer_zerop (init)) + { + /* Fold an empty/zero constructor for an implicitly initialized + object or subobject into the empty string. */ + + /* Determine the character type from that of the original + expression. */ + tree chartype = argtype; + if (POINTER_TYPE_P (chartype)) + chartype = TREE_TYPE (chartype); + while (TREE_CODE (chartype) == ARRAY_TYPE) + chartype = TREE_TYPE (chartype); + /* Convert a char array to an empty STRING_CST having an array + of the expected type. */ + if (!initsize) + initsize = integer_zero_node; + + unsigned HOST_WIDE_INT size = tree_to_uhwi (initsize); + init = build_string_literal (size ? 1 : 0, "", chartype, size); + init = TREE_OPERAND (init, 0); + init = TREE_OPERAND (init, 0); + + *ptr_offset = integer_zero_node; + } + + if (decl) + *decl = array; + if (TREE_CODE (init) != STRING_CST) return NULL_TREE; + *mem_size = initsize; + gcc_checking_assert (tree_to_shwi (initsize) >= TREE_STRING_LENGTH (init)); return init; -- cgit v1.1 From 70cdb21e579191fe9f0f1d45e328908e59c0179e Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Wed, 28 Aug 2019 10:18:23 +0000 Subject: expr.c (expand_assignment): Handle misaligned DECLs. 2019-09-28 Bernd Edlinger Richard Biener * expr.c (expand_assignment): Handle misaligned DECLs. (expand_expr_real_1): Handle FUNCTION_DECL as unaligned. * function.c (assign_parm_adjust_stack_rtl): Check movmisalign optab too. (assign_parm_setup_stack): Allocate properly aligned stack slots. * varasm.c (build_constant_desc): Align constants of misaligned types. * config/arm/predicates.md (aligned_operand): New predicate. * config/arm/arm.md (movdi, movsi, movhi, movhf, movsf, movdf): Use aligned_operand to check restrictions on memory addresses. * config/arm/neon.md (movti, mov, mov): Likewise. * config/arm/vec-common.md (mov): Likewise. Co-Authored-By: Richard Biener From-SVN: r274986 --- gcc/expr.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'gcc/expr.c') diff --git a/gcc/expr.c b/gcc/expr.c index 5ca0e20..022b571 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -5001,9 +5001,10 @@ expand_assignment (tree to, tree from, bool nontemporal) /* Handle misaligned stores. */ mode = TYPE_MODE (TREE_TYPE (to)); if ((TREE_CODE (to) == MEM_REF - || TREE_CODE (to) == TARGET_MEM_REF) + || TREE_CODE (to) == TARGET_MEM_REF + || DECL_P (to)) && mode != BLKmode - && !mem_ref_refers_to_non_mem_p (to) + && (DECL_P (to) || !mem_ref_refers_to_non_mem_p (to)) && ((align = get_object_alignment (to)) < GET_MODE_ALIGNMENT (mode)) && (((icode = optab_handler (movmisalign_optab, mode)) @@ -10795,6 +10796,14 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, MEM_VOLATILE_P (op0) = 1; } + if (MEM_P (op0) && TREE_CODE (tem) == FUNCTION_DECL) + { + if (op0 == orig_op0) + op0 = copy_rtx (op0); + + set_mem_align (op0, BITS_PER_UNIT); + } + /* In cases where an aligned union has an unaligned object as a field, we might be extracting a BLKmode value from an integer-mode (e.g., SImode) object. Handle this case -- cgit v1.1 From b82c2e6fce74a6283fb3efd195d62aa6a88ef561 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Mon, 2 Sep 2019 14:26:26 +0000 Subject: re PR middle-end/91605 (ICE in ix86_avx256_split_vector_move_misalign, at config/i386/i386-expand.c:489 since r274986) 2019-09-02 Bernd Edlinger PR middle-end/91605 * expr.c (addr_expr_of_non_mem_decl_p_1): Refactor into... (non_mem_decl_p): ...this. (mem_ref_refers_to_non_mem_p): Handle DECL_P as well ase MEM_REF. (expand_assignment): Call mem_ref_referes_to_non_mem_p unconditionally as before. testsuite: 2019-09-02 Bernd Edlinger PR middle-end/91605 * g++.target/i386/pr91605.C: New test. From-SVN: r275320 --- gcc/expr.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) (limited to 'gcc/expr.c') diff --git a/gcc/expr.c b/gcc/expr.c index 022b571..3c3f15a 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -4942,37 +4942,46 @@ get_bit_range (poly_uint64_pod *bitstart, poly_uint64_pod *bitend, tree exp, *bitend = *bitstart + tree_to_poly_uint64 (DECL_SIZE (repr)) - 1; } -/* Returns true if ADDR is an ADDR_EXPR of a DECL that does not reside - in memory and has non-BLKmode. DECL_RTL must not be a MEM; if - DECL_RTL was not set yet, return NORTL. */ +/* Returns true if BASE is a DECL that does not reside in memory and + has non-BLKmode. DECL_RTL must not be a MEM; if + DECL_RTL was not set yet, return false. */ static inline bool -addr_expr_of_non_mem_decl_p_1 (tree addr, bool nortl) +non_mem_decl_p (tree base) { - if (TREE_CODE (addr) != ADDR_EXPR) - return false; - - tree base = TREE_OPERAND (addr, 0); - if (!DECL_P (base) || TREE_ADDRESSABLE (base) || DECL_MODE (base) == BLKmode) return false; if (!DECL_RTL_SET_P (base)) - return nortl; + return false; return (!MEM_P (DECL_RTL (base))); } -/* Returns true if the MEM_REF REF refers to an object that does not +/* Returns true if REF refers to an object that does not reside in memory and has non-BLKmode. */ static inline bool mem_ref_refers_to_non_mem_p (tree ref) { - tree base = TREE_OPERAND (ref, 0); - return addr_expr_of_non_mem_decl_p_1 (base, false); + tree base; + + if (TREE_CODE (ref) == MEM_REF + || TREE_CODE (ref) == TARGET_MEM_REF) + { + tree addr = TREE_OPERAND (ref, 0); + + if (TREE_CODE (addr) != ADDR_EXPR) + return false; + + base = TREE_OPERAND (addr, 0); + } + else + base = ref; + + return non_mem_decl_p (base); } /* Expand an assignment that stores the value of FROM into TO. If NONTEMPORAL @@ -5004,7 +5013,7 @@ expand_assignment (tree to, tree from, bool nontemporal) || TREE_CODE (to) == TARGET_MEM_REF || DECL_P (to)) && mode != BLKmode - && (DECL_P (to) || !mem_ref_refers_to_non_mem_p (to)) + && !mem_ref_refers_to_non_mem_p (to) && ((align = get_object_alignment (to)) < GET_MODE_ALIGNMENT (mode)) && (((icode = optab_handler (movmisalign_optab, mode)) -- cgit v1.1 From 934392185369af22fee845e4edd92c420b8c248b Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Tue, 3 Sep 2019 14:37:41 +0000 Subject: re PR middle-end/91603 (Unaligned access in expand_assignment) 2019-09-03 Bernd Edlinger PR middle-end/91603 PR middle-end/91612 PR middle-end/91613 * expr.c (expand_expr_real_1): Handle unaligned decl_rtl and SSA_NAME referring to CONSTANT_P correctly. testsuite: 2019-09-03 Bernd Edlinger PR middle-end/91603 * testsuite/gcc.target/arm/pr91603.c: New test. From-SVN: r275342 --- gcc/expr.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) (limited to 'gcc/expr.c') diff --git a/gcc/expr.c b/gcc/expr.c index 3c3f15a..0c96551 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -10062,6 +10062,42 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, { if (exp && MEM_P (temp) && REG_P (XEXP (temp, 0))) mark_reg_pointer (XEXP (temp, 0), DECL_ALIGN (exp)); + } + else if (MEM_P (decl_rtl)) + temp = decl_rtl; + + if (temp != 0) + { + if (MEM_P (temp) + && modifier != EXPAND_WRITE + && modifier != EXPAND_MEMORY + && modifier != EXPAND_INITIALIZER + && modifier != EXPAND_CONST_ADDRESS + && modifier != EXPAND_SUM + && !inner_reference_p + && mode != BLKmode + && MEM_ALIGN (temp) < GET_MODE_ALIGNMENT (mode)) + { + enum insn_code icode; + + if ((icode = optab_handler (movmisalign_optab, mode)) + != CODE_FOR_nothing) + { + class expand_operand ops[2]; + + /* We've already validated the memory, and we're creating a + new pseudo destination. The predicates really can't fail, + nor can the generator. */ + create_output_operand (&ops[0], NULL_RTX, mode); + create_fixed_operand (&ops[1], temp); + expand_insn (icode, 2, ops); + temp = ops[0].value; + } + else if (targetm.slow_unaligned_access (mode, MEM_ALIGN (temp))) + temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode), + 0, unsignedp, NULL_RTX, + mode, mode, false, NULL); + } return temp; } @@ -10974,9 +11010,10 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, op0 = copy_rtx (op0); /* Don't set memory attributes if the base expression is - SSA_NAME that got expanded as a MEM. In that case, we should - just honor its original memory attributes. */ - if (TREE_CODE (tem) != SSA_NAME || !MEM_P (orig_op0)) + SSA_NAME that got expanded as a MEM or a CONSTANT. In that case, + we should just honor its original memory attributes. */ + if (!(TREE_CODE (tem) == SSA_NAME + && (MEM_P (orig_op0) || CONSTANT_P (orig_op0)))) set_mem_attributes (op0, exp, 0); if (REG_P (XEXP (op0, 0))) -- cgit v1.1 From 55e8f926f260342e0b89765a306a3027daeaa10e Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Thu, 5 Sep 2019 13:40:17 +0000 Subject: re PR target/91615 ([armeb] ICEs since r274986) 2019-09-05 Bernd Edlinger PR middle-end/91615 * expr.c (expand_expr_real_1): Handle misaligned TARGET_MEM_REF without movmisalign optab. From-SVN: r275409 --- gcc/expr.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'gcc/expr.c') diff --git a/gcc/expr.c b/gcc/expr.c index 0c96551..3f4c98c 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -10313,7 +10313,6 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, { addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)))); - enum insn_code icode; unsigned int align; op0 = addr_for_mem_ref (exp, as, true); @@ -10325,21 +10324,27 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, if (modifier != EXPAND_WRITE && modifier != EXPAND_MEMORY && mode != BLKmode - && align < GET_MODE_ALIGNMENT (mode) - /* If the target does not have special handling for unaligned - loads of mode then it can use regular moves for them. */ - && ((icode = optab_handler (movmisalign_optab, mode)) - != CODE_FOR_nothing)) + && align < GET_MODE_ALIGNMENT (mode)) { - class expand_operand ops[2]; + enum insn_code icode; - /* We've already validated the memory, and we're creating a - new pseudo destination. The predicates really can't fail, - nor can the generator. */ - create_output_operand (&ops[0], NULL_RTX, mode); - create_fixed_operand (&ops[1], temp); - expand_insn (icode, 2, ops); - temp = ops[0].value; + if ((icode = optab_handler (movmisalign_optab, mode)) + != CODE_FOR_nothing) + { + class expand_operand ops[2]; + + /* We've already validated the memory, and we're creating a + new pseudo destination. The predicates really can't fail, + nor can the generator. */ + create_output_operand (&ops[0], NULL_RTX, mode); + create_fixed_operand (&ops[1], temp); + expand_insn (icode, 2, ops); + temp = ops[0].value; + } + else if (targetm.slow_unaligned_access (mode, align)) + temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode), + 0, unsignedp, NULL_RTX, + mode, mode, false, NULL); } return temp; } -- cgit v1.1 From b3baefb205e22aef208192aaf02f7ab0fad7c025 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Mon, 9 Sep 2019 19:44:15 +0000 Subject: expmed.c (extract_bit_field): Update function comment regarding alt_rtl. 2019-09-09 Bernd Edlinger * expmed.c (extract_bit_field): Update function comment regarding alt_rtl. * expr.c (expand_expr_real): Update function comment regarding alt_rtl. (expand_misaligned_mem_ref): New helper function. (expand_expr_real_2): Use expand_misaligned_mem_ref. Remove duplicate assignment to "base" at case MEM_REF. Remove a shadowed variable "unsignedp" at case VCE. From-SVN: r275541 --- gcc/expr.c | 113 ++++++++++++++++++++++++------------------------------------- 1 file changed, 45 insertions(+), 68 deletions(-) (limited to 'gcc/expr.c') diff --git a/gcc/expr.c b/gcc/expr.c index 3f4c98c..2f2b53f 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -8261,6 +8261,8 @@ expand_constructor (tree exp, rtx target, enum expand_modifier modifier, DECL_RTL of the VAR_DECL. *ALT_RTL is also set if EXP is a COMPOUND_EXPR whose second argument is such a VAR_DECL, and so on recursively. + If the result can be stored at TARGET, and ALT_RTL is non-NULL, + then *ALT_RTL is set to TARGET (before legitimziation). If INNER_REFERENCE_P is true, we are expanding an inner reference. In this case, we don't adjust a returned MEM rtx that wouldn't be @@ -8398,6 +8400,40 @@ expand_cond_expr_using_cmove (tree treeop0 ATTRIBUTE_UNUSED, return NULL_RTX; } +/* A helper function for expand_expr_real_2 to be used with a + misaligned mem_ref TEMP. Assume an unsigned type if UNSIGNEDP + is nonzero, with alignment ALIGN in bits. + Store the value at TARGET if possible (if TARGET is nonzero). + Regardless of TARGET, we return the rtx for where the value is placed. + If the result can be stored at TARGET, and ALT_RTL is non-NULL, + then *ALT_RTL is set to TARGET (before legitimziation). */ + +static rtx +expand_misaligned_mem_ref (rtx temp, machine_mode mode, int unsignedp, + unsigned int align, rtx target, rtx *alt_rtl) +{ + enum insn_code icode; + + if ((icode = optab_handler (movmisalign_optab, mode)) + != CODE_FOR_nothing) + { + class expand_operand ops[2]; + + /* We've already validated the memory, and we're creating a + new pseudo destination. The predicates really can't fail, + nor can the generator. */ + create_output_operand (&ops[0], NULL_RTX, mode); + create_fixed_operand (&ops[1], temp); + expand_insn (icode, 2, ops); + temp = ops[0].value; + } + else if (targetm.slow_unaligned_access (mode, align)) + temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode), + 0, unsignedp, target, + mode, mode, false, alt_rtl); + return temp; +} + rtx expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, enum expand_modifier modifier) @@ -10077,27 +10113,8 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, && !inner_reference_p && mode != BLKmode && MEM_ALIGN (temp) < GET_MODE_ALIGNMENT (mode)) - { - enum insn_code icode; - - if ((icode = optab_handler (movmisalign_optab, mode)) - != CODE_FOR_nothing) - { - class expand_operand ops[2]; - - /* We've already validated the memory, and we're creating a - new pseudo destination. The predicates really can't fail, - nor can the generator. */ - create_output_operand (&ops[0], NULL_RTX, mode); - create_fixed_operand (&ops[1], temp); - expand_insn (icode, 2, ops); - temp = ops[0].value; - } - else if (targetm.slow_unaligned_access (mode, MEM_ALIGN (temp))) - temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode), - 0, unsignedp, NULL_RTX, - mode, mode, false, NULL); - } + temp = expand_misaligned_mem_ref (temp, mode, unsignedp, + MEM_ALIGN (temp), NULL_RTX, NULL); return temp; } @@ -10325,27 +10342,8 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, && modifier != EXPAND_MEMORY && mode != BLKmode && align < GET_MODE_ALIGNMENT (mode)) - { - enum insn_code icode; - - if ((icode = optab_handler (movmisalign_optab, mode)) - != CODE_FOR_nothing) - { - class expand_operand ops[2]; - - /* We've already validated the memory, and we're creating a - new pseudo destination. The predicates really can't fail, - nor can the generator. */ - create_output_operand (&ops[0], NULL_RTX, mode); - create_fixed_operand (&ops[1], temp); - expand_insn (icode, 2, ops); - temp = ops[0].value; - } - else if (targetm.slow_unaligned_access (mode, align)) - temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode), - 0, unsignedp, NULL_RTX, - mode, mode, false, NULL); - } + temp = expand_misaligned_mem_ref (temp, mode, unsignedp, + align, NULL_RTX, NULL); return temp; } @@ -10357,7 +10355,6 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, machine_mode address_mode; tree base = TREE_OPERAND (exp, 0); gimple *def_stmt; - enum insn_code icode; unsigned align; /* Handle expansion of non-aliased memory with non-BLKmode. That might end up in a register. */ @@ -10387,7 +10384,6 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, return expand_expr (exp, target, tmode, modifier); } address_mode = targetm.addr_space.address_mode (as); - base = TREE_OPERAND (exp, 0); if ((def_stmt = get_def_for_expr (base, BIT_AND_EXPR))) { tree mask = gimple_assign_rhs2 (def_stmt); @@ -10414,27 +10410,9 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, && !inner_reference_p && mode != BLKmode && align < GET_MODE_ALIGNMENT (mode)) - { - if ((icode = optab_handler (movmisalign_optab, mode)) - != CODE_FOR_nothing) - { - class expand_operand ops[2]; - - /* We've already validated the memory, and we're creating a - new pseudo destination. The predicates really can't fail, - nor can the generator. */ - create_output_operand (&ops[0], NULL_RTX, mode); - create_fixed_operand (&ops[1], temp); - expand_insn (icode, 2, ops); - temp = ops[0].value; - } - else if (targetm.slow_unaligned_access (mode, align)) - temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode), - 0, TYPE_UNSIGNED (TREE_TYPE (exp)), - (modifier == EXPAND_STACK_PARM - ? NULL_RTX : target), - mode, mode, false, alt_rtl); - } + temp = expand_misaligned_mem_ref (temp, mode, unsignedp, align, + modifier == EXPAND_STACK_PARM + ? NULL_RTX : target, alt_rtl); if (reverse && modifier != EXPAND_MEMORY && modifier != EXPAND_WRITE) @@ -11109,11 +11087,10 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, machine_mode mode1; poly_int64 bitsize, bitpos, bytepos; tree offset; - int unsignedp, reversep, volatilep = 0; + int reversep, volatilep = 0; tree tem = get_inner_reference (treeop0, &bitsize, &bitpos, &offset, &mode1, &unsignedp, &reversep, &volatilep); - rtx orig_op0; /* ??? We should work harder and deal with non-zero offsets. */ if (!offset @@ -11123,7 +11100,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, && known_eq (wi::to_poly_offset (TYPE_SIZE (type)), bitsize)) { /* See the normal_inner_ref case for the rationale. */ - orig_op0 + rtx orig_op0 = expand_expr_real (tem, (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem))) -- cgit v1.1