Commit f96bf49a by Jim Wilson Committed by Jim Wilson

Patch for RTL expand bug affecting aarch64 vector code.

	gcc/
	PR middle-end/79794
    	* expmed.c (extract_bit_field_1): Add alt_rtl argument.  Before
	maybe_expand_insn call, set ops[0].target.  If still set after call,
	set alt_rtl.  Add extra arg to recursive calls.
	(extract_bit_field): Add alt_rtl argument.  Pass to
	extract_bit_field.
	* expmed.h (extract_bit_field): Fix prototype.
	* expr.c (emit_group_load_1, copy_blkmode_from_reg)
	(copy_blkmode_to_reg, read_complex_part, store_field): Pass extra NULL
	to extract_bit_field_calls.
	(expand_expr_real_1): Pass alt_rtl to expand_expr_real instead of 0.
	Pass alt_rtl to extract_bit_field calls.
	* calls.c (store_unaligned_arguments_into_psuedos)
	load_register_parameters): Pass extra NULL to extract_bit_field calls.
	* optabs.c (maybe_legitimize_operand): Clear op->target when call
	gen_reg_rtx.
	* optabs.h (struct expand_operand): Add target bitfield.

From-SVN: r248004
parent 7f390a7b
2017-05-12 Jim Wilson <jim.wilson@linaro.org>
PR middle-end/79794
* expmed.c (extract_bit_field_1): Add alt_rtl argument. Before
maybe_expand_insn call, set ops[0].target. If still set after call,
set alt_rtl. Add extra arg to recursive calls.
(extract_bit_field): Add alt_rtl argument. Pass to
extract_bit_field.
* expmed.h (extract_bit_field): Fix prototype.
* expr.c (emit_group_load_1, copy_blkmode_from_reg)
(copy_blkmode_to_reg, read_complex_part, store_field): Pass extra NULL
to extract_bit_field_calls.
(expand_expr_real_1): Pass alt_rtl to expand_expr_real instead of 0.
Pass alt_rtl to extract_bit_field calls.
* calls.c (store_unaligned_arguments_into_psuedos)
load_register_parameters): Pass extra NULL to extract_bit_field calls.
* optabs.c (maybe_legitimize_operand): Clear op->target when call
gen_reg_rtx.
* optabs.h (struct expand_operand): Add target bitfield.
2017-05-12 Uros Bizjak <ubizjak@gmail.com> 2017-05-12 Uros Bizjak <ubizjak@gmail.com>
* compare-elim.c (try_eliminate_compare): Canonicalize * compare-elim.c (try_eliminate_compare): Canonicalize
......
...@@ -1164,7 +1164,7 @@ store_unaligned_arguments_into_pseudos (struct arg_data *args, int num_actuals) ...@@ -1164,7 +1164,7 @@ store_unaligned_arguments_into_pseudos (struct arg_data *args, int num_actuals)
args[i].aligned_regs[j] = reg; args[i].aligned_regs[j] = reg;
word = extract_bit_field (word, bitsize, 0, 1, NULL_RTX, word = extract_bit_field (word, bitsize, 0, 1, NULL_RTX,
word_mode, word_mode, false); word_mode, word_mode, false, NULL);
/* There is no need to restrict this code to loading items /* There is no need to restrict this code to loading items
in TYPE_ALIGN sized hunks. The bitfield instructions can in TYPE_ALIGN sized hunks. The bitfield instructions can
...@@ -2557,7 +2557,8 @@ load_register_parameters (struct arg_data *args, int num_actuals, ...@@ -2557,7 +2557,8 @@ load_register_parameters (struct arg_data *args, int num_actuals,
unsigned int bitoff = (nregs - 1) * BITS_PER_WORD; unsigned int bitoff = (nregs - 1) * BITS_PER_WORD;
unsigned int bitsize = size * BITS_PER_UNIT - bitoff; unsigned int bitsize = size * BITS_PER_UNIT - bitoff;
rtx x = extract_bit_field (mem, bitsize, bitoff, 1, dest, rtx x = extract_bit_field (mem, bitsize, bitoff, 1, dest,
word_mode, word_mode, false); word_mode, word_mode, false,
NULL);
if (BYTES_BIG_ENDIAN) if (BYTES_BIG_ENDIAN)
x = expand_shift (LSHIFT_EXPR, word_mode, x, x = expand_shift (LSHIFT_EXPR, word_mode, x,
BITS_PER_WORD - bitsize, dest, 1); BITS_PER_WORD - bitsize, dest, 1);
......
...@@ -1534,7 +1534,7 @@ static rtx ...@@ -1534,7 +1534,7 @@ static rtx
extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target, unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target,
machine_mode mode, machine_mode tmode, machine_mode mode, machine_mode tmode,
bool reverse, bool fallback_p) bool reverse, bool fallback_p, rtx *alt_rtl)
{ {
rtx op0 = str_rtx; rtx op0 = str_rtx;
machine_mode int_mode; machine_mode int_mode;
...@@ -1610,10 +1610,13 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, ...@@ -1610,10 +1610,13 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
unsigned HOST_WIDE_INT pos = bitnum / GET_MODE_BITSIZE (innermode); unsigned HOST_WIDE_INT pos = bitnum / GET_MODE_BITSIZE (innermode);
create_output_operand (&ops[0], target, innermode); create_output_operand (&ops[0], target, innermode);
ops[0].target = 1;
create_input_operand (&ops[1], op0, outermode); create_input_operand (&ops[1], op0, outermode);
create_integer_operand (&ops[2], pos); create_integer_operand (&ops[2], pos);
if (maybe_expand_insn (icode, 3, ops)) if (maybe_expand_insn (icode, 3, ops))
{ {
if (alt_rtl && ops[0].target)
*alt_rtl = target;
target = ops[0].value; target = ops[0].value;
if (GET_MODE (target) != mode) if (GET_MODE (target) != mode)
return gen_lowpart (tmode, target); return gen_lowpart (tmode, target);
...@@ -1735,7 +1738,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, ...@@ -1735,7 +1738,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
= extract_bit_field_1 (op0, MIN (BITS_PER_WORD, = extract_bit_field_1 (op0, MIN (BITS_PER_WORD,
bitsize - i * BITS_PER_WORD), bitsize - i * BITS_PER_WORD),
bitnum + bit_offset, 1, target_part, bitnum + bit_offset, 1, target_part,
mode, word_mode, reverse, fallback_p); mode, word_mode, reverse, fallback_p, NULL);
gcc_assert (target_part); gcc_assert (target_part);
if (!result_part) if (!result_part)
...@@ -1838,7 +1841,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, ...@@ -1838,7 +1841,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
xop0 = copy_to_reg (xop0); xop0 = copy_to_reg (xop0);
rtx result = extract_bit_field_1 (xop0, bitsize, bitpos, rtx result = extract_bit_field_1 (xop0, bitsize, bitpos,
unsignedp, target, unsignedp, target,
mode, tmode, reverse, false); mode, tmode, reverse, false, NULL);
if (result) if (result)
return result; return result;
delete_insns_since (last); delete_insns_since (last);
...@@ -1894,7 +1897,8 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, ...@@ -1894,7 +1897,8 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
rtx rtx
extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target, unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target,
machine_mode mode, machine_mode tmode, bool reverse) machine_mode mode, machine_mode tmode, bool reverse,
rtx *alt_rtl)
{ {
machine_mode mode1; machine_mode mode1;
...@@ -1929,7 +1933,7 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, ...@@ -1929,7 +1933,7 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
} }
return extract_bit_field_1 (str_rtx, bitsize, bitnum, unsignedp, return extract_bit_field_1 (str_rtx, bitsize, bitnum, unsignedp,
target, mode, tmode, reverse, true); target, mode, tmode, reverse, true, alt_rtl);
} }
/* Use shifts and boolean operations to extract a field of BITSIZE bits /* Use shifts and boolean operations to extract a field of BITSIZE bits
......
...@@ -725,7 +725,7 @@ extern void store_bit_field (rtx, unsigned HOST_WIDE_INT, ...@@ -725,7 +725,7 @@ extern void store_bit_field (rtx, unsigned HOST_WIDE_INT,
machine_mode, rtx, bool); machine_mode, rtx, bool);
extern rtx extract_bit_field (rtx, unsigned HOST_WIDE_INT, extern rtx extract_bit_field (rtx, unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT, int, rtx, unsigned HOST_WIDE_INT, int, rtx,
machine_mode, machine_mode, bool); machine_mode, machine_mode, bool, rtx *);
extern rtx extract_low_bits (machine_mode, machine_mode, rtx); extern rtx extract_low_bits (machine_mode, machine_mode, rtx);
extern rtx expand_mult (machine_mode, rtx, rtx, rtx, int); extern rtx expand_mult (machine_mode, rtx, rtx, rtx, int);
extern rtx expand_mult_highpart_adjust (machine_mode, rtx, rtx, rtx, rtx, int); extern rtx expand_mult_highpart_adjust (machine_mode, rtx, rtx, rtx, rtx, int);
......
...@@ -2192,7 +2192,8 @@ emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type, int ssize) ...@@ -2192,7 +2192,8 @@ emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type, int ssize)
&& (!REG_P (tmps[i]) || GET_MODE (tmps[i]) != mode))) && (!REG_P (tmps[i]) || GET_MODE (tmps[i]) != mode)))
tmps[i] = extract_bit_field (tmps[i], bytelen * BITS_PER_UNIT, tmps[i] = extract_bit_field (tmps[i], bytelen * BITS_PER_UNIT,
subpos * BITS_PER_UNIT, subpos * BITS_PER_UNIT,
1, NULL_RTX, mode, mode, false); 1, NULL_RTX, mode, mode, false,
NULL);
} }
else else
{ {
...@@ -2202,7 +2203,8 @@ emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type, int ssize) ...@@ -2202,7 +2203,8 @@ emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type, int ssize)
mem = assign_stack_temp (GET_MODE (src), slen); mem = assign_stack_temp (GET_MODE (src), slen);
emit_move_insn (mem, src); emit_move_insn (mem, src);
tmps[i] = extract_bit_field (mem, bytelen * BITS_PER_UNIT, tmps[i] = extract_bit_field (mem, bytelen * BITS_PER_UNIT,
0, 1, NULL_RTX, mode, mode, false); 0, 1, NULL_RTX, mode, mode, false,
NULL);
} }
} }
/* FIXME: A SIMD parallel will eventually lead to a subreg of a /* FIXME: A SIMD parallel will eventually lead to a subreg of a
...@@ -2245,7 +2247,7 @@ emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type, int ssize) ...@@ -2245,7 +2247,7 @@ emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type, int ssize)
else else
tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT, tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT,
bytepos * BITS_PER_UNIT, 1, NULL_RTX, bytepos * BITS_PER_UNIT, 1, NULL_RTX,
mode, mode, false); mode, mode, false, NULL);
if (shift) if (shift)
tmps[i] = expand_shift (LSHIFT_EXPR, mode, tmps[i], tmps[i] = expand_shift (LSHIFT_EXPR, mode, tmps[i],
...@@ -2697,7 +2699,7 @@ copy_blkmode_from_reg (rtx target, rtx srcreg, tree type) ...@@ -2697,7 +2699,7 @@ copy_blkmode_from_reg (rtx target, rtx srcreg, tree type)
extract_bit_field (src, bitsize, extract_bit_field (src, bitsize,
xbitpos % BITS_PER_WORD, 1, xbitpos % BITS_PER_WORD, 1,
NULL_RTX, copy_mode, copy_mode, NULL_RTX, copy_mode, copy_mode,
false), false, NULL),
false); false);
} }
} }
...@@ -2776,7 +2778,7 @@ copy_blkmode_to_reg (machine_mode mode, tree src) ...@@ -2776,7 +2778,7 @@ copy_blkmode_to_reg (machine_mode mode, tree src)
extract_bit_field (src_word, bitsize, extract_bit_field (src_word, bitsize,
bitpos % BITS_PER_WORD, 1, bitpos % BITS_PER_WORD, 1,
NULL_RTX, word_mode, word_mode, NULL_RTX, word_mode, word_mode,
false), false, NULL),
false); false);
} }
...@@ -3225,7 +3227,7 @@ read_complex_part (rtx cplx, bool imag_p) ...@@ -3225,7 +3227,7 @@ read_complex_part (rtx cplx, bool imag_p)
} }
return extract_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0, return extract_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0,
true, NULL_RTX, imode, imode, false); true, NULL_RTX, imode, imode, false, NULL);
} }
/* A subroutine of emit_move_insn_1. Yet another lowpart generator. /* A subroutine of emit_move_insn_1. Yet another lowpart generator.
...@@ -6911,7 +6913,7 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos, ...@@ -6911,7 +6913,7 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
{ {
machine_mode temp_mode = smallest_mode_for_size (bitsize, MODE_INT); machine_mode temp_mode = smallest_mode_for_size (bitsize, MODE_INT);
temp = extract_bit_field (temp, bitsize, 0, 1, NULL_RTX, temp_mode, temp = extract_bit_field (temp, bitsize, 0, 1, NULL_RTX, temp_mode,
temp_mode, false); temp_mode, false, NULL);
} }
/* Store the value in the bitfield. */ /* Store the value in the bitfield. */
...@@ -9780,7 +9782,8 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, ...@@ -9780,7 +9782,8 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
case GIMPLE_SINGLE_RHS: case GIMPLE_SINGLE_RHS:
{ {
r = expand_expr_real (gimple_assign_rhs1 (g), target, r = expand_expr_real (gimple_assign_rhs1 (g), target,
tmode, modifier, NULL, inner_reference_p); tmode, modifier, alt_rtl,
inner_reference_p);
break; break;
} }
default: default:
...@@ -10210,7 +10213,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, ...@@ -10210,7 +10213,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
0, TYPE_UNSIGNED (TREE_TYPE (exp)), 0, TYPE_UNSIGNED (TREE_TYPE (exp)),
(modifier == EXPAND_STACK_PARM (modifier == EXPAND_STACK_PARM
? NULL_RTX : target), ? NULL_RTX : target),
mode, mode, false); mode, mode, false, alt_rtl);
} }
if (reverse if (reverse
&& modifier != EXPAND_MEMORY && modifier != EXPAND_MEMORY
...@@ -10707,7 +10710,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, ...@@ -10707,7 +10710,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp, op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp,
(modifier == EXPAND_STACK_PARM (modifier == EXPAND_STACK_PARM
? NULL_RTX : target), ? NULL_RTX : target),
ext_mode, ext_mode, reversep); ext_mode, ext_mode, reversep, alt_rtl);
/* If the result has a record type and the mode of OP0 is an /* If the result has a record type and the mode of OP0 is an
integral mode then, if BITSIZE is narrower than this mode integral mode then, if BITSIZE is narrower than this mode
...@@ -10928,7 +10931,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, ...@@ -10928,7 +10931,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
else if (reduce_bit_field) else if (reduce_bit_field)
return extract_bit_field (op0, TYPE_PRECISION (type), 0, return extract_bit_field (op0, TYPE_PRECISION (type), 0,
TYPE_UNSIGNED (type), NULL_RTX, TYPE_UNSIGNED (type), NULL_RTX,
mode, mode, false); mode, mode, false, NULL);
/* As a last resort, spill op0 to memory, and reload it in a /* As a last resort, spill op0 to memory, and reload it in a
different mode. */ different mode. */
else if (!MEM_P (op0)) else if (!MEM_P (op0))
......
...@@ -6962,6 +6962,7 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno, ...@@ -6962,6 +6962,7 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
return true; return true;
op->value = gen_reg_rtx (mode); op->value = gen_reg_rtx (mode);
op->target = 0;
break; break;
case EXPAND_INPUT: case EXPAND_INPUT:
......
...@@ -48,8 +48,11 @@ struct expand_operand { ...@@ -48,8 +48,11 @@ struct expand_operand {
rather than signed. Only meaningful for certain types. */ rather than signed. Only meaningful for certain types. */
unsigned int unsigned_p : 1; unsigned int unsigned_p : 1;
/* Is the target operand. */
unsigned int target : 1;
/* Unused; available for future use. */ /* Unused; available for future use. */
unsigned int unused : 7; unsigned int unused : 6;
/* The mode passed to the convert_*_operand function. It has a /* The mode passed to the convert_*_operand function. It has a
type-dependent meaning. */ type-dependent meaning. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment