diff options
author | hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-07-01 22:22:57 +0000 |
---|---|---|
committer | hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-07-01 22:22:57 +0000 |
commit | 9e169c4bf36a38689550c059570c57efbf00a6fb (patch) | |
tree | 95e6800f7ac2a49ff7f799d96f04172320e70ac0 /gcc/expr.c | |
parent | 6170dfb6edfb7b19f8ae5209b8f948fe0076a4ad (diff) | |
download | gcc-vect256.tar.gz |
Merged trunk at revision 161680 into branch.vect256
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/vect256@161681 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 364 |
1 files changed, 229 insertions, 135 deletions
diff --git a/gcc/expr.c b/gcc/expr.c index 6b2feb685a4..a2a8054eb4e 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -1276,12 +1276,14 @@ block_move_libcall_safe_for_call_parm (void) for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg)) { enum machine_mode mode = TYPE_MODE (TREE_VALUE (arg)); - rtx tmp = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1); + rtx tmp = targetm.calls.function_arg (&args_so_far, mode, + NULL_TREE, true); if (!tmp || !REG_P (tmp)) return false; if (targetm.calls.arg_partial_bytes (&args_so_far, mode, NULL, 1)) return false; - FUNCTION_ARG_ADVANCE (args_so_far, mode, NULL_TREE, 1); + targetm.calls.function_arg_advance (&args_so_far, mode, + NULL_TREE, true); } } return true; @@ -4211,6 +4213,10 @@ expand_assignment (tree to, tree from, bool nontemporal) an array element in an unaligned packed structure field, has the same problem. */ if (handled_component_p (to) + /* ??? We only need to handle MEM_REF here if the access is not + a full access of the base object. */ + || (TREE_CODE (to) == MEM_REF + && TREE_CODE (TREE_OPERAND (to, 0)) == ADDR_EXPR) || TREE_CODE (TREE_TYPE (to)) == ARRAY_TYPE) { enum machine_mode mode1; @@ -4229,6 +4235,13 @@ expand_assignment (tree to, tree from, bool nontemporal) to_rtx = expand_normal (tem); + /* If the bitfield is volatile, we want to access it in the + field's mode, not the computed mode. */ + if (volatilep + && GET_CODE (to_rtx) == MEM + && flag_strict_volatile_bitfields > 0) + to_rtx = adjust_address (to_rtx, mode1, 0); + if (offset != 0) { enum machine_mode address_mode; @@ -4677,6 +4690,51 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal) BLOCK_OP_NORMAL); return NULL_RTX; } + else if (TREE_CODE (exp) == MEM_REF + && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) == STRING_CST + && integer_zerop (TREE_OPERAND (exp, 1)) + && !nontemporal && !call_param_p + && TYPE_MODE (TREE_TYPE (exp)) == BLKmode) + { + /* Optimize initialization of an array with a STRING_CST. */ + HOST_WIDE_INT exp_len, str_copy_len; + rtx dest_mem; + tree str = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); + + exp_len = int_expr_size (exp); + if (exp_len <= 0) + goto normal_expr; + + str_copy_len = strlen (TREE_STRING_POINTER (str)); + if (str_copy_len < TREE_STRING_LENGTH (str) - 1) + goto normal_expr; + + str_copy_len = TREE_STRING_LENGTH (str); + if ((STORE_MAX_PIECES & (STORE_MAX_PIECES - 1)) == 0) + { + str_copy_len += STORE_MAX_PIECES - 1; + str_copy_len &= ~(STORE_MAX_PIECES - 1); + } + str_copy_len = MIN (str_copy_len, exp_len); + if (!can_store_by_pieces (str_copy_len, builtin_strncpy_read_str, + CONST_CAST(char *, TREE_STRING_POINTER (str)), + MEM_ALIGN (target), false)) + goto normal_expr; + + dest_mem = target; + + dest_mem = store_by_pieces (dest_mem, + str_copy_len, builtin_strncpy_read_str, + CONST_CAST(char *, TREE_STRING_POINTER (str)), + MEM_ALIGN (target), false, + exp_len > str_copy_len ? 1 : 0); + if (exp_len > str_copy_len) + clear_storage (adjust_address (dest_mem, BLKmode, 0), + GEN_INT (exp_len - str_copy_len), + BLOCK_OP_NORMAL); + return NULL_RTX; + } else { rtx tmp_target; @@ -5843,7 +5901,15 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos, operations. */ || (bitsize >= 0 && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) == INTEGER_CST - && compare_tree_int (TYPE_SIZE (TREE_TYPE (exp)), bitsize) != 0)) + && compare_tree_int (TYPE_SIZE (TREE_TYPE (exp)), bitsize) != 0) + /* If we are expanding a MEM_REF of a non-BLKmode non-addressable + decl we must use bitfield operations. */ + || (bitsize >= 0 + && TREE_CODE (exp) == MEM_REF + && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR + && DECL_P (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) + && !TREE_ADDRESSABLE (TREE_OPERAND (TREE_OPERAND (exp, 0),0 )) + && DECL_MODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) != BLKmode)) { rtx temp; gimple nop_def; @@ -5977,7 +6043,7 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, enum machine_mode mode = VOIDmode; bool blkmode_bitfield = false; tree offset = size_zero_node; - tree bit_offset = bitsize_zero_node; + double_int bit_offset = double_int_zero; /* First get the mode, signedness, and size. We do this from just the outermost expression. */ @@ -5990,6 +6056,12 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, mode = DECL_MODE (field); else if (DECL_MODE (field) == BLKmode) blkmode_bitfield = true; + else if (TREE_THIS_VOLATILE (exp) + && flag_strict_volatile_bitfields > 0) + /* Volatile bitfields should be accessed in the mode of the + field's type, not the mode computed based on the bit + size. */ + mode = TYPE_MODE (DECL_BIT_FIELD_TYPE (field)); *punsignedp = DECL_UNSIGNED (field); } @@ -6032,8 +6104,9 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, switch (TREE_CODE (exp)) { case BIT_FIELD_REF: - bit_offset = size_binop (PLUS_EXPR, bit_offset, - TREE_OPERAND (exp, 2)); + bit_offset + = double_int_add (bit_offset, + tree_to_double_int (TREE_OPERAND (exp, 2))); break; case COMPONENT_REF: @@ -6048,8 +6121,9 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, break; offset = size_binop (PLUS_EXPR, offset, this_offset); - bit_offset = size_binop (PLUS_EXPR, bit_offset, - DECL_FIELD_BIT_OFFSET (field)); + bit_offset = double_int_add (bit_offset, + tree_to_double_int + (DECL_FIELD_BIT_OFFSET (field))); /* ??? Right now we don't do anything with DECL_OFFSET_ALIGN. */ } @@ -6081,8 +6155,8 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, break; case IMAGPART_EXPR: - bit_offset = size_binop (PLUS_EXPR, bit_offset, - bitsize_int (*pbitsize)); + bit_offset = double_int_add (bit_offset, + uhwi_to_double_int (*pbitsize)); break; case VIEW_CONVERT_EXPR: @@ -6096,6 +6170,24 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, goto done; break; + case MEM_REF: + /* Hand back the decl for MEM[&decl, off]. */ + if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR) + { + tree off = TREE_OPERAND (exp, 1); + if (!integer_zerop (off)) + { + double_int boff, coff = mem_ref_offset (exp); + boff = double_int_lshift (coff, + BITS_PER_UNIT == 8 + ? 3 : exact_log2 (BITS_PER_UNIT), + HOST_BITS_PER_DOUBLE_INT, true); + bit_offset = double_int_add (bit_offset, boff); + } + exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); + } + goto done; + default: goto done; } @@ -6113,9 +6205,11 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, this conversion. */ if (host_integerp (offset, 0)) { - double_int tem = double_int_mul (tree_to_double_int (offset), - uhwi_to_double_int (BITS_PER_UNIT)); - tem = double_int_add (tem, tree_to_double_int (bit_offset)); + double_int tem = double_int_lshift (tree_to_double_int (offset), + BITS_PER_UNIT == 8 + ? 3 : exact_log2 (BITS_PER_UNIT), + HOST_BITS_PER_DOUBLE_INT, true); + tem = double_int_add (tem, bit_offset); if (double_int_fits_in_shwi_p (tem)) { *pbitpos = double_int_to_shwi (tem); @@ -6126,7 +6220,7 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, /* Otherwise, split it up. */ if (offset) { - *pbitpos = tree_low_cst (bit_offset, 0); + *pbitpos = double_int_to_shwi (bit_offset); *poffset = offset; } @@ -6854,6 +6948,16 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode, /* This case will happen via recursion for &a->b. */ return expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier); + case MEM_REF: + { + tree tem = TREE_OPERAND (exp, 0); + if (!integer_zerop (TREE_OPERAND (exp, 1))) + tem = build2 (POINTER_PLUS_EXPR, TREE_TYPE (TREE_OPERAND (exp, 1)), + tem, + double_int_to_tree (sizetype, mem_ref_offset (exp))); + return expand_expr (tem, target, tmode, modifier); + } + case CONST_DECL: /* Expand the initializer like constants above. */ return XEXP (expand_expr_constant (DECL_INITIAL (exp), 0, modifier), 0); @@ -7222,8 +7326,6 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, rtx subtarget, original_target; int ignore; bool reduce_bit_field; - gimple subexp0_def, subexp1_def; - tree top0, top1; location_t loc = ops->location; tree treeop0, treeop1; #define REDUCE_BIT_FIELD(expr) (reduce_bit_field \ @@ -7243,7 +7345,8 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, exactly those that are valid in gimple expressions that aren't GIMPLE_SINGLE_RHS (or invalid). */ gcc_assert (get_gimple_rhs_class (code) == GIMPLE_UNARY_RHS - || get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS); + || get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS + || get_gimple_rhs_class (code) == GIMPLE_TERNARY_RHS); ignore = (target == const0_rtx || ((CONVERT_EXPR_CODE_P (code) @@ -7418,58 +7521,6 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, fold_convert_loc (loc, ssizetype, treeop1)); case PLUS_EXPR: - - /* Check if this is a case for multiplication and addition. */ - if ((TREE_CODE (type) == INTEGER_TYPE - || TREE_CODE (type) == FIXED_POINT_TYPE) - && (subexp0_def = get_def_for_expr (treeop0, - MULT_EXPR))) - { - tree subsubexp0, subsubexp1; - gimple subsubexp0_def, subsubexp1_def; - enum tree_code this_code; - - this_code = TREE_CODE (type) == INTEGER_TYPE ? NOP_EXPR - : FIXED_CONVERT_EXPR; - subsubexp0 = gimple_assign_rhs1 (subexp0_def); - subsubexp0_def = get_def_for_expr (subsubexp0, this_code); - subsubexp1 = gimple_assign_rhs2 (subexp0_def); - subsubexp1_def = get_def_for_expr (subsubexp1, this_code); - if (subsubexp0_def && subsubexp1_def - && (top0 = gimple_assign_rhs1 (subsubexp0_def)) - && (top1 = gimple_assign_rhs1 (subsubexp1_def)) - && (TYPE_PRECISION (TREE_TYPE (top0)) - < TYPE_PRECISION (TREE_TYPE (subsubexp0))) - && (TYPE_PRECISION (TREE_TYPE (top0)) - == TYPE_PRECISION (TREE_TYPE (top1))) - && (TYPE_UNSIGNED (TREE_TYPE (top0)) - == TYPE_UNSIGNED (TREE_TYPE (top1)))) - { - tree op0type = TREE_TYPE (top0); - enum machine_mode innermode = TYPE_MODE (op0type); - bool zextend_p = TYPE_UNSIGNED (op0type); - bool sat_p = TYPE_SATURATING (TREE_TYPE (subsubexp0)); - if (sat_p == 0) - this_optab = zextend_p ? umadd_widen_optab : smadd_widen_optab; - else - this_optab = zextend_p ? usmadd_widen_optab - : ssmadd_widen_optab; - if (mode == GET_MODE_2XWIDER_MODE (innermode) - && (optab_handler (this_optab, mode)->insn_code - != CODE_FOR_nothing)) - { - expand_operands (top0, top1, NULL_RTX, &op0, &op1, - EXPAND_NORMAL); - op2 = expand_expr (treeop1, subtarget, - VOIDmode, EXPAND_NORMAL); - temp = expand_ternary_op (mode, this_optab, op0, op1, op2, - target, unsignedp); - gcc_assert (temp); - return REDUCE_BIT_FIELD (temp); - } - } - } - /* If we are adding a constant, a VAR_DECL that is sp, fp, or ap, and something else, make sure we add the register to the constant and then to the other thing. This case can occur during strength @@ -7584,57 +7635,6 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1)); case MINUS_EXPR: - /* Check if this is a case for multiplication and subtraction. */ - if ((TREE_CODE (type) == INTEGER_TYPE - || TREE_CODE (type) == FIXED_POINT_TYPE) - && (subexp1_def = get_def_for_expr (treeop1, - MULT_EXPR))) - { - tree subsubexp0, subsubexp1; - gimple subsubexp0_def, subsubexp1_def; - enum tree_code this_code; - - this_code = TREE_CODE (type) == INTEGER_TYPE ? NOP_EXPR - : FIXED_CONVERT_EXPR; - subsubexp0 = gimple_assign_rhs1 (subexp1_def); - subsubexp0_def = get_def_for_expr (subsubexp0, this_code); - subsubexp1 = gimple_assign_rhs2 (subexp1_def); - subsubexp1_def = get_def_for_expr (subsubexp1, this_code); - if (subsubexp0_def && subsubexp1_def - && (top0 = gimple_assign_rhs1 (subsubexp0_def)) - && (top1 = gimple_assign_rhs1 (subsubexp1_def)) - && (TYPE_PRECISION (TREE_TYPE (top0)) - < TYPE_PRECISION (TREE_TYPE (subsubexp0))) - && (TYPE_PRECISION (TREE_TYPE (top0)) - == TYPE_PRECISION (TREE_TYPE (top1))) - && (TYPE_UNSIGNED (TREE_TYPE (top0)) - == TYPE_UNSIGNED (TREE_TYPE (top1)))) - { - tree op0type = TREE_TYPE (top0); - enum machine_mode innermode = TYPE_MODE (op0type); - bool zextend_p = TYPE_UNSIGNED (op0type); - bool sat_p = TYPE_SATURATING (TREE_TYPE (subsubexp0)); - if (sat_p == 0) - this_optab = zextend_p ? umsub_widen_optab : smsub_widen_optab; - else - this_optab = zextend_p ? usmsub_widen_optab - : ssmsub_widen_optab; - if (mode == GET_MODE_2XWIDER_MODE (innermode) - && (optab_handler (this_optab, mode)->insn_code - != CODE_FOR_nothing)) - { - expand_operands (top0, top1, NULL_RTX, &op0, &op1, - EXPAND_NORMAL); - op2 = expand_expr (treeop0, subtarget, - VOIDmode, EXPAND_NORMAL); - temp = expand_ternary_op (mode, this_optab, op0, op1, op2, - target, unsignedp); - gcc_assert (temp); - return REDUCE_BIT_FIELD (temp); - } - } - } - /* For initializers, we are allowed to return a MINUS of two symbolic constants. Here we handle all cases when both operands are constant. */ @@ -7675,6 +7675,14 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, goto binop2; + case WIDEN_MULT_PLUS_EXPR: + case WIDEN_MULT_MINUS_EXPR: + expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL); + op2 = expand_normal (ops->op2); + target = expand_widen_pattern_expr (ops, op0, op1, op2, + target, unsignedp); + return target; + case WIDEN_MULT_EXPR: /* If first operand is constant, swap them. Thus the following special case checks need only @@ -8284,6 +8292,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, location_t loc = EXPR_LOCATION (exp); struct separate_ops ops; tree treeop0, treeop1, treeop2; + tree ssa_name = NULL_TREE; + gimple g; type = TREE_TYPE (exp); mode = TYPE_MODE (type); @@ -8396,15 +8406,17 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, base variable. This unnecessarily allocates a pseudo, see how we can reuse it, if partition base vars have it set already. */ if (!currently_expanding_to_rtl) - return expand_expr_real_1 (SSA_NAME_VAR (exp), target, tmode, modifier, NULL); - { - gimple g = get_gimple_for_ssa_name (exp); - if (g) - return expand_expr_real (gimple_assign_rhs_to_tree (g), target, - tmode, modifier, NULL); - } - decl_rtl = get_rtx_for_ssa_name (exp); - exp = SSA_NAME_VAR (exp); + return expand_expr_real_1 (SSA_NAME_VAR (exp), target, tmode, modifier, + NULL); + + g = get_gimple_for_ssa_name (exp); + if (g) + return expand_expr_real (gimple_assign_rhs_to_tree (g), target, tmode, + modifier, NULL); + + ssa_name = exp; + decl_rtl = get_rtx_for_ssa_name (ssa_name); + exp = SSA_NAME_VAR (ssa_name); goto expand_decl_rtl; case PARM_DECL: @@ -8506,15 +8518,21 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, /* If the mode of DECL_RTL does not match that of the decl, it must be a promoted value. We return a SUBREG of the wanted mode, but mark it so that we know that it was already extended. */ - - if (REG_P (decl_rtl) - && GET_MODE (decl_rtl) != DECL_MODE (exp)) + if (REG_P (decl_rtl) && GET_MODE (decl_rtl) != DECL_MODE (exp)) { enum machine_mode pmode; - /* Get the signedness used for this variable. Ensure we get the - same mode we got when the variable was declared. */ - pmode = promote_decl_mode (exp, &unsignedp); + /* Get the signedness to be used for this variable. Ensure we get + the same mode we got when the variable was declared. */ + if (code == SSA_NAME + && (g = SSA_NAME_DEF_STMT (ssa_name)) + && gimple_code (g) == GIMPLE_CALL) + pmode = promote_function_mode (type, mode, &unsignedp, + TREE_TYPE + (TREE_TYPE (gimple_call_fn (g))), + 2); + else + pmode = promote_decl_mode (exp, &unsignedp); gcc_assert (GET_MODE (decl_rtl) == pmode); temp = gen_lowpart_SUBREG (mode, decl_rtl); @@ -8751,6 +8769,71 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, } return temp; + case MEM_REF: + { + addr_space_t as + = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 1)))); + enum machine_mode address_mode; + tree base = TREE_OPERAND (exp, 0); + /* Handle expansion of non-aliased memory with non-BLKmode. That + might end up in a register. */ + if (TREE_CODE (base) == ADDR_EXPR) + { + HOST_WIDE_INT offset = mem_ref_offset (exp).low; + tree bit_offset; + base = TREE_OPERAND (base, 0); + if (!DECL_P (base)) + { + HOST_WIDE_INT off; + base = get_addr_base_and_unit_offset (base, &off); + gcc_assert (base); + offset += off; + } + /* If we are expanding a MEM_REF of a non-BLKmode non-addressable + decl we must use bitfield operations. */ + if (DECL_P (base) + && !TREE_ADDRESSABLE (base) + && DECL_MODE (base) != BLKmode + && DECL_RTL_SET_P (base) + && !MEM_P (DECL_RTL (base))) + { + tree bftype; + if (offset == 0 + && host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1) + && (GET_MODE_BITSIZE (DECL_MODE (base)) + == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))) + return expand_expr (build1 (VIEW_CONVERT_EXPR, + TREE_TYPE (exp), base), + target, tmode, modifier); + bit_offset = bitsize_int (offset * BITS_PER_UNIT); + bftype = TREE_TYPE (base); + if (TYPE_MODE (TREE_TYPE (exp)) != BLKmode) + bftype = TREE_TYPE (exp); + return expand_expr (build3 (BIT_FIELD_REF, bftype, + base, + TYPE_SIZE (TREE_TYPE (exp)), + bit_offset), + target, tmode, modifier); + } + } + address_mode = targetm.addr_space.address_mode (as); + op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, address_mode, + EXPAND_NORMAL); + if (!integer_zerop (TREE_OPERAND (exp, 1))) + { + rtx off; + off = immed_double_int_const (mem_ref_offset (exp), address_mode); + op0 = simplify_gen_binary (PLUS, address_mode, op0, off); + } + op0 = memory_address_addr_space (mode, op0, as); + temp = gen_rtx_MEM (mode, op0); + set_mem_attributes (temp, exp, 0); + set_mem_addr_space (temp, as); + if (TREE_THIS_VOLATILE (exp)) + MEM_VOLATILE_P (temp) = 1; + return temp; + } + case ARRAY_REF: { @@ -8966,6 +9049,14 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, || modifier == EXPAND_STACK_PARM) ? modifier : EXPAND_NORMAL); + + /* If the bitfield is volatile, we want to access it in the + field's mode, not the computed mode. */ + if (volatilep + && GET_CODE (op0) == MEM + && flag_strict_volatile_bitfields > 0) + op0 = adjust_address (op0, mode1, 0); + mode2 = CONSTANT_P (op0) ? TYPE_MODE (TREE_TYPE (tem)) : GET_MODE (op0); @@ -9091,6 +9182,9 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT && modifier != EXPAND_CONST_ADDRESS && modifier != EXPAND_INITIALIZER) + /* If the field is volatile, we always want an aligned + access. */ + || (volatilep && flag_strict_volatile_bitfields > 0) /* If the field isn't aligned enough to fetch as a memref, fetch it as a bit field. */ || (mode1 != BLKmode |