https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118643

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot 
gnu.org
           Priority|P3                          |P1
             Status|NEW                         |ASSIGNED

--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> ---
The bogus BIT_FIELD_REF is built from

#0  0x0000000001d3a091 in make_node (code=BIT_FIELD_REF)
    at /space/rguenther/src/gcc/gcc/tree.cc:1217
#1  0x0000000001d496ce in build3 (code=BIT_FIELD_REF, 
    tt=<vector_type 0x7ffff6fbe930>, arg0=<var_decl 0x7ffff6fef000 f>, 
    arg1=<integer_cst 0x7ffff6e02fa8>, arg2=<integer_cst 0x7ffff6c9fed8>)
    at /space/rguenther/src/gcc/gcc/tree.cc:5211
#2  0x00000000013053f0 in expand_expr_real_1 (exp=<mem_ref 0x7ffff6c86190>, 
    target=0x7ffff6cabc60, tmode=E_V4SImode, modifier=EXPAND_NORMAL, 
    alt_rtl=0x7fffffffcf38, inner_reference_p=false)
    at /space/rguenther/src/gcc/gcc/expr.cc:11808
#3  0x00000000012fa625 in expand_expr_real (exp=<mem_ref 0x7ffff6c86190>, 
    target=0x7ffff6cabc60, tmode=E_V4SImode, modifier=EXPAND_NORMAL, 
    alt_rtl=0x7fffffffcf38, inner_reference_p=false)
    at /space/rguenther/src/gcc/gcc/expr.cc:9521
#4  0x00000000012eead8 in store_expr (exp=<mem_ref 0x7ffff6c86190>, 
    target=0x7ffff6cabc60, call_param_p=0, nontemporal=false, reverse=false)
    at /space/rguenther/src/gcc/gcc/expr.cc:6771
#5  0x00000000012ecf53 in expand_assignment (to=<ssa_name 0x7ffff6c85438 874>, 
    from=<mem_ref 0x7ffff6c86190>, nontemporal=false)
    at /space/rguenther/src/gcc/gcc/expr.cc:6492

expanding

vect__24.107_874 = MEM <vector(4) int> [(int *)&f + -12B];

which is the fallback of

        /* Handle expansion of non-aliased memory with non-BLKmode.  That
           might end up in a register.  */
        if (mem_ref_refers_to_non_mem_p (exp))
          {
            poly_int64 offset = mem_ref_offset (exp).force_shwi ();
            base = TREE_OPERAND (base, 0);
            poly_uint64 type_size;
            if (known_eq (offset, 0)
                && !reverse
                && poly_int_tree_p (TYPE_SIZE (type), &type_size)
                && known_eq (GET_MODE_BITSIZE (DECL_MODE (base)), type_size))
              return expand_expr (build1 (VIEW_CONVERT_EXPR, type, base),
                                  target, tmode, modifier);
            if (TYPE_MODE (type) == BLKmode)
              {
                temp = assign_stack_temp (DECL_MODE (base),
                                          GET_MODE_SIZE (DECL_MODE (base)));
                store_expr (base, temp, 0, false, false);
                temp = adjust_address (temp, BLKmode, offset);
                set_mem_size (temp, int_size_in_bytes (type));
                return temp;
              }
            exp = build3 (BIT_FIELD_REF, type, base, TYPE_SIZE (type),
                          bitsize_int (offset * BITS_PER_UNIT));
            REF_REVERSE_STORAGE_ORDER (exp) = reverse;
            return expand_expr (exp, target, tmode, modifier);

we possibly want to guard offset and fall back to a stack temporary like
with the following which fixes the ICE.

diff --git a/gcc/expr.cc b/gcc/expr.cc
index a310b2d9131..4bfcde54523 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -11796,13 +11796,15 @@ expand_expr_real_1 (tree exp, rtx target,
machine_mode tmode,
                && known_eq (GET_MODE_BITSIZE (DECL_MODE (base)), type_size))
              return expand_expr (build1 (VIEW_CONVERT_EXPR, type, base),
                                  target, tmode, modifier);
-           if (TYPE_MODE (type) == BLKmode)
+           if (TYPE_MODE (type) == BLKmode
+               || maybe_lt (offset, 0))
              {
                temp = assign_stack_temp (DECL_MODE (base),
                                          GET_MODE_SIZE (DECL_MODE (base)));
                store_expr (base, temp, 0, false, false);
-               temp = adjust_address (temp, BLKmode, offset);
-               set_mem_size (temp, int_size_in_bytes (type));
+               temp = adjust_address (temp, TYPE_MODE (type), offset);
+               if (TYPE_MODE (type) == BLKmode)
+                 set_mem_size (temp, int_size_in_bytes (type));
                return temp;
              }
            exp = build3 (BIT_FIELD_REF, type, base, TYPE_SIZE (type),

Reply via email to