diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 04423bbd1952f9dfcac4323e08ca5330759c57e0..c82101c73a46e300bc65eb2104a2205433ff5d24 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -2294,6 +2294,53 @@ comparison_code_valid_for_mode (enum rtx_code code, enum machine_mode mode) gcc_unreachable (); } } + +/* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right + false/true value of comparison with MODE where comparison operands + have CMP_MODE. */ + +static rtx +relational_result (machine_mode mode, machine_mode cmp_mode, rtx res) +{ + if (SCALAR_FLOAT_MODE_P (mode)) + { + if (res == const0_rtx) + return CONST0_RTX (mode); +#ifdef FLOAT_STORE_FLAG_VALUE + REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode); + return const_double_from_real_value (val, mode); +#else + return NULL_RTX; +#endif + } + if (VECTOR_MODE_P (mode)) + { + if (res == const0_rtx) + return CONST0_RTX (mode); +#ifdef VECTOR_STORE_FLAG_VALUE + rtx val = VECTOR_STORE_FLAG_VALUE (mode); + if (val == NULL_RTX) + return NULL_RTX; + if (val == const1_rtx) + return CONST1_RTX (mode); + + return gen_const_vec_duplicate (mode, val); +#else + return NULL_RTX; +#endif + } + /* For vector comparison with scalar int result, it is unknown + if the target means here a comparison into an integral bitmask, + or comparison where all comparisons true mean const_true_rtx + whole result, or where any comparisons true mean const_true_rtx + whole result. For const0_rtx all the cases are the same. */ + if (VECTOR_MODE_P (cmp_mode) + && SCALAR_INT_MODE_P (mode) + && res == const_true_rtx) + return NULL_RTX; + + return res; +} /* Simplify a logical operation CODE with result mode MODE, operating on OP0 and OP1, which should be both relational operations. Return 0 if no such @@ -2329,7 +2376,7 @@ simplify_context::simplify_logical_relational_operation (rtx_code code, int mask = mask0 | mask1; if (mask == 15) - return const_true_rtx; + return relational_result (mode, GET_MODE (op0), const_true_rtx); code = mask_to_comparison (mask); @@ -5315,51 +5362,7 @@ simplify_context::simplify_relational_operation (rtx_code code, tem = simplify_const_relational_operation (code, cmp_mode, op0, op1); if (tem) - { - if (SCALAR_FLOAT_MODE_P (mode)) - { - if (tem == const0_rtx) - return CONST0_RTX (mode); -#ifdef FLOAT_STORE_FLAG_VALUE - { - REAL_VALUE_TYPE val; - val = FLOAT_STORE_FLAG_VALUE (mode); - return const_double_from_real_value (val, mode); - } -#else - return NULL_RTX; -#endif - } - if (VECTOR_MODE_P (mode)) - { - if (tem == const0_rtx) - return CONST0_RTX (mode); -#ifdef VECTOR_STORE_FLAG_VALUE - { - rtx val = VECTOR_STORE_FLAG_VALUE (mode); - if (val == NULL_RTX) - return NULL_RTX; - if (val == const1_rtx) - return CONST1_RTX (mode); - - return gen_const_vec_duplicate (mode, val); - } -#else - return NULL_RTX; -#endif - } - /* For vector comparison with scalar int result, it is unknown - if the target means here a comparison into an integral bitmask, - or comparison where all comparisons true mean const_true_rtx - whole result, or where any comparisons true mean const_true_rtx - whole result. For const0_rtx all the cases are the same. */ - if (VECTOR_MODE_P (cmp_mode) - && SCALAR_INT_MODE_P (mode) - && tem == const_true_rtx) - return NULL_RTX; - - return tem; - } + return relational_result (mode, cmp_mode, tem); /* For the following tests, ensure const0_rtx is op1. */ if (swap_commutative_operands_p (op0, op1) diff --git a/gcc/testsuite/gcc.dg/pr101008.c b/gcc/testsuite/gcc.dg/pr101008.c new file mode 100644 index 0000000000000000000000000000000000000000..c06208d3425bf2867eb4f0fe82aa00eaf8411a4f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101008.c @@ -0,0 +1,18 @@ +/* PR rtl-optimization/101008 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g" } */ + +typedef unsigned __attribute__((__vector_size__(32))) U; +typedef unsigned __attribute__((__vector_size__(16))) V; + +int c, r; + +V v; + +void +foo(void) +{ + U u = __builtin_shufflevector (v, (V)(v != c) | (V)(c == v), + 4, 3, 5, 5, 1, 2, 3, 0); + r = ((union { U a; int b; }) u).b; +}