comparison gcc/simplify-rtx.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 /* RTL simplification functions for GNU compiler. 1 /* RTL simplification functions for GNU compiler.
2 Copyright (C) 1987-2018 Free Software Foundation, Inc. 2 Copyright (C) 1987-2020 Free Software Foundation, Inc.
3 3
4 This file is part of GCC. 4 This file is part of GCC.
5 5
6 GCC is free software; you can redistribute it and/or modify it under 6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free 7 the terms of the GNU General Public License as published by the Free
33 #include "diagnostic-core.h" 33 #include "diagnostic-core.h"
34 #include "varasm.h" 34 #include "varasm.h"
35 #include "flags.h" 35 #include "flags.h"
36 #include "selftest.h" 36 #include "selftest.h"
37 #include "selftest-rtl.h" 37 #include "selftest-rtl.h"
38 #include "rtx-vector-builder.h"
38 39
39 /* Simplification and canonicalization of RTL. */ 40 /* Simplification and canonicalization of RTL. */
40 41
41 /* Much code operates on (low, high) pairs; the low value is an 42 /* Much code operates on (low, high) pairs; the low value is an
42 unsigned wide int, the high value a signed wide int. We 43 unsigned wide int, the high value a signed wide int. We
43 occasionally need to sign extend from low to high as if low were a 44 occasionally need to sign extend from low to high as if low were a
44 signed wide int. */ 45 signed wide int. */
45 #define HWI_SIGN_EXTEND(low) \ 46 #define HWI_SIGN_EXTEND(low) \
46 ((((HOST_WIDE_INT) low) < 0) ? HOST_WIDE_INT_M1 : HOST_WIDE_INT_0) 47 ((((HOST_WIDE_INT) low) < 0) ? HOST_WIDE_INT_M1 : HOST_WIDE_INT_0)
47 48
48 static rtx neg_const_int (machine_mode, const_rtx);
49 static bool plus_minus_operand_p (const_rtx); 49 static bool plus_minus_operand_p (const_rtx);
50 static rtx simplify_plus_minus (enum rtx_code, machine_mode, rtx, rtx); 50 static rtx simplify_plus_minus (enum rtx_code, machine_mode, rtx, rtx);
51 static rtx simplify_associative_operation (enum rtx_code, machine_mode, 51 static rtx simplify_associative_operation (enum rtx_code, machine_mode,
52 rtx, rtx); 52 rtx, rtx);
53 static rtx simplify_relational_operation_1 (enum rtx_code, machine_mode, 53 static rtx simplify_relational_operation_1 (enum rtx_code, machine_mode,
54 machine_mode, rtx, rtx); 54 machine_mode, rtx, rtx);
55 static rtx simplify_unary_operation_1 (enum rtx_code, machine_mode, rtx); 55 static rtx simplify_unary_operation_1 (enum rtx_code, machine_mode, rtx);
56 static rtx simplify_binary_operation_1 (enum rtx_code, machine_mode, 56 static rtx simplify_binary_operation_1 (enum rtx_code, machine_mode,
57 rtx, rtx, rtx, rtx); 57 rtx, rtx, rtx, rtx);
58 58
59 /* Negate a CONST_INT rtx. */ 59 /* Negate I, which satisfies poly_int_rtx_p. MODE is the mode of I. */
60
60 static rtx 61 static rtx
61 neg_const_int (machine_mode mode, const_rtx i) 62 neg_poly_int_rtx (machine_mode mode, const_rtx i)
62 { 63 {
63 unsigned HOST_WIDE_INT val = -UINTVAL (i); 64 return immed_wide_int_const (-wi::to_poly_wide (i, mode), mode);
64
65 if (!HWI_COMPUTABLE_MODE_P (mode)
66 && val == UINTVAL (i))
67 return simplify_const_unary_operation (NEG, mode, CONST_CAST_RTX (i),
68 mode);
69 return gen_int_mode (val, mode);
70 } 65 }
71 66
72 /* Test whether expression, X, is an immediate constant that represents 67 /* Test whether expression, X, is an immediate constant that represents
73 the most significant bit of machine mode MODE. */ 68 the most significant bit of machine mode MODE. */
74 69
1502 && GET_CODE (XEXP (op, 0)) == ASHIFT 1497 && GET_CODE (XEXP (op, 0)) == ASHIFT
1503 && is_a <scalar_int_mode> (mode, &int_mode) 1498 && is_a <scalar_int_mode> (mode, &int_mode)
1504 && CONST_INT_P (XEXP (op, 1)) 1499 && CONST_INT_P (XEXP (op, 1))
1505 && XEXP (XEXP (op, 0), 1) == XEXP (op, 1) 1500 && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1506 && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)), 1501 && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1507 GET_MODE_BITSIZE (op_mode) > INTVAL (XEXP (op, 1)))) 1502 GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1508 { 1503 {
1509 scalar_int_mode tmode; 1504 scalar_int_mode tmode;
1510 gcc_assert (GET_MODE_BITSIZE (int_mode) 1505 gcc_assert (GET_MODE_PRECISION (int_mode)
1511 > GET_MODE_BITSIZE (op_mode)); 1506 > GET_MODE_PRECISION (op_mode));
1512 if (int_mode_for_size (GET_MODE_BITSIZE (op_mode) 1507 if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1513 - INTVAL (XEXP (op, 1)), 1).exists (&tmode)) 1508 - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1514 { 1509 {
1515 rtx inner = 1510 rtx inner =
1516 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0)); 1511 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1517 if (inner) 1512 if (inner)
1733 gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER 1728 gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
1734 (GET_MODE (op))); 1729 (GET_MODE (op)));
1735 } 1730 }
1736 if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op)) 1731 if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
1737 return gen_const_vec_duplicate (mode, op); 1732 return gen_const_vec_duplicate (mode, op);
1738 unsigned int n_elts;
1739 if (GET_CODE (op) == CONST_VECTOR 1733 if (GET_CODE (op) == CONST_VECTOR
1740 && GET_MODE_NUNITS (mode).is_constant (&n_elts)) 1734 && (CONST_VECTOR_DUPLICATE_P (op)
1741 { 1735 || CONST_VECTOR_NUNITS (op).is_constant ()))
1742 /* This must be constant if we're duplicating it to a constant 1736 {
1743 number of elements. */ 1737 unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
1744 unsigned int in_n_elts = CONST_VECTOR_NUNITS (op).to_constant (); 1738 ? CONST_VECTOR_NPATTERNS (op)
1745 gcc_assert (in_n_elts < n_elts); 1739 : CONST_VECTOR_NUNITS (op).to_constant ());
1746 gcc_assert ((n_elts % in_n_elts) == 0); 1740 gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
1747 rtvec v = rtvec_alloc (n_elts); 1741 rtx_vector_builder builder (mode, npatterns, 1);
1748 for (unsigned i = 0; i < n_elts; i++) 1742 for (unsigned i = 0; i < npatterns; i++)
1749 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op, i % in_n_elts); 1743 builder.quick_push (CONST_VECTOR_ELT (op, i));
1750 return gen_rtx_CONST_VECTOR (mode, v); 1744 return builder.build ();
1751 } 1745 }
1752 } 1746 }
1753 1747
1754 if (VECTOR_MODE_P (mode) && GET_CODE (op) == CONST_VECTOR) 1748 if (VECTOR_MODE_P (mode)
1755 { 1749 && GET_CODE (op) == CONST_VECTOR
1756 unsigned int n_elts; 1750 && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
1757 if (!CONST_VECTOR_NUNITS (op).is_constant (&n_elts)) 1751 {
1758 return NULL_RTX; 1752 gcc_assert (GET_MODE (op) == op_mode);
1759 1753
1760 machine_mode opmode = GET_MODE (op); 1754 rtx_vector_builder builder;
1761 gcc_assert (known_eq (GET_MODE_NUNITS (mode), n_elts)); 1755 if (!builder.new_unary_operation (mode, op, false))
1762 gcc_assert (known_eq (GET_MODE_NUNITS (opmode), n_elts)); 1756 return 0;
1763 1757
1764 rtvec v = rtvec_alloc (n_elts); 1758 unsigned int count = builder.encoded_nelts ();
1765 unsigned int i; 1759 for (unsigned int i = 0; i < count; i++)
1766
1767 for (i = 0; i < n_elts; i++)
1768 { 1760 {
1769 rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode), 1761 rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
1770 CONST_VECTOR_ELT (op, i), 1762 CONST_VECTOR_ELT (op, i),
1771 GET_MODE_INNER (opmode)); 1763 GET_MODE_INNER (op_mode));
1772 if (!x || !valid_for_const_vector_p (mode, x)) 1764 if (!x || !valid_for_const_vector_p (mode, x))
1773 return 0; 1765 return 0;
1774 RTVEC_ELT (v, i) = x; 1766 builder.quick_push (x);
1775 } 1767 }
1776 return gen_rtx_CONST_VECTOR (mode, v); 1768 return builder.build ();
1777 } 1769 }
1778 1770
1779 /* The order of these tests is critical so that, for example, we don't 1771 /* The order of these tests is critical so that, for example, we don't
1780 check the wrong mode (input vs. output) for a conversion operation, 1772 check the wrong mode (input vs. output) for a conversion operation,
1781 such as FIX. At some point, this should be simplified. */ 1773 such as FIX. At some point, this should be simplified. */
1830 } 1822 }
1831 1823
1832 if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode)) 1824 if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
1833 { 1825 {
1834 unsigned int width = GET_MODE_PRECISION (result_mode); 1826 unsigned int width = GET_MODE_PRECISION (result_mode);
1827 if (width > MAX_BITSIZE_MODE_ANY_INT)
1828 return 0;
1829
1835 wide_int result; 1830 wide_int result;
1836 scalar_int_mode imode = (op_mode == VOIDmode 1831 scalar_int_mode imode = (op_mode == VOIDmode
1837 ? result_mode 1832 ? result_mode
1838 : as_a <scalar_int_mode> (op_mode)); 1833 : as_a <scalar_int_mode> (op_mode));
1839 rtx_mode_t op0 = rtx_mode_t (op, imode); 1834 rtx_mode_t op0 = rtx_mode_t (op, imode);
1974 else if (CONST_DOUBLE_AS_FLOAT_P (op) 1969 else if (CONST_DOUBLE_AS_FLOAT_P (op)
1975 && SCALAR_FLOAT_MODE_P (GET_MODE (op)) 1970 && SCALAR_FLOAT_MODE_P (GET_MODE (op))
1976 && is_int_mode (mode, &result_mode)) 1971 && is_int_mode (mode, &result_mode))
1977 { 1972 {
1978 unsigned int width = GET_MODE_PRECISION (result_mode); 1973 unsigned int width = GET_MODE_PRECISION (result_mode);
1974 if (width > MAX_BITSIZE_MODE_ANY_INT)
1975 return 0;
1976
1979 /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX 1977 /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
1980 operators are intentionally left unspecified (to ease implementation 1978 operators are intentionally left unspecified (to ease implementation
1981 by target backends), for consistency, this routine implements the 1979 by target backends), for consistency, this routine implements the
1982 same semantics for constant folding as used by the middle-end. */ 1980 same semantics for constant folding as used by the middle-end. */
1983 1981
2131 } 2129 }
2132 2130
2133 return 0; 2131 return 0;
2134 } 2132 }
2135 2133
2134 /* Return a mask describing the COMPARISON. */
2135 static int
2136 comparison_to_mask (enum rtx_code comparison)
2137 {
2138 switch (comparison)
2139 {
2140 case LT:
2141 return 8;
2142 case GT:
2143 return 4;
2144 case EQ:
2145 return 2;
2146 case UNORDERED:
2147 return 1;
2148
2149 case LTGT:
2150 return 12;
2151 case LE:
2152 return 10;
2153 case GE:
2154 return 6;
2155 case UNLT:
2156 return 9;
2157 case UNGT:
2158 return 5;
2159 case UNEQ:
2160 return 3;
2161
2162 case ORDERED:
2163 return 14;
2164 case NE:
2165 return 13;
2166 case UNLE:
2167 return 11;
2168 case UNGE:
2169 return 7;
2170
2171 default:
2172 gcc_unreachable ();
2173 }
2174 }
2175
2176 /* Return a comparison corresponding to the MASK. */
2177 static enum rtx_code
2178 mask_to_comparison (int mask)
2179 {
2180 switch (mask)
2181 {
2182 case 8:
2183 return LT;
2184 case 4:
2185 return GT;
2186 case 2:
2187 return EQ;
2188 case 1:
2189 return UNORDERED;
2190
2191 case 12:
2192 return LTGT;
2193 case 10:
2194 return LE;
2195 case 6:
2196 return GE;
2197 case 9:
2198 return UNLT;
2199 case 5:
2200 return UNGT;
2201 case 3:
2202 return UNEQ;
2203
2204 case 14:
2205 return ORDERED;
2206 case 13:
2207 return NE;
2208 case 11:
2209 return UNLE;
2210 case 7:
2211 return UNGE;
2212
2213 default:
2214 gcc_unreachable ();
2215 }
2216 }
2217
2218 /* Simplify a logical operation CODE with result mode MODE, operating on OP0
2219 and OP1, which should be both relational operations. Return 0 if no such
2220 simplification is possible. */
2221 rtx
2222 simplify_logical_relational_operation (enum rtx_code code, machine_mode mode,
2223 rtx op0, rtx op1)
2224 {
2225 /* We only handle IOR of two relational operations. */
2226 if (code != IOR)
2227 return 0;
2228
2229 if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
2230 return 0;
2231
2232 if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2233 && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
2234 return 0;
2235
2236 enum rtx_code code0 = GET_CODE (op0);
2237 enum rtx_code code1 = GET_CODE (op1);
2238
2239 /* We don't handle unsigned comparisons currently. */
2240 if (code0 == LTU || code0 == GTU || code0 == LEU || code0 == GEU)
2241 return 0;
2242 if (code1 == LTU || code1 == GTU || code1 == LEU || code1 == GEU)
2243 return 0;
2244
2245 int mask0 = comparison_to_mask (code0);
2246 int mask1 = comparison_to_mask (code1);
2247
2248 int mask = mask0 | mask1;
2249
2250 if (mask == 15)
2251 return const_true_rtx;
2252
2253 code = mask_to_comparison (mask);
2254
2255 op0 = XEXP (op1, 0);
2256 op1 = XEXP (op1, 1);
2257
2258 return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
2259 }
2136 2260
2137 /* Simplify a binary operation CODE with result mode MODE, operating on OP0 2261 /* Simplify a binary operation CODE with result mode MODE, operating on OP0
2138 and OP1. Return 0 if no simplification is possible. 2262 and OP1. Return 0 if no simplification is possible.
2139 2263
2140 Don't use this for relational operations such as EQ or LT. 2264 Don't use this for relational operations such as EQ or LT.
2547 || GET_CODE (op0) == LABEL_REF) 2671 || GET_CODE (op0) == LABEL_REF)
2548 && poly_int_rtx_p (op1, &offset)) 2672 && poly_int_rtx_p (op1, &offset))
2549 return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode)); 2673 return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
2550 2674
2551 /* Don't let a relocatable value get a negative coeff. */ 2675 /* Don't let a relocatable value get a negative coeff. */
2552 if (CONST_INT_P (op1) && GET_MODE (op0) != VOIDmode) 2676 if (poly_int_rtx_p (op1) && GET_MODE (op0) != VOIDmode)
2553 return simplify_gen_binary (PLUS, mode, 2677 return simplify_gen_binary (PLUS, mode,
2554 op0, 2678 op0,
2555 neg_const_int (mode, op1)); 2679 neg_poly_int_rtx (mode, op1));
2556 2680
2557 /* (x - (x & y)) -> (x & ~y) */ 2681 /* (x - (x & y)) -> (x & ~y) */
2558 if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND) 2682 if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
2559 { 2683 {
2560 if (rtx_equal_p (op0, XEXP (op1, 0))) 2684 if (rtx_equal_p (op0, XEXP (op1, 0)))
2855 plus_constant (mode, XEXP (op0, 0), 2979 plus_constant (mode, XEXP (op0, 0),
2856 mask), 2980 mask),
2857 XEXP (op0, 1)); 2981 XEXP (op0, 1));
2858 } 2982 }
2859 2983
2984 /* The following happens with bitfield merging.
2985 (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
2986 if (GET_CODE (op0) == AND
2987 && GET_CODE (op1) == AND
2988 && CONST_INT_P (XEXP (op0, 1))
2989 && CONST_INT_P (XEXP (op1, 1))
2990 && (INTVAL (XEXP (op0, 1))
2991 == ~INTVAL (XEXP (op1, 1))))
2992 {
2993 /* The IOR may be on both sides. */
2994 rtx top0 = NULL_RTX, top1 = NULL_RTX;
2995 if (GET_CODE (XEXP (op1, 0)) == IOR)
2996 top0 = op0, top1 = op1;
2997 else if (GET_CODE (XEXP (op0, 0)) == IOR)
2998 top0 = op1, top1 = op0;
2999 if (top0 && top1)
3000 {
3001 /* X may be on either side of the inner IOR. */
3002 rtx tem = NULL_RTX;
3003 if (rtx_equal_p (XEXP (top0, 0),
3004 XEXP (XEXP (top1, 0), 0)))
3005 tem = XEXP (XEXP (top1, 0), 1);
3006 else if (rtx_equal_p (XEXP (top0, 0),
3007 XEXP (XEXP (top1, 0), 1)))
3008 tem = XEXP (XEXP (top1, 0), 0);
3009 if (tem)
3010 return simplify_gen_binary (IOR, mode, XEXP (top0, 0),
3011 simplify_gen_binary
3012 (AND, mode, tem, XEXP (top1, 1)));
3013 }
3014 }
3015
2860 tem = simplify_byte_swapping_operation (code, mode, op0, op1); 3016 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
2861 if (tem) 3017 if (tem)
2862 return tem; 3018 return tem;
2863 3019
2864 tem = simplify_associative_operation (code, mode, op0, op1); 3020 tem = simplify_associative_operation (code, mode, op0, op1);
3021 if (tem)
3022 return tem;
3023
3024 tem = simplify_logical_relational_operation (code, mode, op0, op1);
2865 if (tem) 3025 if (tem)
2866 return tem; 3026 return tem;
2867 break; 3027 break;
2868 3028
2869 case XOR: 3029 case XOR:
3485 == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode)) 3645 == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
3486 && subreg_lowpart_p (op0)) 3646 && subreg_lowpart_p (op0))
3487 { 3647 {
3488 rtx tmp = gen_int_shift_amount 3648 rtx tmp = gen_int_shift_amount
3489 (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1)); 3649 (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
3490 tmp = simplify_gen_binary (code, inner_mode, 3650
3491 XEXP (SUBREG_REG (op0), 0), 3651 /* Combine would usually zero out the value when combining two
3492 tmp); 3652 local shifts and the range becomes larger or equal to the mode.
3653 However since we fold away one of the shifts here combine won't
3654 see it so we should immediately zero the result if it's out of
3655 range. */
3656 if (code == LSHIFTRT
3657 && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
3658 tmp = const0_rtx;
3659 else
3660 tmp = simplify_gen_binary (code,
3661 inner_mode,
3662 XEXP (SUBREG_REG (op0), 0),
3663 tmp);
3664
3493 return lowpart_subreg (int_mode, tmp, inner_mode); 3665 return lowpart_subreg (int_mode, tmp, inner_mode);
3494 } 3666 }
3495 3667
3496 if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1)) 3668 if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
3497 { 3669 {
4025 } 4197 }
4026 4198
4027 return 0; 4199 return 0;
4028 } 4200 }
4029 4201
4202 /* Return true if binary operation OP distributes over addition in operand
4203 OPNO, with the other operand being held constant. OPNO counts from 1. */
4204
4205 static bool
4206 distributes_over_addition_p (rtx_code op, int opno)
4207 {
4208 switch (op)
4209 {
4210 case PLUS:
4211 case MINUS:
4212 case MULT:
4213 return true;
4214
4215 case ASHIFT:
4216 return opno == 1;
4217
4218 default:
4219 return false;
4220 }
4221 }
4222
4030 rtx 4223 rtx
4031 simplify_const_binary_operation (enum rtx_code code, machine_mode mode, 4224 simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
4032 rtx op0, rtx op1) 4225 rtx op0, rtx op1)
4033 { 4226 {
4034 if (VECTOR_MODE_P (mode) 4227 if (VECTOR_MODE_P (mode)
4035 && code != VEC_CONCAT 4228 && code != VEC_CONCAT
4036 && GET_CODE (op0) == CONST_VECTOR 4229 && GET_CODE (op0) == CONST_VECTOR
4037 && GET_CODE (op1) == CONST_VECTOR) 4230 && GET_CODE (op1) == CONST_VECTOR)
4038 { 4231 {
4039 unsigned int n_elts; 4232 bool step_ok_p;
4040 if (!CONST_VECTOR_NUNITS (op0).is_constant (&n_elts)) 4233 if (CONST_VECTOR_STEPPED_P (op0)
4041 return NULL_RTX; 4234 && CONST_VECTOR_STEPPED_P (op1))
4042 4235 /* We can operate directly on the encoding if:
4043 gcc_assert (known_eq (n_elts, CONST_VECTOR_NUNITS (op1))); 4236
4044 gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode))); 4237 a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
4045 rtvec v = rtvec_alloc (n_elts); 4238 implies
4046 unsigned int i; 4239 (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
4047 4240
4048 for (i = 0; i < n_elts; i++) 4241 Addition and subtraction are the supported operators
4242 for which this is true. */
4243 step_ok_p = (code == PLUS || code == MINUS);
4244 else if (CONST_VECTOR_STEPPED_P (op0))
4245 /* We can operate directly on stepped encodings if:
4246
4247 a3 - a2 == a2 - a1
4248 implies:
4249 (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
4250
4251 which is true if (x -> x op c) distributes over addition. */
4252 step_ok_p = distributes_over_addition_p (code, 1);
4253 else
4254 /* Similarly in reverse. */
4255 step_ok_p = distributes_over_addition_p (code, 2);
4256 rtx_vector_builder builder;
4257 if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
4258 return 0;
4259
4260 unsigned int count = builder.encoded_nelts ();
4261 for (unsigned int i = 0; i < count; i++)
4049 { 4262 {
4050 rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode), 4263 rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
4051 CONST_VECTOR_ELT (op0, i), 4264 CONST_VECTOR_ELT (op0, i),
4052 CONST_VECTOR_ELT (op1, i)); 4265 CONST_VECTOR_ELT (op1, i));
4053 if (!x || !valid_for_const_vector_p (mode, x)) 4266 if (!x || !valid_for_const_vector_p (mode, x))
4054 return 0; 4267 return 0;
4055 RTVEC_ELT (v, i) = x; 4268 builder.quick_push (x);
4056 } 4269 }
4057 4270 return builder.build ();
4058 return gen_rtx_CONST_VECTOR (mode, v);
4059 } 4271 }
4060 4272
4061 if (VECTOR_MODE_P (mode) 4273 if (VECTOR_MODE_P (mode)
4062 && code == VEC_CONCAT 4274 && code == VEC_CONCAT
4063 && (CONST_SCALAR_INT_P (op0) 4275 && (CONST_SCALAR_INT_P (op0)
4226 4438
4227 /* We can fold some multi-word operations. */ 4439 /* We can fold some multi-word operations. */
4228 scalar_int_mode int_mode; 4440 scalar_int_mode int_mode;
4229 if (is_a <scalar_int_mode> (mode, &int_mode) 4441 if (is_a <scalar_int_mode> (mode, &int_mode)
4230 && CONST_SCALAR_INT_P (op0) 4442 && CONST_SCALAR_INT_P (op0)
4231 && CONST_SCALAR_INT_P (op1)) 4443 && CONST_SCALAR_INT_P (op1)
4444 && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
4232 { 4445 {
4233 wide_int result; 4446 wide_int result;
4234 wi::overflow_type overflow; 4447 wi::overflow_type overflow;
4235 rtx_mode_t pop0 = rtx_mode_t (op0, int_mode); 4448 rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
4236 rtx_mode_t pop1 = rtx_mode_t (op1, int_mode); 4449 rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
4547 changed = 1; 4760 changed = 1;
4548 canonicalized = 1; 4761 canonicalized = 1;
4549 } 4762 }
4550 break; 4763 break;
4551 4764
4552 case CONST_INT: 4765 CASE_CONST_SCALAR_INT:
4766 case CONST_POLY_INT:
4553 n_constants++; 4767 n_constants++;
4554 if (this_neg) 4768 if (this_neg)
4555 { 4769 {
4556 ops[i].op = neg_const_int (mode, this_op); 4770 ops[i].op = neg_poly_int_rtx (mode, this_op);
4557 ops[i].neg = 0; 4771 ops[i].neg = 0;
4558 changed = 1; 4772 changed = 1;
4559 canonicalized = 1; 4773 canonicalized = 1;
4560 } 4774 }
4561 break; 4775 break;
4676 && XEXP (XEXP (tem, 0), 1) == rhs) 4890 && XEXP (XEXP (tem, 0), 1) == rhs)
4677 break; 4891 break;
4678 lneg &= rneg; 4892 lneg &= rneg;
4679 if (GET_CODE (tem) == NEG) 4893 if (GET_CODE (tem) == NEG)
4680 tem = XEXP (tem, 0), lneg = !lneg; 4894 tem = XEXP (tem, 0), lneg = !lneg;
4681 if (CONST_INT_P (tem) && lneg) 4895 if (poly_int_rtx_p (tem) && lneg)
4682 tem = neg_const_int (mode, tem), lneg = 0; 4896 tem = neg_poly_int_rtx (mode, tem), lneg = 0;
4683 4897
4684 ops[i].op = tem; 4898 ops[i].op = tem;
4685 ops[i].neg = lneg; 4899 ops[i].neg = lneg;
4686 ops[j].op = NULL_RTX; 4900 ops[j].op = NULL_RTX;
4687 changed = 1; 4901 changed = 1;
4736 The combination loop should have ensured that there is exactly 4950 The combination loop should have ensured that there is exactly
4737 one CONST_INT, and the sort will have ensured that it is last 4951 one CONST_INT, and the sort will have ensured that it is last
4738 in the array and that any other constant will be next-to-last. */ 4952 in the array and that any other constant will be next-to-last. */
4739 4953
4740 if (n_ops > 1 4954 if (n_ops > 1
4741 && CONST_INT_P (ops[n_ops - 1].op) 4955 && poly_int_rtx_p (ops[n_ops - 1].op)
4742 && CONSTANT_P (ops[n_ops - 2].op)) 4956 && CONSTANT_P (ops[n_ops - 2].op))
4743 { 4957 {
4744 rtx value = ops[n_ops - 1].op; 4958 rtx value = ops[n_ops - 1].op;
4745 if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg) 4959 if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
4746 value = neg_const_int (mode, value); 4960 value = neg_poly_int_rtx (mode, value);
4747 if (CONST_INT_P (value)) 4961 if (CONST_INT_P (value))
4748 { 4962 {
4749 ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op, 4963 ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
4750 INTVAL (value)); 4964 INTVAL (value));
4751 n_ops--; 4965 n_ops--;
4840 } 5054 }
4841 #else 5055 #else
4842 return NULL_RTX; 5056 return NULL_RTX;
4843 #endif 5057 #endif
4844 } 5058 }
5059 /* For vector comparison with scalar int result, it is unknown
5060 if the target means here a comparison into an integral bitmask,
5061 or comparison where all comparisons true mean const_true_rtx
5062 whole result, or where any comparisons true mean const_true_rtx
5063 whole result. For const0_rtx all the cases are the same. */
5064 if (VECTOR_MODE_P (cmp_mode)
5065 && SCALAR_INT_MODE_P (mode)
5066 && tem == const_true_rtx)
5067 return NULL_RTX;
4845 5068
4846 return tem; 5069 return tem;
4847 } 5070 }
4848 5071
4849 /* For the following tests, ensure const0_rtx is op1. */ 5072 /* For the following tests, ensure const0_rtx is op1. */
5186 gcc_unreachable (); 5409 gcc_unreachable ();
5187 } 5410 }
5188 } 5411 }
5189 5412
5190 /* Check if the given comparison (done in the given MODE) is actually 5413 /* Check if the given comparison (done in the given MODE) is actually
5191 a tautology or a contradiction. If the mode is VOID_mode, the 5414 a tautology or a contradiction. If the mode is VOIDmode, the
5192 comparison is done in "infinite precision". If no simplification 5415 comparison is done in "infinite precision". If no simplification
5193 is possible, this function returns zero. Otherwise, it returns 5416 is possible, this function returns zero. Otherwise, it returns
5194 either const_true_rtx or const0_rtx. */ 5417 either const_true_rtx or const0_rtx. */
5195 5418
5196 rtx 5419 rtx
5613 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)) 5836 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
5614 { 5837 {
5615 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op); 5838 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
5616 rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op); 5839 rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
5617 if (top0 || top1) 5840 if (top0 || top1)
5618 return simplify_gen_binary (GET_CODE (x), GET_MODE (x), 5841 {
5619 top0 ? top0 : XEXP (x, 0), 5842 if (COMPARISON_P (x))
5620 top1 ? top1 : XEXP (x, 1)); 5843 return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
5844 GET_MODE (XEXP (x, 0)) != VOIDmode
5845 ? GET_MODE (XEXP (x, 0))
5846 : GET_MODE (XEXP (x, 1)),
5847 top0 ? top0 : XEXP (x, 0),
5848 top1 ? top1 : XEXP (x, 1));
5849 else
5850 return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
5851 top0 ? top0 : XEXP (x, 0),
5852 top1 ? top1 : XEXP (x, 1));
5853 }
5621 } 5854 }
5622 if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY 5855 if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
5623 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0))) 5856 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
5624 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits) 5857 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
5625 && VECTOR_MODE_P (GET_MODE (XEXP (x, 1))) 5858 && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
6029 && !side_effects_p (op2) && !side_effects_p (op1)) 6262 && !side_effects_p (op2) && !side_effects_p (op1))
6030 return op0; 6263 return op0;
6031 6264
6032 if (!side_effects_p (op2)) 6265 if (!side_effects_p (op2))
6033 { 6266 {
6034 rtx top0 = simplify_merge_mask (op0, op2, 0); 6267 rtx top0
6035 rtx top1 = simplify_merge_mask (op1, op2, 1); 6268 = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
6269 rtx top1
6270 = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
6036 if (top0 || top1) 6271 if (top0 || top1)
6037 return simplify_gen_ternary (code, mode, mode, 6272 return simplify_gen_ternary (code, mode, mode,
6038 top0 ? top0 : op0, 6273 top0 ? top0 : op0,
6039 top1 ? top1 : op1, op2); 6274 top1 ? top1 : op1, op2);
6040 } 6275 }
6046 } 6281 }
6047 6282
6048 return 0; 6283 return 0;
6049 } 6284 }
6050 6285
6051 /* Evaluate a SUBREG of a CONST_INT or CONST_WIDE_INT or CONST_DOUBLE 6286 /* Try to calculate NUM_BYTES bytes of the target memory image of X,
6052 or CONST_FIXED or CONST_VECTOR, returning another CONST_INT or 6287 starting at byte FIRST_BYTE. Return true on success and add the
6053 CONST_WIDE_INT or CONST_DOUBLE or CONST_FIXED or CONST_VECTOR. 6288 bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
6054 6289 that the bytes follow target memory order. Leave BYTES unmodified
6055 Works by unpacking INNER_BYTES bytes of OP into a collection of 8-bit values 6290 on failure.
6056 represented as a little-endian array of 'unsigned char', selecting by BYTE, 6291
6057 and then repacking them again for OUTERMODE. If OP is a CONST_VECTOR, 6292 MODE is the mode of X. The caller must reserve NUM_BYTES bytes in
6058 FIRST_ELEM is the number of the first element to extract, otherwise 6293 BYTES before calling this function. */
6059 FIRST_ELEM is ignored. */ 6294
6295 bool
6296 native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
6297 unsigned int first_byte, unsigned int num_bytes)
6298 {
6299 /* Check the mode is sensible. */
6300 gcc_assert (GET_MODE (x) == VOIDmode
6301 ? is_a <scalar_int_mode> (mode)
6302 : mode == GET_MODE (x));
6303
6304 if (GET_CODE (x) == CONST_VECTOR)
6305 {
6306 /* CONST_VECTOR_ELT follows target memory order, so no shuffling
6307 is necessary. The only complication is that MODE_VECTOR_BOOL
6308 vectors can have several elements per byte. */
6309 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
6310 GET_MODE_NUNITS (mode));
6311 unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
6312 if (elt_bits < BITS_PER_UNIT)
6313 {
6314 /* This is the only case in which elements can be smaller than
6315 a byte. */
6316 gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
6317 for (unsigned int i = 0; i < num_bytes; ++i)
6318 {
6319 target_unit value = 0;
6320 for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
6321 {
6322 value |= (INTVAL (CONST_VECTOR_ELT (x, elt)) & 1) << j;
6323 elt += 1;
6324 }
6325 bytes.quick_push (value);
6326 }
6327 return true;
6328 }
6329
6330 unsigned int start = bytes.length ();
6331 unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
6332 /* Make FIRST_BYTE relative to ELT. */
6333 first_byte %= elt_bytes;
6334 while (num_bytes > 0)
6335 {
6336 /* Work out how many bytes we want from element ELT. */
6337 unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
6338 if (!native_encode_rtx (GET_MODE_INNER (mode),
6339 CONST_VECTOR_ELT (x, elt), bytes,
6340 first_byte, chunk_bytes))
6341 {
6342 bytes.truncate (start);
6343 return false;
6344 }
6345 elt += 1;
6346 first_byte = 0;
6347 num_bytes -= chunk_bytes;
6348 }
6349 return true;
6350 }
6351
6352 /* All subsequent cases are limited to scalars. */
6353 scalar_mode smode;
6354 if (!is_a <scalar_mode> (mode, &smode))
6355 return false;
6356
6357 /* Make sure that the region is in range. */
6358 unsigned int end_byte = first_byte + num_bytes;
6359 unsigned int mode_bytes = GET_MODE_SIZE (smode);
6360 gcc_assert (end_byte <= mode_bytes);
6361
6362 if (CONST_SCALAR_INT_P (x))
6363 {
6364 /* The target memory layout is affected by both BYTES_BIG_ENDIAN
6365 and WORDS_BIG_ENDIAN. Use the subreg machinery to get the lsb
6366 position of each byte. */
6367 rtx_mode_t value (x, smode);
6368 wide_int_ref value_wi (value);
6369 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
6370 {
6371 /* Always constant because the inputs are. */
6372 unsigned int lsb
6373 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
6374 /* Operate directly on the encoding rather than using
6375 wi::extract_uhwi, so that we preserve the sign or zero
6376 extension for modes that are not a whole number of bits in
6377 size. (Zero extension is only used for the combination of
6378 innermode == BImode && STORE_FLAG_VALUE == 1). */
6379 unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
6380 unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
6381 unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
6382 bytes.quick_push (uhwi >> shift);
6383 }
6384 return true;
6385 }
6386
6387 if (CONST_DOUBLE_P (x))
6388 {
6389 /* real_to_target produces an array of integers in target memory order.
6390 All integers before the last one have 32 bits; the last one may
6391 have 32 bits or fewer, depending on whether the mode bitsize
6392 is divisible by 32. Each of these integers is then laid out
6393 in target memory as any other integer would be. */
6394 long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
6395 real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
6396
6397 /* The (maximum) number of target bytes per element of el32. */
6398 unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
6399 gcc_assert (bytes_per_el32 != 0);
6400
6401 /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
6402 handling above. */
6403 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
6404 {
6405 unsigned int index = byte / bytes_per_el32;
6406 unsigned int subbyte = byte % bytes_per_el32;
6407 unsigned int int_bytes = MIN (bytes_per_el32,
6408 mode_bytes - index * bytes_per_el32);
6409 /* Always constant because the inputs are. */
6410 unsigned int lsb
6411 = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
6412 bytes.quick_push ((unsigned long) el32[index] >> lsb);
6413 }
6414 return true;
6415 }
6416
6417 if (GET_CODE (x) == CONST_FIXED)
6418 {
6419 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
6420 {
6421 /* Always constant because the inputs are. */
6422 unsigned int lsb
6423 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
6424 unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
6425 if (lsb >= HOST_BITS_PER_WIDE_INT)
6426 {
6427 lsb -= HOST_BITS_PER_WIDE_INT;
6428 piece = CONST_FIXED_VALUE_HIGH (x);
6429 }
6430 bytes.quick_push (piece >> lsb);
6431 }
6432 return true;
6433 }
6434
6435 return false;
6436 }
6437
6438 /* Read a vector of mode MODE from the target memory image given by BYTES,
6439 starting at byte FIRST_BYTE. The vector is known to be encodable using
6440 NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
6441 and BYTES is known to have enough bytes to supply NPATTERNS *
6442 NELTS_PER_PATTERN vector elements. Each element of BYTES contains
6443 BITS_PER_UNIT bits and the bytes are in target memory order.
6444
6445 Return the vector on success, otherwise return NULL_RTX. */
6446
6447 rtx
6448 native_decode_vector_rtx (machine_mode mode, vec<target_unit> bytes,
6449 unsigned int first_byte, unsigned int npatterns,
6450 unsigned int nelts_per_pattern)
6451 {
6452 rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
6453
6454 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
6455 GET_MODE_NUNITS (mode));
6456 if (elt_bits < BITS_PER_UNIT)
6457 {
6458 /* This is the only case in which elements can be smaller than a byte.
6459 Element 0 is always in the lsb of the containing byte. */
6460 gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
6461 for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
6462 {
6463 unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
6464 unsigned int byte_index = bit_index / BITS_PER_UNIT;
6465 unsigned int lsb = bit_index % BITS_PER_UNIT;
6466 builder.quick_push (bytes[byte_index] & (1 << lsb)
6467 ? CONST1_RTX (BImode)
6468 : CONST0_RTX (BImode));
6469 }
6470 }
6471 else
6472 {
6473 for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
6474 {
6475 rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
6476 if (!x)
6477 return NULL_RTX;
6478 builder.quick_push (x);
6479 first_byte += elt_bits / BITS_PER_UNIT;
6480 }
6481 }
6482 return builder.build ();
6483 }
6484
6485 /* Read an rtx of mode MODE from the target memory image given by BYTES,
6486 starting at byte FIRST_BYTE. Each element of BYTES contains BITS_PER_UNIT
6487 bits and the bytes are in target memory order. The image has enough
6488 values to specify all bytes of MODE.
6489
6490 Return the rtx on success, otherwise return NULL_RTX. */
6491
6492 rtx
6493 native_decode_rtx (machine_mode mode, vec<target_unit> bytes,
6494 unsigned int first_byte)
6495 {
6496 if (VECTOR_MODE_P (mode))
6497 {
6498 /* If we know at compile time how many elements there are,
6499 pull each element directly from BYTES. */
6500 unsigned int nelts;
6501 if (GET_MODE_NUNITS (mode).is_constant (&nelts))
6502 return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
6503 return NULL_RTX;
6504 }
6505
6506 scalar_int_mode imode;
6507 if (is_a <scalar_int_mode> (mode, &imode)
6508 && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
6509 {
6510 /* Pull the bytes msb first, so that we can use simple
6511 shift-and-insert wide_int operations. */
6512 unsigned int size = GET_MODE_SIZE (imode);
6513 wide_int result (wi::zero (GET_MODE_PRECISION (imode)));
6514 for (unsigned int i = 0; i < size; ++i)
6515 {
6516 unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
6517 /* Always constant because the inputs are. */
6518 unsigned int subbyte
6519 = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
6520 result <<= BITS_PER_UNIT;
6521 result |= bytes[first_byte + subbyte];
6522 }
6523 return immed_wide_int_const (result, imode);
6524 }
6525
6526 scalar_float_mode fmode;
6527 if (is_a <scalar_float_mode> (mode, &fmode))
6528 {
6529 /* We need to build an array of integers in target memory order.
6530 All integers before the last one have 32 bits; the last one may
6531 have 32 bits or fewer, depending on whether the mode bitsize
6532 is divisible by 32. */
6533 long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
6534 unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
6535 memset (el32, 0, num_el32 * sizeof (long));
6536
6537 /* The (maximum) number of target bytes per element of el32. */
6538 unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
6539 gcc_assert (bytes_per_el32 != 0);
6540
6541 unsigned int mode_bytes = GET_MODE_SIZE (fmode);
6542 for (unsigned int byte = 0; byte < mode_bytes; ++byte)
6543 {
6544 unsigned int index = byte / bytes_per_el32;
6545 unsigned int subbyte = byte % bytes_per_el32;
6546 unsigned int int_bytes = MIN (bytes_per_el32,
6547 mode_bytes - index * bytes_per_el32);
6548 /* Always constant because the inputs are. */
6549 unsigned int lsb
6550 = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
6551 el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
6552 }
6553 REAL_VALUE_TYPE r;
6554 real_from_target (&r, el32, fmode);
6555 return const_double_from_real_value (r, fmode);
6556 }
6557
6558 if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
6559 {
6560 scalar_mode smode = as_a <scalar_mode> (mode);
6561 FIXED_VALUE_TYPE f;
6562 f.data.low = 0;
6563 f.data.high = 0;
6564 f.mode = smode;
6565
6566 unsigned int mode_bytes = GET_MODE_SIZE (smode);
6567 for (unsigned int byte = 0; byte < mode_bytes; ++byte)
6568 {
6569 /* Always constant because the inputs are. */
6570 unsigned int lsb
6571 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
6572 unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
6573 if (lsb >= HOST_BITS_PER_WIDE_INT)
6574 f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
6575 else
6576 f.data.low |= unit << lsb;
6577 }
6578 return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
6579 }
6580
6581 return NULL_RTX;
6582 }
6583
6584 /* Simplify a byte offset BYTE into CONST_VECTOR X. The main purpose
6585 is to convert a runtime BYTE value into a constant one. */
6586
6587 static poly_uint64
6588 simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
6589 {
6590 /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
6591 machine_mode mode = GET_MODE (x);
6592 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
6593 GET_MODE_NUNITS (mode));
6594 /* The number of bits needed to encode one element from each pattern. */
6595 unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
6596
6597 /* Identify the start point in terms of a sequence number and a byte offset
6598 within that sequence. */
6599 poly_uint64 first_sequence;
6600 unsigned HOST_WIDE_INT subbit;
6601 if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
6602 &first_sequence, &subbit))
6603 {
6604 unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
6605 if (nelts_per_pattern == 1)
6606 /* This is a duplicated vector, so the value of FIRST_SEQUENCE
6607 doesn't matter. */
6608 byte = subbit / BITS_PER_UNIT;
6609 else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
6610 {
6611 /* The subreg drops the first element from each pattern and
6612 only uses the second element. Find the first sequence
6613 that starts on a byte boundary. */
6614 subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
6615 byte = subbit / BITS_PER_UNIT;
6616 }
6617 }
6618 return byte;
6619 }
6620
6621 /* Subroutine of simplify_subreg in which:
6622
6623 - X is known to be a CONST_VECTOR
6624 - OUTERMODE is known to be a vector mode
6625
6626 Try to handle the subreg by operating on the CONST_VECTOR encoding
6627 rather than on each individual element of the CONST_VECTOR.
6628
6629 Return the simplified subreg on success, otherwise return NULL_RTX. */
6060 6630
6061 static rtx 6631 static rtx
6062 simplify_immed_subreg (fixed_size_mode outermode, rtx op, 6632 simplify_const_vector_subreg (machine_mode outermode, rtx x,
6063 machine_mode innermode, unsigned int byte, 6633 machine_mode innermode, unsigned int first_byte)
6064 unsigned int first_elem, unsigned int inner_bytes)
6065 { 6634 {
6066 enum { 6635 /* Paradoxical subregs of vectors have dubious semantics. */
6067 value_bit = 8, 6636 if (paradoxical_subreg_p (outermode, innermode))
6068 value_mask = (1 << value_bit) - 1 6637 return NULL_RTX;
6069 }; 6638
6070 unsigned char value[MAX_BITSIZE_MODE_ANY_MODE / value_bit]; 6639 /* We can only preserve the semantics of a stepped pattern if the new
6071 int value_start; 6640 vector element is the same as the original one. */
6072 int i; 6641 if (CONST_VECTOR_STEPPED_P (x)
6073 int elem; 6642 && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
6074 6643 return NULL_RTX;
6075 int num_elem; 6644
6076 rtx * elems; 6645 /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
6077 int elem_bitsize; 6646 unsigned int x_elt_bits
6078 rtx result_s = NULL; 6647 = vector_element_size (GET_MODE_BITSIZE (innermode),
6079 rtvec result_v = NULL; 6648 GET_MODE_NUNITS (innermode));
6080 enum mode_class outer_class; 6649 unsigned int out_elt_bits
6081 scalar_mode outer_submode; 6650 = vector_element_size (GET_MODE_BITSIZE (outermode),
6082 int max_bitsize; 6651 GET_MODE_NUNITS (outermode));
6652
6653 /* The number of bits needed to encode one element from every pattern
6654 of the original vector. */
6655 unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
6656
6657 /* The number of bits needed to encode one element from every pattern
6658 of the result. */
6659 unsigned int out_sequence_bits
6660 = least_common_multiple (x_sequence_bits, out_elt_bits);
6661
6662 /* Work out the number of interleaved patterns in the output vector
6663 and the number of encoded elements per pattern. */
6664 unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
6665 unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
6666
6667 /* The encoding scheme requires the number of elements to be a multiple
6668 of the number of patterns, so that each pattern appears at least once
6669 and so that the same number of elements appear from each pattern. */
6670 bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
6671 unsigned int const_nunits;
6672 if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
6673 && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
6674 {
6675 /* Either the encoding is invalid, or applying it would give us
6676 more elements than we need. Just encode each element directly. */
6677 out_npatterns = const_nunits;
6678 nelts_per_pattern = 1;
6679 }
6680 else if (!ok_p)
6681 return NULL_RTX;
6682
6683 /* Get enough bytes of X to form the new encoding. */
6684 unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
6685 unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
6686 auto_vec<target_unit, 128> buffer (buffer_bytes);
6687 if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
6688 return NULL_RTX;
6689
6690 /* Reencode the bytes as OUTERMODE. */
6691 return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
6692 nelts_per_pattern);
6693 }
6694
6695 /* Try to simplify a subreg of a constant by encoding the subreg region
6696 as a sequence of target bytes and reading them back in the new mode.
6697 Return the new value on success, otherwise return null.
6698
6699 The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
6700 and byte offset FIRST_BYTE. */
6701
6702 static rtx
6703 simplify_immed_subreg (fixed_size_mode outermode, rtx x,
6704 machine_mode innermode, unsigned int first_byte)
6705 {
6706 unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
6707 auto_vec<target_unit, 128> buffer (buffer_bytes);
6083 6708
6084 /* Some ports misuse CCmode. */ 6709 /* Some ports misuse CCmode. */
6085 if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (op)) 6710 if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
6086 return op; 6711 return x;
6087 6712
6088 /* We have no way to represent a complex constant at the rtl level. */ 6713 /* Paradoxical subregs read undefined values for bytes outside of the
6089 if (COMPLEX_MODE_P (outermode)) 6714 inner value. However, we have traditionally always sign-extended
6090 return NULL_RTX; 6715 integer constants and zero-extended others. */
6091 6716 unsigned int inner_bytes = buffer_bytes;
6092 /* We support any size mode. */ 6717 if (paradoxical_subreg_p (outermode, innermode))
6093 max_bitsize = MAX (GET_MODE_BITSIZE (outermode), 6718 {
6094 inner_bytes * BITS_PER_UNIT); 6719 if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
6095 6720 return NULL_RTX;
6096 /* Unpack the value. */ 6721
6097 6722 target_unit filler = 0;
6098 if (GET_CODE (op) == CONST_VECTOR) 6723 if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
6099 { 6724 filler = -1;
6100 num_elem = CEIL (inner_bytes, GET_MODE_UNIT_SIZE (innermode)); 6725
6101 elem_bitsize = GET_MODE_UNIT_BITSIZE (innermode); 6726 /* Add any leading bytes due to big-endian layout. The number of
6727 bytes must be constant because both modes have constant size. */
6728 unsigned int leading_bytes
6729 = -byte_lowpart_offset (outermode, innermode).to_constant ();
6730 for (unsigned int i = 0; i < leading_bytes; ++i)
6731 buffer.quick_push (filler);
6732
6733 if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
6734 return NULL_RTX;
6735
6736 /* Add any trailing bytes due to little-endian layout. */
6737 while (buffer.length () < buffer_bytes)
6738 buffer.quick_push (filler);
6102 } 6739 }
6103 else 6740 else
6104 { 6741 {
6105 num_elem = 1; 6742 if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
6106 elem_bitsize = max_bitsize; 6743 return NULL_RTX;
6107 }
6108 /* If this asserts, it is too complicated; reducing value_bit may help. */
6109 gcc_assert (BITS_PER_UNIT % value_bit == 0);
6110 /* I don't know how to handle endianness of sub-units. */
6111 gcc_assert (elem_bitsize % BITS_PER_UNIT == 0);
6112
6113 for (elem = 0; elem < num_elem; elem++)
6114 {
6115 unsigned char * vp;
6116 rtx el = (GET_CODE (op) == CONST_VECTOR
6117 ? CONST_VECTOR_ELT (op, first_elem + elem)
6118 : op);
6119
6120 /* Vectors are kept in target memory order. (This is probably
6121 a mistake.) */
6122 {
6123 unsigned byte = (elem * elem_bitsize) / BITS_PER_UNIT;
6124 unsigned ibyte = (((num_elem - 1 - elem) * elem_bitsize)
6125 / BITS_PER_UNIT);
6126 unsigned word_byte = WORDS_BIG_ENDIAN ? ibyte : byte;
6127 unsigned subword_byte = BYTES_BIG_ENDIAN ? ibyte : byte;
6128 unsigned bytele = (subword_byte % UNITS_PER_WORD
6129 + (word_byte / UNITS_PER_WORD) * UNITS_PER_WORD);
6130 vp = value + (bytele * BITS_PER_UNIT) / value_bit;
6131 } 6744 }
6132 6745 return native_decode_rtx (outermode, buffer, 0);
6133 switch (GET_CODE (el))
6134 {
6135 case CONST_INT:
6136 for (i = 0;
6137 i < HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
6138 i += value_bit)
6139 *vp++ = INTVAL (el) >> i;
6140 /* CONST_INTs are always logically sign-extended. */
6141 for (; i < elem_bitsize; i += value_bit)
6142 *vp++ = INTVAL (el) < 0 ? -1 : 0;
6143 break;
6144
6145 case CONST_WIDE_INT:
6146 {
6147 rtx_mode_t val = rtx_mode_t (el, GET_MODE_INNER (innermode));
6148 unsigned char extend = wi::sign_mask (val);
6149 int prec = wi::get_precision (val);
6150
6151 for (i = 0; i < prec && i < elem_bitsize; i += value_bit)
6152 *vp++ = wi::extract_uhwi (val, i, value_bit);
6153 for (; i < elem_bitsize; i += value_bit)
6154 *vp++ = extend;
6155 }
6156 break;
6157
6158 case CONST_DOUBLE:
6159 if (TARGET_SUPPORTS_WIDE_INT == 0 && GET_MODE (el) == VOIDmode)
6160 {
6161 unsigned char extend = 0;
6162 /* If this triggers, someone should have generated a
6163 CONST_INT instead. */
6164 gcc_assert (elem_bitsize > HOST_BITS_PER_WIDE_INT);
6165
6166 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i += value_bit)
6167 *vp++ = CONST_DOUBLE_LOW (el) >> i;
6168 while (i < HOST_BITS_PER_DOUBLE_INT && i < elem_bitsize)
6169 {
6170 *vp++
6171 = CONST_DOUBLE_HIGH (el) >> (i - HOST_BITS_PER_WIDE_INT);
6172 i += value_bit;
6173 }
6174
6175 if (CONST_DOUBLE_HIGH (el) >> (HOST_BITS_PER_WIDE_INT - 1))
6176 extend = -1;
6177 for (; i < elem_bitsize; i += value_bit)
6178 *vp++ = extend;
6179 }
6180 else
6181 {
6182 /* This is big enough for anything on the platform. */
6183 long tmp[MAX_BITSIZE_MODE_ANY_MODE / 32];
6184 scalar_float_mode el_mode;
6185
6186 el_mode = as_a <scalar_float_mode> (GET_MODE (el));
6187 int bitsize = GET_MODE_BITSIZE (el_mode);
6188
6189 gcc_assert (bitsize <= elem_bitsize);
6190 gcc_assert (bitsize % value_bit == 0);
6191
6192 real_to_target (tmp, CONST_DOUBLE_REAL_VALUE (el),
6193 GET_MODE (el));
6194
6195 /* real_to_target produces its result in words affected by
6196 FLOAT_WORDS_BIG_ENDIAN. However, we ignore this,
6197 and use WORDS_BIG_ENDIAN instead; see the documentation
6198 of SUBREG in rtl.texi. */
6199 for (i = 0; i < bitsize; i += value_bit)
6200 {
6201 int ibase;
6202 if (WORDS_BIG_ENDIAN)
6203 ibase = bitsize - 1 - i;
6204 else
6205 ibase = i;
6206 *vp++ = tmp[ibase / 32] >> i % 32;
6207 }
6208
6209 /* It shouldn't matter what's done here, so fill it with
6210 zero. */
6211 for (; i < elem_bitsize; i += value_bit)
6212 *vp++ = 0;
6213 }
6214 break;
6215
6216 case CONST_FIXED:
6217 if (elem_bitsize <= HOST_BITS_PER_WIDE_INT)
6218 {
6219 for (i = 0; i < elem_bitsize; i += value_bit)
6220 *vp++ = CONST_FIXED_VALUE_LOW (el) >> i;
6221 }
6222 else
6223 {
6224 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i += value_bit)
6225 *vp++ = CONST_FIXED_VALUE_LOW (el) >> i;
6226 for (; i < HOST_BITS_PER_DOUBLE_INT && i < elem_bitsize;
6227 i += value_bit)
6228 *vp++ = CONST_FIXED_VALUE_HIGH (el)
6229 >> (i - HOST_BITS_PER_WIDE_INT);
6230 for (; i < elem_bitsize; i += value_bit)
6231 *vp++ = 0;
6232 }
6233 break;
6234
6235 default:
6236 gcc_unreachable ();
6237 }
6238 }
6239
6240 /* Now, pick the right byte to start with. */
6241 /* Renumber BYTE so that the least-significant byte is byte 0. A special
6242 case is paradoxical SUBREGs, which shouldn't be adjusted since they
6243 will already have offset 0. */
6244 if (inner_bytes >= GET_MODE_SIZE (outermode))
6245 {
6246 unsigned ibyte = inner_bytes - GET_MODE_SIZE (outermode) - byte;
6247 unsigned word_byte = WORDS_BIG_ENDIAN ? ibyte : byte;
6248 unsigned subword_byte = BYTES_BIG_ENDIAN ? ibyte : byte;
6249 byte = (subword_byte % UNITS_PER_WORD
6250 + (word_byte / UNITS_PER_WORD) * UNITS_PER_WORD);
6251 }
6252
6253 /* BYTE should still be inside OP. (Note that BYTE is unsigned,
6254 so if it's become negative it will instead be very large.) */
6255 gcc_assert (byte < inner_bytes);
6256
6257 /* Convert from bytes to chunks of size value_bit. */
6258 value_start = byte * (BITS_PER_UNIT / value_bit);
6259
6260 /* Re-pack the value. */
6261 num_elem = GET_MODE_NUNITS (outermode);
6262
6263 if (VECTOR_MODE_P (outermode))
6264 {
6265 result_v = rtvec_alloc (num_elem);
6266 elems = &RTVEC_ELT (result_v, 0);
6267 }
6268 else
6269 elems = &result_s;
6270
6271 outer_submode = GET_MODE_INNER (outermode);
6272 outer_class = GET_MODE_CLASS (outer_submode);
6273 elem_bitsize = GET_MODE_BITSIZE (outer_submode);
6274
6275 gcc_assert (elem_bitsize % value_bit == 0);
6276 gcc_assert (elem_bitsize + value_start * value_bit <= max_bitsize);
6277
6278 for (elem = 0; elem < num_elem; elem++)
6279 {
6280 unsigned char *vp;
6281
6282 /* Vectors are stored in target memory order. (This is probably
6283 a mistake.) */
6284 {
6285 unsigned byte = (elem * elem_bitsize) / BITS_PER_UNIT;
6286 unsigned ibyte = (((num_elem - 1 - elem) * elem_bitsize)
6287 / BITS_PER_UNIT);
6288 unsigned word_byte = WORDS_BIG_ENDIAN ? ibyte : byte;
6289 unsigned subword_byte = BYTES_BIG_ENDIAN ? ibyte : byte;
6290 unsigned bytele = (subword_byte % UNITS_PER_WORD
6291 + (word_byte / UNITS_PER_WORD) * UNITS_PER_WORD);
6292 vp = value + value_start + (bytele * BITS_PER_UNIT) / value_bit;
6293 }
6294
6295 switch (outer_class)
6296 {
6297 case MODE_INT:
6298 case MODE_PARTIAL_INT:
6299 {
6300 int u;
6301 int base = 0;
6302 int units
6303 = (GET_MODE_BITSIZE (outer_submode) + HOST_BITS_PER_WIDE_INT - 1)
6304 / HOST_BITS_PER_WIDE_INT;
6305 HOST_WIDE_INT tmp[MAX_BITSIZE_MODE_ANY_INT / HOST_BITS_PER_WIDE_INT];
6306 wide_int r;
6307
6308 if (GET_MODE_PRECISION (outer_submode) > MAX_BITSIZE_MODE_ANY_INT)
6309 return NULL_RTX;
6310 for (u = 0; u < units; u++)
6311 {
6312 unsigned HOST_WIDE_INT buf = 0;
6313 for (i = 0;
6314 i < HOST_BITS_PER_WIDE_INT && base + i < elem_bitsize;
6315 i += value_bit)
6316 buf |= (unsigned HOST_WIDE_INT)(*vp++ & value_mask) << i;
6317
6318 tmp[u] = buf;
6319 base += HOST_BITS_PER_WIDE_INT;
6320 }
6321 r = wide_int::from_array (tmp, units,
6322 GET_MODE_PRECISION (outer_submode));
6323 #if TARGET_SUPPORTS_WIDE_INT == 0
6324 /* Make sure r will fit into CONST_INT or CONST_DOUBLE. */
6325 if (wi::min_precision (r, SIGNED) > HOST_BITS_PER_DOUBLE_INT)
6326 return NULL_RTX;
6327 #endif
6328 elems[elem] = immed_wide_int_const (r, outer_submode);
6329 }
6330 break;
6331
6332 case MODE_FLOAT:
6333 case MODE_DECIMAL_FLOAT:
6334 {
6335 REAL_VALUE_TYPE r;
6336 long tmp[MAX_BITSIZE_MODE_ANY_MODE / 32] = { 0 };
6337
6338 /* real_from_target wants its input in words affected by
6339 FLOAT_WORDS_BIG_ENDIAN. However, we ignore this,
6340 and use WORDS_BIG_ENDIAN instead; see the documentation
6341 of SUBREG in rtl.texi. */
6342 for (i = 0; i < elem_bitsize; i += value_bit)
6343 {
6344 int ibase;
6345 if (WORDS_BIG_ENDIAN)
6346 ibase = elem_bitsize - 1 - i;
6347 else
6348 ibase = i;
6349 tmp[ibase / 32] |= (*vp++ & value_mask) << i % 32;
6350 }
6351
6352 real_from_target (&r, tmp, outer_submode);
6353 elems[elem] = const_double_from_real_value (r, outer_submode);
6354 }
6355 break;
6356
6357 case MODE_FRACT:
6358 case MODE_UFRACT:
6359 case MODE_ACCUM:
6360 case MODE_UACCUM:
6361 {
6362 FIXED_VALUE_TYPE f;
6363 f.data.low = 0;
6364 f.data.high = 0;
6365 f.mode = outer_submode;
6366
6367 for (i = 0;
6368 i < HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
6369 i += value_bit)
6370 f.data.low |= (unsigned HOST_WIDE_INT)(*vp++ & value_mask) << i;
6371 for (; i < elem_bitsize; i += value_bit)
6372 f.data.high |= ((unsigned HOST_WIDE_INT)(*vp++ & value_mask)
6373 << (i - HOST_BITS_PER_WIDE_INT));
6374
6375 elems[elem] = CONST_FIXED_FROM_FIXED_VALUE (f, outer_submode);
6376 }
6377 break;
6378
6379 default:
6380 gcc_unreachable ();
6381 }
6382 }
6383 if (VECTOR_MODE_P (outermode))
6384 return gen_rtx_CONST_VECTOR (outermode, result_v);
6385 else
6386 return result_s;
6387 } 6746 }
6388 6747
6389 /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE) 6748 /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
6390 Return 0 if no simplifications are possible. */ 6749 Return 0 if no simplifications are possible. */
6391 rtx 6750 rtx
6410 return NULL_RTX; 6769 return NULL_RTX;
6411 6770
6412 if (outermode == innermode && known_eq (byte, 0U)) 6771 if (outermode == innermode && known_eq (byte, 0U))
6413 return op; 6772 return op;
6414 6773
6774 if (GET_CODE (op) == CONST_VECTOR)
6775 byte = simplify_const_vector_byte_offset (op, byte);
6776
6415 if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode))) 6777 if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
6416 { 6778 {
6417 rtx elt; 6779 rtx elt;
6418 6780
6419 if (VECTOR_MODE_P (outermode) 6781 if (VECTOR_MODE_P (outermode)
6429 if (CONST_SCALAR_INT_P (op) 6791 if (CONST_SCALAR_INT_P (op)
6430 || CONST_DOUBLE_AS_FLOAT_P (op) 6792 || CONST_DOUBLE_AS_FLOAT_P (op)
6431 || CONST_FIXED_P (op) 6793 || CONST_FIXED_P (op)
6432 || GET_CODE (op) == CONST_VECTOR) 6794 || GET_CODE (op) == CONST_VECTOR)
6433 { 6795 {
6434 /* simplify_immed_subreg deconstructs OP into bytes and constructs
6435 the result from bytes, so it only works if the sizes of the modes
6436 and the value of the offset are known at compile time. Cases that
6437 that apply to general modes and offsets should be handled here
6438 before calling simplify_immed_subreg. */
6439 fixed_size_mode fs_outermode, fs_innermode;
6440 unsigned HOST_WIDE_INT cbyte; 6796 unsigned HOST_WIDE_INT cbyte;
6441 if (is_a <fixed_size_mode> (outermode, &fs_outermode) 6797 if (byte.is_constant (&cbyte))
6442 && is_a <fixed_size_mode> (innermode, &fs_innermode) 6798 {
6443 && byte.is_constant (&cbyte)) 6799 if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
6444 return simplify_immed_subreg (fs_outermode, op, fs_innermode, cbyte, 6800 {
6445 0, GET_MODE_SIZE (fs_innermode)); 6801 rtx tmp = simplify_const_vector_subreg (outermode, op,
6446 6802 innermode, cbyte);
6447 /* Handle constant-sized outer modes and variable-sized inner modes. */ 6803 if (tmp)
6448 unsigned HOST_WIDE_INT first_elem; 6804 return tmp;
6449 if (GET_CODE (op) == CONST_VECTOR 6805 }
6450 && is_a <fixed_size_mode> (outermode, &fs_outermode) 6806
6451 && constant_multiple_p (byte, GET_MODE_UNIT_SIZE (innermode), 6807 fixed_size_mode fs_outermode;
6452 &first_elem)) 6808 if (is_a <fixed_size_mode> (outermode, &fs_outermode))
6453 return simplify_immed_subreg (fs_outermode, op, innermode, 0, 6809 return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
6454 first_elem, 6810 }
6455 GET_MODE_SIZE (fs_outermode));
6456
6457 return NULL_RTX;
6458 } 6811 }
6459 6812
6460 /* Changing mode twice with SUBREG => just change it once, 6813 /* Changing mode twice with SUBREG => just change it once,
6461 or not at all if changing back op starting mode. */ 6814 or not at all if changing back op starting mode. */
6462 if (GET_CODE (op) == SUBREG) 6815 if (GET_CODE (op) == SUBREG)
6537 subreg_memory_offset (outermode, 6890 subreg_memory_offset (outermode,
6538 innermode, byte)); 6891 innermode, byte));
6539 6892
6540 /* Propagate original regno. We don't have any way to specify 6893 /* Propagate original regno. We don't have any way to specify
6541 the offset inside original regno, so do so only for lowpart. 6894 the offset inside original regno, so do so only for lowpart.
6542 The information is used only by alias analysis that can not 6895 The information is used only by alias analysis that cannot
6543 grog partial register anyway. */ 6896 grog partial register anyway. */
6544 6897
6545 if (known_eq (subreg_lowpart_offset (outermode, innermode), byte)) 6898 if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
6546 ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op); 6899 ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
6547 return x; 6900 return x;
6651 if (tem) 7004 if (tem)
6652 return tem; 7005 return tem;
6653 } 7006 }
6654 } 7007 }
6655 7008
7009 /* If OP is a vector comparison and the subreg is not changing the
7010 number of elements or the size of the elements, change the result
7011 of the comparison to the new mode. */
7012 if (COMPARISON_P (op)
7013 && VECTOR_MODE_P (outermode)
7014 && VECTOR_MODE_P (innermode)
7015 && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
7016 && known_eq (GET_MODE_UNIT_SIZE (outermode),
7017 GET_MODE_UNIT_SIZE (innermode)))
7018 return simplify_gen_relational (GET_CODE (op), outermode, innermode,
7019 XEXP (op, 0), XEXP (op, 1));
6656 return NULL_RTX; 7020 return NULL_RTX;
6657 } 7021 }
6658 7022
6659 /* Make a SUBREG operation or equivalent if it folds. */ 7023 /* Make a SUBREG operation or equivalent if it folds. */
6660 7024
6883 if (maybe_ne (nunits, 2U) 7247 if (maybe_ne (nunits, 2U)
6884 && multiple_p (nunits, 2) 7248 && multiple_p (nunits, 2)
6885 && mode_for_vector (inner_mode, 2).exists (&narrower_mode) 7249 && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
6886 && VECTOR_MODE_P (narrower_mode)) 7250 && VECTOR_MODE_P (narrower_mode))
6887 { 7251 {
7252 /* Test VEC_DUPLICATE of a vector. */
7253 rtx_vector_builder nbuilder (narrower_mode, 2, 1);
7254 nbuilder.quick_push (const0_rtx);
7255 nbuilder.quick_push (const1_rtx);
7256 rtx_vector_builder builder (mode, 2, 1);
7257 builder.quick_push (const0_rtx);
7258 builder.quick_push (const1_rtx);
7259 ASSERT_RTX_EQ (builder.build (),
7260 simplify_unary_operation (VEC_DUPLICATE, mode,
7261 nbuilder.build (),
7262 narrower_mode));
7263
6888 /* Test VEC_SELECT of a vector. */ 7264 /* Test VEC_SELECT of a vector. */
6889 rtx vec_par 7265 rtx vec_par
6890 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx)); 7266 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
6891 rtx narrower_duplicate 7267 rtx narrower_duplicate
6892 = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg); 7268 = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
6955 simplify_binary_operation (MINUS, mode, duplicate, 7331 simplify_binary_operation (MINUS, mode, duplicate,
6956 series_0_m1)); 7332 series_0_m1));
6957 ASSERT_RTX_EQ (series_0_m1, 7333 ASSERT_RTX_EQ (series_0_m1,
6958 simplify_binary_operation (VEC_SERIES, mode, const0_rtx, 7334 simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
6959 constm1_rtx)); 7335 constm1_rtx));
7336
7337 /* Test NEG on constant vector series. */
7338 ASSERT_RTX_EQ (series_0_m1,
7339 simplify_unary_operation (NEG, mode, series_0_1, mode));
7340 ASSERT_RTX_EQ (series_0_1,
7341 simplify_unary_operation (NEG, mode, series_0_m1, mode));
7342
7343 /* Test PLUS and MINUS on constant vector series. */
7344 rtx scalar2 = gen_int_mode (2, inner_mode);
7345 rtx scalar3 = gen_int_mode (3, inner_mode);
7346 rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
7347 rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
7348 rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
7349 ASSERT_RTX_EQ (series_1_1,
7350 simplify_binary_operation (PLUS, mode, series_0_1,
7351 CONST1_RTX (mode)));
7352 ASSERT_RTX_EQ (series_0_m1,
7353 simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
7354 series_0_m1));
7355 ASSERT_RTX_EQ (series_1_3,
7356 simplify_binary_operation (PLUS, mode, series_1_1,
7357 series_0_2));
7358 ASSERT_RTX_EQ (series_0_1,
7359 simplify_binary_operation (MINUS, mode, series_1_1,
7360 CONST1_RTX (mode)));
7361 ASSERT_RTX_EQ (series_1_1,
7362 simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
7363 series_0_m1));
7364 ASSERT_RTX_EQ (series_1_1,
7365 simplify_binary_operation (MINUS, mode, series_1_3,
7366 series_0_2));
7367
7368 /* Test MULT between constant vectors. */
7369 rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
7370 rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
7371 rtx scalar9 = gen_int_mode (9, inner_mode);
7372 rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
7373 ASSERT_RTX_EQ (series_0_2,
7374 simplify_binary_operation (MULT, mode, series_0_1, vec2));
7375 ASSERT_RTX_EQ (series_3_9,
7376 simplify_binary_operation (MULT, mode, vec3, series_1_3));
7377 if (!GET_MODE_NUNITS (mode).is_constant ())
7378 ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
7379 series_0_1));
7380
7381 /* Test ASHIFT between constant vectors. */
7382 ASSERT_RTX_EQ (series_0_2,
7383 simplify_binary_operation (ASHIFT, mode, series_0_1,
7384 CONST1_RTX (mode)));
7385 if (!GET_MODE_NUNITS (mode).is_constant ())
7386 ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
7387 series_0_1));
6960 } 7388 }
6961 7389
6962 /* Verify simplify_merge_mask works correctly. */ 7390 /* Verify simplify_merge_mask works correctly. */
6963 7391
6964 static void 7392 static void
7020 /* Called indirectly. */ 7448 /* Called indirectly. */
7021 ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1), 7449 ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
7022 simplify_rtx (nvm)); 7450 simplify_rtx (nvm));
7023 } 7451 }
7024 7452
7453 /* Test subregs of integer vector constant X, trying elements in
7454 the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
7455 where NELTS is the number of elements in X. Subregs involving
7456 elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail. */
7457
7458 static void
7459 test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
7460 unsigned int first_valid = 0)
7461 {
7462 machine_mode inner_mode = GET_MODE (x);
7463 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
7464
7465 for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
7466 {
7467 machine_mode outer_mode = (machine_mode) modei;
7468 if (!VECTOR_MODE_P (outer_mode))
7469 continue;
7470
7471 unsigned int outer_nunits;
7472 if (GET_MODE_INNER (outer_mode) == int_mode
7473 && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
7474 && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
7475 {
7476 /* Test subregs in which the outer mode is a smaller,
7477 constant-sized vector of the same element type. */
7478 unsigned int limit
7479 = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
7480 for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
7481 {
7482 rtx expected = NULL_RTX;
7483 if (elt >= first_valid)
7484 {
7485 rtx_vector_builder builder (outer_mode, outer_nunits, 1);
7486 for (unsigned int i = 0; i < outer_nunits; ++i)
7487 builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
7488 expected = builder.build ();
7489 }
7490 poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
7491 ASSERT_RTX_EQ (expected,
7492 simplify_subreg (outer_mode, x,
7493 inner_mode, byte));
7494 }
7495 }
7496 else if (known_eq (GET_MODE_SIZE (outer_mode),
7497 GET_MODE_SIZE (inner_mode))
7498 && known_eq (elt_bias, 0U)
7499 && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
7500 || known_eq (GET_MODE_BITSIZE (outer_mode),
7501 GET_MODE_NUNITS (outer_mode)))
7502 && (!FLOAT_MODE_P (outer_mode)
7503 || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
7504 == GET_MODE_UNIT_PRECISION (outer_mode)))
7505 && (GET_MODE_SIZE (inner_mode).is_constant ()
7506 || !CONST_VECTOR_STEPPED_P (x)))
7507 {
7508 /* Try converting to OUTER_MODE and back. */
7509 rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
7510 ASSERT_TRUE (outer_x != NULL_RTX);
7511 ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
7512 outer_mode, 0));
7513 }
7514 }
7515
7516 if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
7517 {
7518 /* Test each byte in the element range. */
7519 unsigned int limit
7520 = constant_lower_bound (GET_MODE_SIZE (inner_mode));
7521 for (unsigned int i = 0; i < limit; ++i)
7522 {
7523 unsigned int elt = i / GET_MODE_SIZE (int_mode);
7524 rtx expected = NULL_RTX;
7525 if (elt >= first_valid)
7526 {
7527 unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
7528 if (BYTES_BIG_ENDIAN)
7529 byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
7530 rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
7531 wide_int shifted_elt
7532 = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
7533 expected = immed_wide_int_const (shifted_elt, QImode);
7534 }
7535 poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
7536 ASSERT_RTX_EQ (expected,
7537 simplify_subreg (QImode, x, inner_mode, byte));
7538 }
7539 }
7540 }
7541
7542 /* Test constant subregs of integer vector mode INNER_MODE, using 1
7543 element per pattern. */
7544
7545 static void
7546 test_vector_subregs_repeating (machine_mode inner_mode)
7547 {
7548 poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
7549 unsigned int min_nunits = constant_lower_bound (nunits);
7550 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
7551 unsigned int count = gcd (min_nunits, 8);
7552
7553 rtx_vector_builder builder (inner_mode, count, 1);
7554 for (unsigned int i = 0; i < count; ++i)
7555 builder.quick_push (gen_int_mode (8 - i, int_mode));
7556 rtx x = builder.build ();
7557
7558 test_vector_subregs_modes (x);
7559 if (!nunits.is_constant ())
7560 test_vector_subregs_modes (x, nunits - min_nunits);
7561 }
7562
7563 /* Test constant subregs of integer vector mode INNER_MODE, using 2
7564 elements per pattern. */
7565
7566 static void
7567 test_vector_subregs_fore_back (machine_mode inner_mode)
7568 {
7569 poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
7570 unsigned int min_nunits = constant_lower_bound (nunits);
7571 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
7572 unsigned int count = gcd (min_nunits, 4);
7573
7574 rtx_vector_builder builder (inner_mode, count, 2);
7575 for (unsigned int i = 0; i < count; ++i)
7576 builder.quick_push (gen_int_mode (i, int_mode));
7577 for (unsigned int i = 0; i < count; ++i)
7578 builder.quick_push (gen_int_mode (-(int) i, int_mode));
7579 rtx x = builder.build ();
7580
7581 test_vector_subregs_modes (x);
7582 if (!nunits.is_constant ())
7583 test_vector_subregs_modes (x, nunits - min_nunits, count);
7584 }
7585
7586 /* Test constant subregs of integer vector mode INNER_MODE, using 3
7587 elements per pattern. */
7588
7589 static void
7590 test_vector_subregs_stepped (machine_mode inner_mode)
7591 {
7592 /* Build { 0, 1, 2, 3, ... }. */
7593 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
7594 rtx_vector_builder builder (inner_mode, 1, 3);
7595 for (unsigned int i = 0; i < 3; ++i)
7596 builder.quick_push (gen_int_mode (i, int_mode));
7597 rtx x = builder.build ();
7598
7599 test_vector_subregs_modes (x);
7600 }
7601
7602 /* Test constant subregs of integer vector mode INNER_MODE. */
7603
7604 static void
7605 test_vector_subregs (machine_mode inner_mode)
7606 {
7607 test_vector_subregs_repeating (inner_mode);
7608 test_vector_subregs_fore_back (inner_mode);
7609 test_vector_subregs_stepped (inner_mode);
7610 }
7611
7025 /* Verify some simplifications involving vectors. */ 7612 /* Verify some simplifications involving vectors. */
7026 7613
7027 static void 7614 static void
7028 test_vector_ops () 7615 test_vector_ops ()
7029 { 7616 {
7034 { 7621 {
7035 rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode)); 7622 rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
7036 test_vector_ops_duplicate (mode, scalar_reg); 7623 test_vector_ops_duplicate (mode, scalar_reg);
7037 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT 7624 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
7038 && maybe_gt (GET_MODE_NUNITS (mode), 2)) 7625 && maybe_gt (GET_MODE_NUNITS (mode), 2))
7039 test_vector_ops_series (mode, scalar_reg); 7626 {
7627 test_vector_ops_series (mode, scalar_reg);
7628 test_vector_subregs (mode);
7629 }
7040 test_vec_merge (mode); 7630 test_vec_merge (mode);
7041 } 7631 }
7042 } 7632 }
7043 } 7633 }
7044 7634