From: Richard Biener <richard.guenther@gmail.com>
To: GCC Patches <gcc-patches@gcc.gnu.org>,
Richard Sandiford <richard.sandiford@linaro.org>
Subject: Re: Implement SLP of internal functions
Date: Thu, 17 May 2018 11:42:00 -0000 [thread overview]
Message-ID: <CAFiYyc0F27eqfNjtukMJRJudMxBOKG0r0dwCJmQG5YcZ5Homhw@mail.gmail.com> (raw)
In-Reply-To: <87muwzoqd3.fsf@linaro.org>
On Wed, May 16, 2018 at 12:18 PM Richard Sandiford <
richard.sandiford@linaro.org> wrote:
> SLP of calls was previously restricted to built-in functions.
> This patch extends it to internal functions.
> Tested on aarch64-linux-gnu (with and without SVE), aarch64_be-elf
> and x86_64-linux-gnu. OK to install?
> Richard
> 2018-05-16 Richard Sandiford <richard.sandiford@linaro.org>
> gcc/
> * internal-fn.h (vectorizable_internal_fn_p): New function.
> * tree-vect-slp.c (compatible_calls_p): Likewise.
> (vect_build_slp_tree_1): Remove nops argument. Handle calls
> to internal functions.
> (vect_build_slp_tree_2): Update call to vect_build_slp_tree_1.
> gcc/testsuite/
> * gcc.target/aarch64/sve/cond_arith_4.c: New test.
> * gcc.target/aarch64/sve/cond_arith_4_run.c: Likewise.
> * gcc.target/aarch64/sve/cond_arith_5.c: Likewise.
> * gcc.target/aarch64/sve/cond_arith_5_run.c: Likewise.
> * gcc.target/aarch64/sve/slp_14.c: Likewise.
> * gcc.target/aarch64/sve/slp_14_run.c: Likewise.
> Index: gcc/internal-fn.h
> ===================================================================
> --- gcc/internal-fn.h 2018-05-16 11:06:14.513574219 +0100
> +++ gcc/internal-fn.h 2018-05-16 11:12:11.872116220 +0100
> @@ -158,6 +158,17 @@ direct_internal_fn_p (internal_fn fn)
> return direct_internal_fn_array[fn].type0 >= -1;
> }
> +/* Return true if FN is a direct internal function that can be
vectorized by
> + converting the return type and all argument types to vectors of the
same
> + number of elements. E.g. we can vectorize an IFN_SQRT on floats as an
> + IFN_SQRT on vectors of N floats. */
> +
> +inline bool
> +vectorizable_internal_fn_p (internal_fn fn)
> +{
> + return direct_internal_fn_array[fn].vectorizable;
> +}
> +
> /* Return optab information about internal function FN. Only meaningful
> if direct_internal_fn_p (FN). */
> Index: gcc/tree-vect-slp.c
> ===================================================================
> --- gcc/tree-vect-slp.c 2018-05-16 11:02:46.262494712 +0100
> +++ gcc/tree-vect-slp.c 2018-05-16 11:12:11.873116180 +0100
> @@ -564,6 +564,41 @@ vect_get_and_check_slp_defs (vec_info *v
> return 0;
> }
> +/* Return true if call statements CALL1 and CALL2 are similar enough
> + to be combined into the same SLP group. */
> +
> +static bool
> +compatible_calls_p (gcall *call1, gcall *call2)
> +{
> + unsigned int nargs = gimple_call_num_args (call1);
> + if (nargs != gimple_call_num_args (call2))
> + return false;
> +
> + if (gimple_call_combined_fn (call1) != gimple_call_combined_fn (call2))
> + return false;
> +
> + if (gimple_call_internal_p (call1))
> + {
> + if (TREE_TYPE (gimple_call_lhs (call1))
> + != TREE_TYPE (gimple_call_lhs (call2)))
> + return false;
> + for (unsigned int i = 0; i < nargs; ++i)
> + if (TREE_TYPE (gimple_call_arg (call1, i))
> + != TREE_TYPE (gimple_call_arg (call2, i)))
Please use types_compatible_p in these two type comparisons.
Can you please add a generic vect_call_sqrtf to the main
vectorizer testsuite? In fact I already see
gcc.dg/vect/fast-math-bb-slp-call-1.c.
Does that mean SQRT does never appear as internal function before
vectorization?
OK with that changes.
Richard.
> + return false;
> + }
> + else
> + {
> + if (!operand_equal_p (gimple_call_fn (call1),
> + gimple_call_fn (call2), 0))
> + return false;
> +
> + if (gimple_call_fntype (call1) != gimple_call_fntype (call2))
> + return false;
> + }
> + return true;
> +}
> +
> /* A subroutine of vect_build_slp_tree for checking VECTYPE, which is the
> caller's attempt to find the vector type in STMT with the narrowest
> element type. Return true if VECTYPE is nonnull and if it is valid
> @@ -625,8 +660,8 @@ vect_record_max_nunits (vec_info *vinfo,
> static bool
> vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
> vec<gimple *> stmts, unsigned int group_size,
> - unsigned nops, poly_uint64 *max_nunits,
> - bool *matches, bool *two_operators)
> + poly_uint64 *max_nunits, bool *matches,
> + bool *two_operators)
> {
> unsigned int i;
> gimple *first_stmt = stmts[0], *stmt = stmts[0];
> @@ -698,7 +733,9 @@ vect_build_slp_tree_1 (vec_info *vinfo,
> if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
> {
> rhs_code = CALL_EXPR;
> - if (gimple_call_internal_p (call_stmt)
> + if ((gimple_call_internal_p (call_stmt)
> + && (!vectorizable_internal_fn_p
> + (gimple_call_internal_fn (call_stmt))))
> || gimple_call_tail_p (call_stmt)
> || gimple_call_noreturn_p (call_stmt)
> || !gimple_call_nothrow_p (call_stmt)
> @@ -833,11 +870,8 @@ vect_build_slp_tree_1 (vec_info *vinfo,
> if (rhs_code == CALL_EXPR)
> {
> gimple *first_stmt = stmts[0];
> - if (gimple_call_num_args (stmt) != nops
> - || !operand_equal_p (gimple_call_fn (first_stmt),
> - gimple_call_fn (stmt), 0)
> - || gimple_call_fntype (first_stmt)
> - != gimple_call_fntype (stmt))
> + if (!compatible_calls_p (as_a <gcall *> (first_stmt),
> + as_a <gcall *> (stmt)))
> {
> if (dump_enabled_p ())
> {
> @@ -1166,8 +1200,7 @@ vect_build_slp_tree_2 (vec_info *vinfo,
> bool two_operators = false;
> unsigned char *swap = XALLOCAVEC (unsigned char, group_size);
> - if (!vect_build_slp_tree_1 (vinfo, swap,
> - stmts, group_size, nops,
> + if (!vect_build_slp_tree_1 (vinfo, swap, stmts, group_size,
> &this_max_nunits, matches, &two_operators))
> return NULL;
> Index: gcc/testsuite/gcc.target/aarch64/sve/cond_arith_4.c
> ===================================================================
> --- /dev/null 2018-04-20 16:19:46.369131350 +0100
> +++ gcc/testsuite/gcc.target/aarch64/sve/cond_arith_4.c 2018-05-16
11:12:11.872116220 +0100
> @@ -0,0 +1,62 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -ftree-vectorize" } */
> +
> +#include <stdint.h>
> +
> +#define TEST(TYPE, NAME, OP) \
> + void __attribute__ ((noinline, noclone)) \
> + test_##TYPE##_##NAME (TYPE *__restrict x, \
> + TYPE *__restrict y, \
> + TYPE z1, TYPE z2, \
> + TYPE *__restrict pred, int n) \
> + { \
> + for (int i = 0; i < n; i += 2) \
> + {
\
> + x[i] = (pred[i] != 1 ? y[i] OP z1 : y[i]); \
> + x[i + 1] = (pred[i + 1] != 1 ? y[i + 1] OP z2 : y[i + 1]); \
> + }
\
> + }
> +
> +#define TEST_INT_TYPE(TYPE) \
> + TEST (TYPE, div, /)
> +
> +#define TEST_FP_TYPE(TYPE) \
> + TEST (TYPE, add, +) \
> + TEST (TYPE, sub, -) \
> + TEST (TYPE, mul, *) \
> + TEST (TYPE, div, /)
> +
> +#define TEST_ALL \
> + TEST_INT_TYPE (int32_t) \
> + TEST_INT_TYPE (uint32_t) \
> + TEST_INT_TYPE (int64_t) \
> + TEST_INT_TYPE (uint64_t) \
> + TEST_FP_TYPE (float) \
> + TEST_FP_TYPE (double)
> +
> +TEST_ALL
> +
> +/* { dg-final { scan-assembler-times {\tsdiv\tz[0-9]+\.s, p[0-7]/m,} 1 }
} */
> +/* { dg-final { scan-assembler-times {\tudiv\tz[0-9]+\.s, p[0-7]/m,} 1 }
} */
> +/* { dg-final { scan-assembler-times {\tsdiv\tz[0-9]+\.d, p[0-7]/m,} 1 }
} */
> +/* { dg-final { scan-assembler-times {\tudiv\tz[0-9]+\.d, p[0-7]/m,} 1 }
} */
> +
> +/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.s, p[0-7]/m,} 1 }
} */
> +/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.d, p[0-7]/m,} 1 }
} */
> +
> +/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.s, p[0-7]/m,} 1 }
} */
> +/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.d, p[0-7]/m,} 1 }
} */
> +
> +/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.s, p[0-7]/m,} 1 }
} */
> +/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.d, p[0-7]/m,} 1 }
} */
> +
> +/* { dg-final { scan-assembler-times {\tfdiv\tz[0-9]+\.s, p[0-7]/m,} 1 }
} */
> +/* { dg-final { scan-assembler-times {\tfdiv\tz[0-9]+\.d, p[0-7]/m,} 1 }
} */
> +
> +/* { dg-final { scan-assembler-times {\tld1w\tz[0-9]+\.s, p[0-7]/z,} 12
} } */
> +/* { dg-final { scan-assembler-times {\tst1w\tz[0-9]+\.s, p[0-7],} 6 } }
*/
> +
> +/* { dg-final { scan-assembler-times {\tld1d\tz[0-9]+\.d, p[0-7]/z,} 12
} } */
> +/* { dg-final { scan-assembler-times {\tst1d\tz[0-9]+\.d, p[0-7],} 6 } }
*/
> +
> +/* { dg-final { scan-assembler-not {\tsel\t} } } */
> Index: gcc/testsuite/gcc.target/aarch64/sve/cond_arith_4_run.c
> ===================================================================
> --- /dev/null 2018-04-20 16:19:46.369131350 +0100
> +++ gcc/testsuite/gcc.target/aarch64/sve/cond_arith_4_run.c
2018-05-16 11:12:11.872116220 +0100
> @@ -0,0 +1,32 @@
> +/* { dg-do run { target aarch64_sve_hw } } */
> +/* { dg-options "-O2 -ftree-vectorize" } */
> +
> +#include "cond_arith_4.c"
> +
> +#define N 98
> +
> +#undef TEST
> +#define TEST(TYPE, NAME, OP) \
> + { \
> + TYPE x[N], y[N], pred[N], z[2] = { 5, 7 }; \
> + for (int i = 0; i < N; ++i) \
> + { \
> + y[i] = i * i; \
> + pred[i] = i % 3; \
> + } \
> + test_##TYPE##_##NAME (x, y, z[0], z[1], pred, N); \
> + for (int i = 0; i < N; ++i) \
> + { \
> + TYPE expected = i % 3 != 1 ? y[i] OP z[i & 1] : y[i]; \
> + if (x[i] != expected) \
> + __builtin_abort (); \
> + asm volatile ("" ::: "memory"); \
> + } \
> + }
> +
> +int
> +main (void)
> +{
> + TEST_ALL
> + return 0;
> +}
> Index: gcc/testsuite/gcc.target/aarch64/sve/cond_arith_5.c
> ===================================================================
> --- /dev/null 2018-04-20 16:19:46.369131350 +0100
> +++ gcc/testsuite/gcc.target/aarch64/sve/cond_arith_5.c 2018-05-16
11:12:11.872116220 +0100
> @@ -0,0 +1,85 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -ftree-vectorize -fno-vect-cost-model" } */
> +
> +#include <stdint.h>
> +
> +#define TEST(DATA_TYPE, OTHER_TYPE, NAME, OP) \
> + void __attribute__ ((noinline, noclone)) \
> + test_##DATA_TYPE##_##OTHER_TYPE##_##NAME (DATA_TYPE *__restrict x, \
> + DATA_TYPE *__restrict y, \
> + DATA_TYPE z1, DATA_TYPE z2, \
> + DATA_TYPE *__restrict pred, \
> + OTHER_TYPE *__restrict foo, \
> + int n) \
> + { \
> + for (int i = 0; i < n; i += 2) \
> + {
\
> + x[i] = (pred[i] != 1 ? y[i] OP z1 : y[i]); \
> + x[i + 1] = (pred[i + 1] != 1 ? y[i + 1] OP z2 : y[i + 1]); \
> + foo[i] += 1; \
> + foo[i + 1] += 2; \
> + }
\
> + }
> +
> +#define TEST_INT_TYPE(DATA_TYPE, OTHER_TYPE) \
> + TEST (DATA_TYPE, OTHER_TYPE, div, /)
> +
> +#define TEST_FP_TYPE(DATA_TYPE, OTHER_TYPE) \
> + TEST (DATA_TYPE, OTHER_TYPE, add, +) \
> + TEST (DATA_TYPE, OTHER_TYPE, sub, -) \
> + TEST (DATA_TYPE, OTHER_TYPE, mul, *) \
> + TEST (DATA_TYPE, OTHER_TYPE, div, /)
> +
> +#define TEST_ALL \
> + TEST_INT_TYPE (int32_t, int8_t) \
> + TEST_INT_TYPE (int32_t, int16_t) \
> + TEST_INT_TYPE (uint32_t, int8_t) \
> + TEST_INT_TYPE (uint32_t, int16_t) \
> + TEST_INT_TYPE (int64_t, int8_t) \
> + TEST_INT_TYPE (int64_t, int16_t) \
> + TEST_INT_TYPE (int64_t, int32_t) \
> + TEST_INT_TYPE (uint64_t, int8_t) \
> + TEST_INT_TYPE (uint64_t, int16_t) \
> + TEST_INT_TYPE (uint64_t, int32_t) \
> + TEST_FP_TYPE (float, int8_t) \
> + TEST_FP_TYPE (float, int16_t) \
> + TEST_FP_TYPE (double, int8_t) \
> + TEST_FP_TYPE (double, int16_t) \
> + TEST_FP_TYPE (double, int32_t)
> +
> +TEST_ALL
> +
> +/* { dg-final { scan-assembler-times {\tsdiv\tz[0-9]+\.s, p[0-7]/m,} 6 }
} */
> +/* { dg-final { scan-assembler-times {\tudiv\tz[0-9]+\.s, p[0-7]/m,} 6 }
} */
> +/* { dg-final { scan-assembler-times {\tsdiv\tz[0-9]+\.d, p[0-7]/m,} 14
} } */
> +/* { dg-final { scan-assembler-times {\tudiv\tz[0-9]+\.d, p[0-7]/m,} 14
} } */
> +
> +/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.s, p[0-7]/m,} 6 }
} */
> +/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.d, p[0-7]/m,} 14
} } */
> +
> +/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.s, p[0-7]/m,} 6 }
} */
> +/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.d, p[0-7]/m,} 14
} } */
> +
> +/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.s, p[0-7]/m,} 6 }
} */
> +/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.d, p[0-7]/m,} 14
} } */
> +
> +/* { dg-final { scan-assembler-times {\tfdiv\tz[0-9]+\.s, p[0-7]/m,} 6 }
} */
> +/* { dg-final { scan-assembler-times {\tfdiv\tz[0-9]+\.d, p[0-7]/m,} 14
} } */
> +
> +/* The load XFAILs for fixed-length SVE account for extra loads from the
> + constant pool. */
> +/* { dg-final { scan-assembler-times {\tld1b\tz[0-9]+\.b, p[0-7]/z,} 12
{ xfail { aarch64_sve && { ! vect_variable_length } } } } } */
> +/* { dg-final { scan-assembler-times {\tst1b\tz[0-9]+\.b, p[0-7],} 12 }
} */
> +
> +/* { dg-final { scan-assembler-times {\tld1h\tz[0-9]+\.h, p[0-7]/z,} 12
{ xfail { aarch64_sve && { ! vect_variable_length } } } } } */
> +/* { dg-final { scan-assembler-times {\tst1h\tz[0-9]+\.h, p[0-7],} 12 }
} */
> +
> +/* 72 for x operations, 6 for foo operations. */
> +/* { dg-final { scan-assembler-times {\tld1w\tz[0-9]+\.s, p[0-7]/z,} 78
{ xfail { aarch64_sve && { ! vect_variable_length } } } } } */
> +/* 36 for x operations, 6 for foo operations. */
> +/* { dg-final { scan-assembler-times {\tst1w\tz[0-9]+\.s, p[0-7],} 42 }
} */
> +
> +/* { dg-final { scan-assembler-times {\tld1d\tz[0-9]+\.d, p[0-7]/z,} 168
} } */
> +/* { dg-final { scan-assembler-times {\tst1d\tz[0-9]+\.d, p[0-7],} 84 }
} */
> +
> +/* { dg-final { scan-assembler-not {\tsel\t} } } */
> Index: gcc/testsuite/gcc.target/aarch64/sve/cond_arith_5_run.c
> ===================================================================
> --- /dev/null 2018-04-20 16:19:46.369131350 +0100
> +++ gcc/testsuite/gcc.target/aarch64/sve/cond_arith_5_run.c
2018-05-16 11:12:11.873116180 +0100
> @@ -0,0 +1,35 @@
> +/* { dg-do run { target aarch64_sve_hw } } */
> +/* { dg-options "-O2 -ftree-vectorize" } */
> +
> +#include "cond_arith_5.c"
> +
> +#define N 98
> +
> +#undef TEST
> +#define TEST(DATA_TYPE, OTHER_TYPE, NAME, OP) \
> + { \
> + DATA_TYPE x[N], y[N], pred[N], z[2] = { 5, 7 }; \
> + OTHER_TYPE foo[N]; \
> + for (int i = 0; i < N; ++i)
\
> + {
\
> + y[i] = i * i; \
> + pred[i] = i % 3; \
> + foo[i] = i * 5; \
> + }
\
> + test_##DATA_TYPE##_##OTHER_TYPE##_##NAME (x, y, z[0], z[1],
\
> + pred, foo, N); \
> + for (int i = 0; i < N; ++i)
\
> + {
\
> + DATA_TYPE expected = i % 3 != 1 ? y[i] OP z[i & 1] : y[i]; \
> + if (x[i] != expected) \
> + __builtin_abort (); \
> + asm volatile ("" ::: "memory"); \
> + }
\
> + }
> +
> +int
> +main (void)
> +{
> + TEST_ALL
> + return 0;
> +}
> Index: gcc/testsuite/gcc.target/aarch64/sve/slp_14.c
> ===================================================================
> --- /dev/null 2018-04-20 16:19:46.369131350 +0100
> +++ gcc/testsuite/gcc.target/aarch64/sve/slp_14.c 2018-05-16
11:12:11.873116180 +0100
> @@ -0,0 +1,48 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -ftree-vectorize" } */
> +
> +#include <stdint.h>
> +
> +#define VEC_PERM(TYPE) \
> +void __attribute__ ((weak)) \
> +vec_slp_##TYPE (TYPE *restrict a, TYPE *restrict b, int n) \
> +{ \
> + for (int i = 0; i < n; ++i) \
> + { \
> + TYPE a1 = a[i * 2]; \
> + TYPE a2 = a[i * 2 + 1]; \
> + TYPE b1 = b[i * 2]; \
> + TYPE b2 = b[i * 2 + 1]; \
> + a[i * 2] = b1 > 1 ? a1 / b1 : a1; \
> + a[i * 2 + 1] = b2 > 2 ? a2 / b2 : a2; \
> + } \
> +}
> +
> +#define TEST_ALL(T) \
> + T (int32_t) \
> + T (uint32_t) \
> + T (int64_t) \
> + T (uint64_t) \
> + T (float) \
> + T (double)
> +
> +TEST_ALL (VEC_PERM)
> +
> +/* The loop should be fully-masked. The load XFAILs for fixed-length
> + SVE account for extra loads from the constant pool. */
> +/* { dg-final { scan-assembler-times {\tld1w\t} 6 { xfail { aarch64_sve
&& { ! vect_variable_length } } } } } */
> +/* { dg-final { scan-assembler-times {\tst1w\t} 3 } } */
> +/* { dg-final { scan-assembler-times {\tld1d\t} 6 { xfail { aarch64_sve
&& { ! vect_variable_length } } } } } */
> +/* { dg-final { scan-assembler-times {\tst1d\t} 3 } } */
> +/* { dg-final { scan-assembler-not {\tldr} } } */
> +/* { dg-final { scan-assembler-not {\tstr} } } */
> +
> +/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.s} 6 } } */
> +/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.d} 6 } } */
> +
> +/* { dg-final { scan-assembler-times {\tsdiv\tz[0-9]+\.s} 1 } } */
> +/* { dg-final { scan-assembler-times {\tudiv\tz[0-9]+\.s} 1 } } */
> +/* { dg-final { scan-assembler-times {\tfdiv\tz[0-9]+\.s} 1 } } */
> +/* { dg-final { scan-assembler-times {\tsdiv\tz[0-9]+\.d} 1 } } */
> +/* { dg-final { scan-assembler-times {\tudiv\tz[0-9]+\.d} 1 } } */
> +/* { dg-final { scan-assembler-times {\tfdiv\tz[0-9]+\.d} 1 } } */
> Index: gcc/testsuite/gcc.target/aarch64/sve/slp_14_run.c
> ===================================================================
> --- /dev/null 2018-04-20 16:19:46.369131350 +0100
> +++ gcc/testsuite/gcc.target/aarch64/sve/slp_14_run.c 2018-05-16
11:12:11.873116180 +0100
> @@ -0,0 +1,34 @@
> +/* { dg-do run { target aarch64_sve_hw } } */
> +/* { dg-options "-O2 -ftree-vectorize" } */
> +
> +#include "slp_14.c"
> +
> +#define N1 (103 * 2)
> +#define N2 (111 * 2)
> +
> +#define HARNESS(TYPE) \
> + { \
> + TYPE a[N2], b[N2]; \
> + for (unsigned int i = 0; i < N2; ++i) \
> + { \
> + a[i] = i * 2 + i % 5; \
> + b[i] = i % 11; \
> + } \
> + vec_slp_##TYPE (a, b, N1 / 2); \
> + for (unsigned int i = 0; i < N2; ++i) \
> + { \
> + TYPE orig_a = i * 2 + i % 5; \
> + TYPE orig_b = i % 11; \
> + TYPE expected_a = orig_a; \
> + if (i < N1 && orig_b > (i & 1 ? 2 : 1)) \
> + expected_a /= orig_b; \
> + if (a[i] != expected_a || b[i] != orig_b) \
> + __builtin_abort (); \
> + } \
> + }
> +
> +int
> +main (void)
> +{
> + TEST_ALL (HARNESS)
> +}
next prev parent reply other threads:[~2018-05-17 11:36 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-16 10:21 Richard Sandiford
2018-05-17 11:42 ` Richard Biener [this message]
2018-05-25 10:49 ` Richard Sandiford
2018-05-25 11:09 ` Richard Biener
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAFiYyc0F27eqfNjtukMJRJudMxBOKG0r0dwCJmQG5YcZ5Homhw@mail.gmail.com \
--to=richard.guenther@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=richard.sandiford@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).