Commit a9f6e019 by Segher Boessenkool Committed by Segher Boessenkool

rs6000: Do not allow out of range immediate in vsplt[bhw] (PR86987)

The original AltiVec manuals had the immediate lane number in the
splat instructions as a 5-bit number, but anything too big has no
defined meaning, and gas will choke on it too.  This patch disallows
it in the instruction patterns as well as in the builtins.  This
solves PR86987.


	PR target/86987
	* config/rs6000/altivec.md (altivec_vspltb): Use
	const_0_to_15_operand instead of u5bit_cint_operand.
	(*altivec_vspltb_internal): Ditto.
	(altivec_vspltb_direct): Ditto.
	(altivec_vsplth): Use const_0_to_7_operand instead of
	u5bit_cint_operand.
	(*altivec_vsplth_internal): Ditto.
	(altivec_vsplth_direct): Ditto.
	(altivec_vspltw): Use const_0_to_3_operand instead of
	u5bit_cint_operand.
	(*altivec_vspltw_internal): Ditto.
	(altivec_vspltw_direct): Ditto.
	(altivec_vspltsf): Ditto.
	(*altivec_vspltsf_internal): Ditto.
	* config/rs6000/rs6000.c (rs6000_expand_binop_builtin): Handle the
	various splats with the proper size immediate.  Reorder the various
	cases by ascending size of immediate, and put all such together.

From-SVN: r264584
parent ee850518
2018-09-25 Segher Boessenkool <segher@kernel.crashing.org>
PR target/86987
* config/rs6000/altivec.md (altivec_vspltb): Use
const_0_to_15_operand instead of u5bit_cint_operand.
(*altivec_vspltb_internal): Ditto.
(altivec_vspltb_direct): Ditto.
(altivec_vsplth): Use const_0_to_7_operand instead of
u5bit_cint_operand.
(*altivec_vsplth_internal): Ditto.
(altivec_vsplth_direct): Ditto.
(altivec_vspltw): Use const_0_to_3_operand instead of
u5bit_cint_operand.
(*altivec_vspltw_internal): Ditto.
(altivec_vspltw_direct): Ditto.
(altivec_vspltsf): Ditto.
(*altivec_vspltsf_internal): Ditto.
* config/rs6000/rs6000.c (rs6000_expand_binop_builtin): Handle the
various splats with the proper size immediate. Reorder the various
cases by ascending size of immediate, and put all such together.
2018-09-25 Richard Biener <rguenther@suse.de>
PR debug/83941
......
......@@ -1861,7 +1861,7 @@
(define_expand "altivec_vspltb"
[(use (match_operand:V16QI 0 "register_operand"))
(use (match_operand:V16QI 1 "register_operand"))
(use (match_operand:QI 2 "u5bit_cint_operand"))]
(use (match_operand:QI 2 "const_0_to_15_operand"))]
"TARGET_ALTIVEC"
{
rtvec v = gen_rtvec (1, operands[2]);
......@@ -1877,7 +1877,7 @@
(vec_duplicate:V16QI
(vec_select:QI (match_operand:V16QI 1 "register_operand" "v")
(parallel
[(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
[(match_operand:QI 2 "const_0_to_15_operand" "")]))))]
"TARGET_ALTIVEC"
{
if (!BYTES_BIG_ENDIAN)
......@@ -1890,7 +1890,7 @@
(define_insn "altivec_vspltb_direct"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
(match_operand:QI 2 "u5bit_cint_operand" "i")]
(match_operand:QI 2 "const_0_to_15_operand" "i")]
UNSPEC_VSPLT_DIRECT))]
"TARGET_ALTIVEC"
"vspltb %0,%1,%2"
......@@ -1899,7 +1899,7 @@
(define_expand "altivec_vsplth"
[(use (match_operand:V8HI 0 "register_operand"))
(use (match_operand:V8HI 1 "register_operand"))
(use (match_operand:QI 2 "u5bit_cint_operand"))]
(use (match_operand:QI 2 "const_0_to_7_operand"))]
"TARGET_ALTIVEC"
{
rtvec v = gen_rtvec (1, operands[2]);
......@@ -1915,7 +1915,7 @@
(vec_duplicate:V8HI
(vec_select:HI (match_operand:V8HI 1 "register_operand" "v")
(parallel
[(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
[(match_operand:QI 2 "const_0_to_7_operand" "")]))))]
"TARGET_ALTIVEC"
{
if (!BYTES_BIG_ENDIAN)
......@@ -1928,7 +1928,7 @@
(define_insn "altivec_vsplth_direct"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
(match_operand:QI 2 "u5bit_cint_operand" "i")]
(match_operand:QI 2 "const_0_to_7_operand" "i")]
UNSPEC_VSPLT_DIRECT))]
"TARGET_ALTIVEC"
"vsplth %0,%1,%2"
......@@ -1937,7 +1937,7 @@
(define_expand "altivec_vspltw"
[(use (match_operand:V4SI 0 "register_operand"))
(use (match_operand:V4SI 1 "register_operand"))
(use (match_operand:QI 2 "u5bit_cint_operand"))]
(use (match_operand:QI 2 "const_0_to_3_operand"))]
"TARGET_ALTIVEC"
{
rtvec v = gen_rtvec (1, operands[2]);
......@@ -1953,7 +1953,7 @@
(vec_duplicate:V4SI
(vec_select:SI (match_operand:V4SI 1 "register_operand" "v")
(parallel
[(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
[(match_operand:QI 2 "const_0_to_3_operand" "i")]))))]
"TARGET_ALTIVEC"
{
if (!BYTES_BIG_ENDIAN)
......@@ -1966,7 +1966,7 @@
(define_insn "altivec_vspltw_direct"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:QI 2 "u5bit_cint_operand" "i")]
(match_operand:QI 2 "const_0_to_3_operand" "i")]
UNSPEC_VSPLT_DIRECT))]
"TARGET_ALTIVEC"
"vspltw %0,%1,%2"
......@@ -1975,7 +1975,7 @@
(define_expand "altivec_vspltsf"
[(use (match_operand:V4SF 0 "register_operand"))
(use (match_operand:V4SF 1 "register_operand"))
(use (match_operand:QI 2 "u5bit_cint_operand"))]
(use (match_operand:QI 2 "const_0_to_3_operand"))]
"TARGET_ALTIVEC"
{
rtvec v = gen_rtvec (1, operands[2]);
......@@ -1991,7 +1991,7 @@
(vec_duplicate:V4SF
(vec_select:SF (match_operand:V4SF 1 "register_operand" "v")
(parallel
[(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
[(match_operand:QI 2 "const_0_to_3_operand" "i")]))))]
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
{
if (!BYTES_BIG_ENDIAN)
......
......@@ -13456,13 +13456,58 @@ rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
if (arg0 == error_mark_node || arg1 == error_mark_node)
return const0_rtx;
if (icode == CODE_FOR_altivec_vcfux
if (icode == CODE_FOR_unpackv1ti
|| icode == CODE_FOR_unpackkf
|| icode == CODE_FOR_unpacktf
|| icode == CODE_FOR_unpackif
|| icode == CODE_FOR_unpacktd)
{
/* Only allow 1-bit unsigned literals. */
STRIP_NOPS (arg1);
if (TREE_CODE (arg1) != INTEGER_CST
|| !IN_RANGE (TREE_INT_CST_LOW (arg1), 0, 1))
{
error ("argument 2 must be a 1-bit unsigned literal");
return CONST0_RTX (tmode);
}
}
else if (icode == CODE_FOR_altivec_vspltw)
{
/* Only allow 2-bit unsigned literals. */
STRIP_NOPS (arg1);
if (TREE_CODE (arg1) != INTEGER_CST
|| TREE_INT_CST_LOW (arg1) & ~3)
{
error ("argument 2 must be a 2-bit unsigned literal");
return CONST0_RTX (tmode);
}
}
else if (icode == CODE_FOR_altivec_vsplth)
{
/* Only allow 3-bit unsigned literals. */
STRIP_NOPS (arg1);
if (TREE_CODE (arg1) != INTEGER_CST
|| TREE_INT_CST_LOW (arg1) & ~7)
{
error ("argument 2 must be a 3-bit unsigned literal");
return CONST0_RTX (tmode);
}
}
else if (icode == CODE_FOR_altivec_vspltb)
{
/* Only allow 4-bit unsigned literals. */
STRIP_NOPS (arg1);
if (TREE_CODE (arg1) != INTEGER_CST
|| TREE_INT_CST_LOW (arg1) & ~15)
{
error ("argument 2 must be a 4-bit unsigned literal");
return CONST0_RTX (tmode);
}
}
else if (icode == CODE_FOR_altivec_vcfux
|| icode == CODE_FOR_altivec_vcfsx
|| icode == CODE_FOR_altivec_vctsxs
|| icode == CODE_FOR_altivec_vctuxs
|| icode == CODE_FOR_altivec_vspltb
|| icode == CODE_FOR_altivec_vsplth
|| icode == CODE_FOR_altivec_vspltw)
|| icode == CODE_FOR_altivec_vctuxs)
{
/* Only allow 5-bit unsigned literals. */
STRIP_NOPS (arg1);
......@@ -13507,21 +13552,6 @@ rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
return CONST0_RTX (tmode);
}
}
else if (icode == CODE_FOR_unpackv1ti
|| icode == CODE_FOR_unpackkf
|| icode == CODE_FOR_unpacktf
|| icode == CODE_FOR_unpackif
|| icode == CODE_FOR_unpacktd)
{
/* Only allow 1-bit unsigned literals. */
STRIP_NOPS (arg1);
if (TREE_CODE (arg1) != INTEGER_CST
|| !IN_RANGE (TREE_INT_CST_LOW (arg1), 0, 1))
{
error ("argument 2 must be a 1-bit unsigned literal");
return CONST0_RTX (tmode);
}
}
if (target == 0
|| GET_MODE (target) != tmode
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