Commit 3c84109e by Richard Sandiford Committed by Richard Sandiford

[54/77] Add explicit int checks for alternative optab implementations

expand_unop can expand narrow clz, clrsb, ctz, bswap, parity and
ffs operations using optabs for wider modes.  These expansions
apply only to scalar integer modes (and not for example to vectors),
so the patch adds explicit checks for that.

2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

gcc/
	* optabs.c (widen_leading): Change the type of the mode argument
	to scalar_int_mode.  Use opt_scalar_int_mode for the mode iterator.
	(widen_bswap): Likewise.
	(expand_parity): Likewise.
	(expand_ctz): Change the type of the mode argument to scalar_int_mode.
	(expand_ffs): Likewise.
	(epand_unop): Check for scalar integer modes before calling the
	above routines.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>

From-SVN: r251506
parent 04d6ea36
...@@ -2,6 +2,19 @@ ...@@ -2,6 +2,19 @@
Alan Hayward <alan.hayward@arm.com> Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com> David Sherwood <david.sherwood@arm.com>
* optabs.c (widen_leading): Change the type of the mode argument
to scalar_int_mode. Use opt_scalar_int_mode for the mode iterator.
(widen_bswap): Likewise.
(expand_parity): Likewise.
(expand_ctz): Change the type of the mode argument to scalar_int_mode.
(expand_ffs): Likewise.
(epand_unop): Check for scalar integer modes before calling the
above routines.
2017-08-30 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* expr.c (const_scalar_mask_from_tree): Add a mode argument. * expr.c (const_scalar_mask_from_tree): Add a mode argument.
Expand commentary. Expand commentary.
(expand_expr_real_1): Update call accordingly. (expand_expr_real_1): Update call accordingly.
......
...@@ -2129,14 +2129,12 @@ expand_simple_unop (machine_mode mode, enum rtx_code code, rtx op0, ...@@ -2129,14 +2129,12 @@ expand_simple_unop (machine_mode mode, enum rtx_code code, rtx op0,
A similar operation can be used for clrsb. UNOPTAB says which operation A similar operation can be used for clrsb. UNOPTAB says which operation
we are trying to expand. */ we are trying to expand. */
static rtx static rtx
widen_leading (machine_mode mode, rtx op0, rtx target, optab unoptab) widen_leading (scalar_int_mode mode, rtx op0, rtx target, optab unoptab)
{ {
enum mode_class mclass = GET_MODE_CLASS (mode); opt_scalar_int_mode wider_mode_iter;
if (CLASS_HAS_WIDER_MODES_P (mclass)) FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
{
machine_mode wider_mode;
FOR_EACH_WIDER_MODE (wider_mode, mode)
{ {
scalar_int_mode wider_mode = wider_mode_iter.require ();
if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing) if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
{ {
rtx xop0, temp; rtx xop0, temp;
...@@ -2163,7 +2161,6 @@ widen_leading (machine_mode mode, rtx op0, rtx target, optab unoptab) ...@@ -2163,7 +2161,6 @@ widen_leading (machine_mode mode, rtx op0, rtx target, optab unoptab)
return temp; return temp;
} }
} }
}
return 0; return 0;
} }
...@@ -2295,22 +2292,21 @@ expand_doubleword_parity (machine_mode mode, rtx op0, rtx target) ...@@ -2295,22 +2292,21 @@ expand_doubleword_parity (machine_mode mode, rtx op0, rtx target)
as as
(lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */ (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
static rtx static rtx
widen_bswap (machine_mode mode, rtx op0, rtx target) widen_bswap (scalar_int_mode mode, rtx op0, rtx target)
{ {
enum mode_class mclass = GET_MODE_CLASS (mode);
machine_mode wider_mode;
rtx x; rtx x;
rtx_insn *last; rtx_insn *last;
opt_scalar_int_mode wider_mode_iter;
if (!CLASS_HAS_WIDER_MODES_P (mclass)) FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
return NULL_RTX; if (optab_handler (bswap_optab, wider_mode_iter.require ())
!= CODE_FOR_nothing)
break;
FOR_EACH_WIDER_MODE (wider_mode, mode) if (!wider_mode_iter.exists ())
if (optab_handler (bswap_optab, wider_mode) != CODE_FOR_nothing)
goto found;
return NULL_RTX; return NULL_RTX;
found: scalar_int_mode wider_mode = wider_mode_iter.require ();
last = get_last_insn (); last = get_last_insn ();
x = widen_operand (op0, wider_mode, mode, true, true); x = widen_operand (op0, wider_mode, mode, true, true);
...@@ -2361,14 +2357,13 @@ expand_doubleword_bswap (machine_mode mode, rtx op, rtx target) ...@@ -2361,14 +2357,13 @@ expand_doubleword_bswap (machine_mode mode, rtx op, rtx target)
/* Try calculating (parity x) as (and (popcount x) 1), where /* Try calculating (parity x) as (and (popcount x) 1), where
popcount can also be done in a wider mode. */ popcount can also be done in a wider mode. */
static rtx static rtx
expand_parity (machine_mode mode, rtx op0, rtx target) expand_parity (scalar_int_mode mode, rtx op0, rtx target)
{ {
enum mode_class mclass = GET_MODE_CLASS (mode); enum mode_class mclass = GET_MODE_CLASS (mode);
if (CLASS_HAS_WIDER_MODES_P (mclass)) opt_scalar_int_mode wider_mode_iter;
{ FOR_EACH_MODE_FROM (wider_mode_iter, mode)
machine_mode wider_mode;
FOR_EACH_MODE_FROM (wider_mode, mode)
{ {
scalar_int_mode wider_mode = wider_mode_iter.require ();
if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing) if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing)
{ {
rtx xop0, temp; rtx xop0, temp;
...@@ -2398,7 +2393,6 @@ expand_parity (machine_mode mode, rtx op0, rtx target) ...@@ -2398,7 +2393,6 @@ expand_parity (machine_mode mode, rtx op0, rtx target)
delete_insns_since (last); delete_insns_since (last);
} }
} }
}
return 0; return 0;
} }
...@@ -2415,7 +2409,7 @@ expand_parity (machine_mode mode, rtx op0, rtx target) ...@@ -2415,7 +2409,7 @@ expand_parity (machine_mode mode, rtx op0, rtx target)
less convenient for expand_ffs anyway. */ less convenient for expand_ffs anyway. */
static rtx static rtx
expand_ctz (machine_mode mode, rtx op0, rtx target) expand_ctz (scalar_int_mode mode, rtx op0, rtx target)
{ {
rtx_insn *seq; rtx_insn *seq;
rtx temp; rtx temp;
...@@ -2458,7 +2452,7 @@ expand_ctz (machine_mode mode, rtx op0, rtx target) ...@@ -2458,7 +2452,7 @@ expand_ctz (machine_mode mode, rtx op0, rtx target)
may have an undefined value in that case. If they do not give us a may have an undefined value in that case. If they do not give us a
convenient value, we have to generate a test and branch. */ convenient value, we have to generate a test and branch. */
static rtx static rtx
expand_ffs (machine_mode mode, rtx op0, rtx target) expand_ffs (scalar_int_mode mode, rtx op0, rtx target)
{ {
HOST_WIDE_INT val = 0; HOST_WIDE_INT val = 0;
bool defined_at_zero = false; bool defined_at_zero = false;
...@@ -2715,26 +2709,32 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target, ...@@ -2715,26 +2709,32 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
/* Widening (or narrowing) clz needs special treatment. */ /* Widening (or narrowing) clz needs special treatment. */
if (unoptab == clz_optab) if (unoptab == clz_optab)
{ {
temp = widen_leading (mode, op0, target, unoptab); if (is_a <scalar_int_mode> (mode, &int_mode))
{
temp = widen_leading (int_mode, op0, target, unoptab);
if (temp) if (temp)
return temp; return temp;
if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
&& optab_handler (unoptab, word_mode) != CODE_FOR_nothing) && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
{ {
temp = expand_doubleword_clz (mode, op0, target); temp = expand_doubleword_clz (int_mode, op0, target);
if (temp) if (temp)
return temp; return temp;
} }
}
goto try_libcall; goto try_libcall;
} }
if (unoptab == clrsb_optab) if (unoptab == clrsb_optab)
{ {
temp = widen_leading (mode, op0, target, unoptab); if (is_a <scalar_int_mode> (mode, &int_mode))
{
temp = widen_leading (int_mode, op0, target, unoptab);
if (temp) if (temp)
return temp; return temp;
}
goto try_libcall; goto try_libcall;
} }
...@@ -2806,17 +2806,20 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target, ...@@ -2806,17 +2806,20 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
delete_insns_since (last); delete_insns_since (last);
} }
temp = widen_bswap (mode, op0, target); if (is_a <scalar_int_mode> (mode, &int_mode))
{
temp = widen_bswap (int_mode, op0, target);
if (temp) if (temp)
return temp; return temp;
if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
&& optab_handler (unoptab, word_mode) != CODE_FOR_nothing) && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
{ {
temp = expand_doubleword_bswap (mode, op0, target); temp = expand_doubleword_bswap (mode, op0, target);
if (temp) if (temp)
return temp; return temp;
} }
}
goto try_libcall; goto try_libcall;
} }
...@@ -2916,25 +2919,25 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target, ...@@ -2916,25 +2919,25 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
} }
/* Try calculating parity (x) as popcount (x) % 2. */ /* Try calculating parity (x) as popcount (x) % 2. */
if (unoptab == parity_optab) if (unoptab == parity_optab && is_a <scalar_int_mode> (mode, &int_mode))
{ {
temp = expand_parity (mode, op0, target); temp = expand_parity (int_mode, op0, target);
if (temp) if (temp)
return temp; return temp;
} }
/* Try implementing ffs (x) in terms of clz (x). */ /* Try implementing ffs (x) in terms of clz (x). */
if (unoptab == ffs_optab) if (unoptab == ffs_optab && is_a <scalar_int_mode> (mode, &int_mode))
{ {
temp = expand_ffs (mode, op0, target); temp = expand_ffs (int_mode, op0, target);
if (temp) if (temp)
return temp; return temp;
} }
/* Try implementing ctz (x) in terms of clz (x). */ /* Try implementing ctz (x) in terms of clz (x). */
if (unoptab == ctz_optab) if (unoptab == ctz_optab && is_a <scalar_int_mode> (mode, &int_mode))
{ {
temp = expand_ctz (mode, op0, target); temp = expand_ctz (int_mode, op0, target);
if (temp) if (temp)
return temp; return temp;
} }
......
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