From a9f6e019d15819f52b312e1b10cd460b59b57780 Mon Sep 17 00:00:00 2001 From: Segher Boessenkool Date: Wed, 26 Sep 2018 00:09:38 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 21 +++++++++++ gcc/config/rs6000/altivec.md | 22 ++++++------ gcc/config/rs6000/rs6000.c | 70 +++++++++++++++++++++++++----------- 3 files changed, 82 insertions(+), 31 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6be143e9f18..12e7789991a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2018-09-25 Segher Boessenkool + + 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 PR debug/83941 diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index 1ddf5802607..345be09ceff 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -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) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 5c7ab2b24e2..baa585191b0 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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 -- 2.30.2