[Bug target/66866] [miscompile] incorrect load address on manual vector shuffle
rguenth at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Tue Jul 14 12:45:00 GMT 2015
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66866
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |wrong-code
Target| |x86_64-*-*
CC| |uros at gcc dot gnu.org
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
Expansion is already wrong:
;; MEM[(A * {ref-all})&r + 10B] = _2;
(insn 6 5 7 (set (reg:TI 92)
(subreg:TI (reg/v:V2DI 91 [ v ]) 0)) t.c:8 -1
(nil))
(insn 7 6 8 (set (reg:V8HI 93)
(vec_merge:V8HI (vec_duplicate:V8HI (subreg:HI (reg:TI 92) 0))
(subreg:V8HI (reg/v:V2DI 89 [ r ]) 0)
(const_int 32 [0x20]))) t.c:8 -1
(nil))
(insn 8 7 0 (set (reg/v:V2DI 89 [ r ])
(subreg:V2DI (reg:V8HI 93) 0)) t.c:8 -1
(nil))
(subreg:HI (reg:TI 92) 0) selects the wrong source.
We go
/* 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
by doing the extract into an object as wide as the field
(which we know to be the width of a basic mode), then
storing into memory, and changing the mode to BLKmode. */
if (mode1 == VOIDmode
...
op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp,
(modifier == EXPAND_STACK_PARM
? NULL_RTX : target),
ext_mode, ext_mode);
(gdb) p debug_rtx (op0)
(reg/v:V2DI 91 [ v ])
(gdb) p bitsize
$7 = 16
(gdb) p bitpos
$8 = 64
(gdb) p ext_mode
$9 = HImode
which gets us
(gdb) p debug_rtx (op0)
(subreg:HI (reg:TI 92) 8)
so handling the load is fine. Ultimately returned to
#0 0x0000000000c1bf17 in store_field (target=0x7ffff6a49d80, bitsize=16,
bitpos=80, bitregion_start=80, bitregion_end=95, mode=HImode,
exp=<ssa_name 0x7ffff68d5b40>, alias_set=0, nontemporal=false)
at /space/rguenther/tramp3d/trunk/gcc/expr.c:6643
#1 0x0000000000c1582a in expand_assignment (to=<mem_ref 0x7ffff6a42168>,
from=<ssa_name 0x7ffff68d5b40>, nontemporal=false)
at /space/rguenther/tramp3d/trunk/gcc/expr.c:5016
and leading to
#0 store_bit_field_1 (str_rtx=0x7ffff6a49d80, bitsize=16, bitnum=80,
bitregion_start=80, bitregion_end=95, fieldmode=HImode,
value=0x7ffff6a49f18, fallback_p=true)
at /space/rguenther/tramp3d/trunk/gcc/expmed.c:881
876 /* If OP0 is a multi-word register, narrow it to the affected word.
877 If the region spans two words, defer to store_split_bit_field. */
878 if (!MEM_P (op0) && GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD)
879 {
and finally using the insv path.
Breakpoint 7, store_bit_field_using_insv (insv=0x7fffffffd380,
op0=0x7ffff6a49f48, bitsize=16, bitnum=16, value=0x7ffff6a49f18)
at /space/rguenther/tramp3d/trunk/gcc/expmed.c:508
508 rtx xop0 = op0;
(gdb) p debug_rtx (op0)
(subreg:DI (reg/v:V2DI 89 [ r ]) 8)
$40 = void
(gdb) p debug_rtx (value)
(subreg:HI (reg:TI 92) 8)
$41 = void
creating insv with
611 create_fixed_operand (&ops[0], xop0);
612 create_integer_operand (&ops[1], bitsize);
613 create_integer_operand (&ops[2], bitnum);
614 create_input_operand (&ops[3], value1, op_mode);
(gdb) p debug_rtx (xop0)
(subreg:DI (reg/v:V2DI 89 [ r ]) 8)
$47 = void
(gdb) p debug_rtx (value1)
(subreg:DI (reg:TI 92) 8)
$48 = void
(gdb) p bitsize
$49 = 16
(gdb) p bitnum
$50 = 16
More information about the Gcc-bugs
mailing list