Remove dead vector comparisons

Message ID 03913c07-80db-63c6-2188-4a47d02ccc05@suse.cz
State New
Headers show
Series
  • Remove dead vector comparisons
Related show

Commit Message

Martin Liška July 10, 2020, 7:49 a.m.
As mentioned in the PR, we need to clean up orphan vector comparisons
that tend to happen be gimplification of VEC_COND_EXPR.

I've done that easily in expand_vector_comparison where I add these
to a bitmap used in simple DCE.

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

Ready to be installed?
Thanks,
Martin

gcc/ChangeLog:

	PR tree-optimization/96128
	* tree-vect-generic.c (expand_vector_comparison): Remove vector
	comparisons that don't have a usage.

gcc/testsuite/ChangeLog:

	PR tree-optimization/96128
	* gcc.target/s390/vector/pr96128.c: New test.
---
  .../gcc.target/s390/vector/pr96128.c          | 35 +++++++++++++++++++
  gcc/tree-vect-generic.c                       |  4 ++-
  2 files changed, 38 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/gcc.target/s390/vector/pr96128.c

-- 
2.27.0

Comments

Marek Polacek via Gcc-patches July 10, 2020, 8:24 a.m. | #1
On Fri, Jul 10, 2020 at 9:50 AM Martin Liška <mliska@suse.cz> wrote:
>

> As mentioned in the PR, we need to clean up orphan vector comparisons

> that tend to happen be gimplification of VEC_COND_EXPR.

>

> I've done that easily in expand_vector_comparison where I add these

> to a bitmap used in simple DCE.

>

> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

>

> Ready to be installed?


I don't like this much - the reason for the dead code is that the gimplifier,
while it manages to DCE the VEC_COND_EXPR because the value is not
needed, does not apply the same for the operands where only side-effects
would need to be kept.

But then if the vector comparisons would not be dead, the testcase
would still ICE even with your patch.  And the reason for the ICE is
that vector lowering checks

  if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code)
      && !expand_vec_cond_expr_p (type, TREE_TYPE (op0), code))
    {

while RTL expansion has

  /* For vector typed comparisons emit code to generate the desired
     all-ones or all-zeros mask.  */
  if (TREE_CODE (ops->type) == VECTOR_TYPE)
    {
      tree ifexp = build2 (ops->code, ops->type, arg0, arg1);
      if (VECTOR_BOOLEAN_TYPE_P (ops->type)
          && expand_vec_cmp_expr_p (TREE_TYPE (arg0), ops->type, ops->code))
        return expand_vec_cmp_expr (ops->type, ifexp, target);
      else
        gcc_unreachable ();

so vector lowering doesn't lower vector comparisons when we can expand
via a VEC_COND_EXPR but the RTL expansion code asserts this will not
be needed.

Thus this should either be fixed by re-instantiating the RTL expansion code
or handling vector comparisons in gimple-isel.cc at least when they need
to be expanded as VEC_COND_EXPR.

Richard.

> Thanks,

> Martin

>

> gcc/ChangeLog:

>

>         PR tree-optimization/96128

>         * tree-vect-generic.c (expand_vector_comparison): Remove vector

>         comparisons that don't have a usage.

>

> gcc/testsuite/ChangeLog:

>

>         PR tree-optimization/96128

>         * gcc.target/s390/vector/pr96128.c: New test.

> ---

>   .../gcc.target/s390/vector/pr96128.c          | 35 +++++++++++++++++++

>   gcc/tree-vect-generic.c                       |  4 ++-

>   2 files changed, 38 insertions(+), 1 deletion(-)

>   create mode 100644 gcc/testsuite/gcc.target/s390/vector/pr96128.c

>

> diff --git a/gcc/testsuite/gcc.target/s390/vector/pr96128.c b/gcc/testsuite/gcc.target/s390/vector/pr96128.c

> new file mode 100644

> index 00000000000..20abe5e515c

> --- /dev/null

> +++ b/gcc/testsuite/gcc.target/s390/vector/pr96128.c

> @@ -0,0 +1,35 @@

> +/* PR tree-optimization/96128 */

> +/* { dg-options "-march=z13" } */

> +

> +#define B_TEST(TYPE) { TYPE v __attribute__((vector_size(16))); (void)((v < v) < v); }

> +#ifdef __cplusplus

> +#define T_TEST(TYPE) { TYPE s; TYPE v __attribute__((vector_size(16))); __typeof((v<v)[0]) iv __attribute__((vector_size(16))); (void)((iv ? s : s) < v); }

> +#else

> +#define T_TEST(TYPE)

> +#endif

> +#define T(TYPE) B_TEST(TYPE) T_TEST(TYPE)

> +#ifdef __SIZEOF_INT128__

> +#define SIZEOF_MAXINT __SIZEOF_INT128__

> +#else

> +#define SIZEOF_MAXINT __SIZEOF_LONG_LONG__

> +#endif

> +

> +void f ()

> +{

> +  T(short)

> +  T(int)

> +  T(long)

> +  T(long long)

> +

> +  T_TEST(float)

> +  T_TEST(double)

> +  /* Avoid trouble with non-power-of-two sizes.

> +     Also avoid trouble with long double larger than integral types.  */

> +#if !defined(__i386__) && !defined(__x86_64__) && !defined(__m68k__) \

> +    && !defined(__ia64__) && !defined(__hppa__) \

> +    && (__SIZEOF_LONG_DOUBLE__ & (__SIZEOF_LONG_DOUBLE__ - 1)) == 0 \

> +    && __SIZEOF_LONG_DOUBLE__ <= 16 \

> +    && __SIZEOF_LONG_DOUBLE__ <= SIZEOF_MAXINT

> +  T_TEST(long double)

> +#endif

> +}

> diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c

> index f8bd26f2156..636104dea13 100644

> --- a/gcc/tree-vect-generic.c

> +++ b/gcc/tree-vect-generic.c

> @@ -415,7 +415,9 @@ expand_vector_comparison (gimple_stmt_iterator *gsi, tree type, tree op0,

>         }

>       }

>

> -  if (!uses.is_empty () && vec_cond_expr_only)

> +  if (uses.is_empty ())

> +    bitmap_set_bit (dce_ssa_names, SSA_NAME_VERSION (lhs));

> +  else if (vec_cond_expr_only)

>       return NULL_TREE;

>

>     tree t;

> --

> 2.27.0

>
Martin Liška July 27, 2020, 9:32 a.m. | #2
On 7/10/20 10:24 AM, Richard Biener wrote:
> On Fri, Jul 10, 2020 at 9:50 AM Martin Liška <mliska@suse.cz> wrote:

>>

>> As mentioned in the PR, we need to clean up orphan vector comparisons

>> that tend to happen be gimplification of VEC_COND_EXPR.

>>

>> I've done that easily in expand_vector_comparison where I add these

>> to a bitmap used in simple DCE.

>>

>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

>>

>> Ready to be installed?

> 

> I don't like this much - the reason for the dead code is that the gimplifier,

> while it manages to DCE the VEC_COND_EXPR because the value is not

> needed, does not apply the same for the operands where only side-effects

> would need to be kept.

> 

> But then if the vector comparisons would not be dead, the testcase

> would still ICE even with your patch.


Hello.

Question here is if one can write such a test-case? I would the target
would lower a vector comparison directly to a non-vector code?

>  And the reason for the ICE is

> that vector lowering checks

> 

>    if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code)

>        && !expand_vec_cond_expr_p (type, TREE_TYPE (op0), code))

>      {

> 

> while RTL expansion has

> 

>    /* For vector typed comparisons emit code to generate the desired

>       all-ones or all-zeros mask.  */

>    if (TREE_CODE (ops->type) == VECTOR_TYPE)

>      {

>        tree ifexp = build2 (ops->code, ops->type, arg0, arg1);

>        if (VECTOR_BOOLEAN_TYPE_P (ops->type)

>            && expand_vec_cmp_expr_p (TREE_TYPE (arg0), ops->type, ops->code))

>          return expand_vec_cmp_expr (ops->type, ifexp, target);

>        else

>          gcc_unreachable ();

> 

> so vector lowering doesn't lower vector comparisons when we can expand

> via a VEC_COND_EXPR but the RTL expansion code asserts this will not

> be needed.


Ah, ok, now I understand that.

> 

> Thus this should either be fixed by re-instantiating the RTL expansion code


Could you please explain what re-instantiating the RTL means?

> or handling vector comparisons in gimple-isel.cc at least when they need

> to be expanded as VEC_COND_EXPR.


That's doable but by something like:

   _1 = v_5(D) > { 0, 0, 0, 0, 0, 0, 0, 0 };
   _10 = VEC_COND_EXPR <_1, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 1, 1, 1, 1, 1, 1 }>;

which will be immediately expanded to in ISEL to:

   _10 = .VCOND (v_5(D), { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 1, 1, 1, 1, 1, 1 }, 109);

But I would need to redirect all uses of _1 to _10, right? Do we prefer to do this?

Thanks,
Martin

> 

> Richard.

> 

>> Thanks,

>> Martin

>>

>> gcc/ChangeLog:

>>

>>          PR tree-optimization/96128

>>          * tree-vect-generic.c (expand_vector_comparison): Remove vector

>>          comparisons that don't have a usage.

>>

>> gcc/testsuite/ChangeLog:

>>

>>          PR tree-optimization/96128

>>          * gcc.target/s390/vector/pr96128.c: New test.

>> ---

>>    .../gcc.target/s390/vector/pr96128.c          | 35 +++++++++++++++++++

>>    gcc/tree-vect-generic.c                       |  4 ++-

>>    2 files changed, 38 insertions(+), 1 deletion(-)

>>    create mode 100644 gcc/testsuite/gcc.target/s390/vector/pr96128.c

>>

>> diff --git a/gcc/testsuite/gcc.target/s390/vector/pr96128.c b/gcc/testsuite/gcc.target/s390/vector/pr96128.c

>> new file mode 100644

>> index 00000000000..20abe5e515c

>> --- /dev/null

>> +++ b/gcc/testsuite/gcc.target/s390/vector/pr96128.c

>> @@ -0,0 +1,35 @@

>> +/* PR tree-optimization/96128 */

>> +/* { dg-options "-march=z13" } */

>> +

>> +#define B_TEST(TYPE) { TYPE v __attribute__((vector_size(16))); (void)((v < v) < v); }

>> +#ifdef __cplusplus

>> +#define T_TEST(TYPE) { TYPE s; TYPE v __attribute__((vector_size(16))); __typeof((v<v)[0]) iv __attribute__((vector_size(16))); (void)((iv ? s : s) < v); }

>> +#else

>> +#define T_TEST(TYPE)

>> +#endif

>> +#define T(TYPE) B_TEST(TYPE) T_TEST(TYPE)

>> +#ifdef __SIZEOF_INT128__

>> +#define SIZEOF_MAXINT __SIZEOF_INT128__

>> +#else

>> +#define SIZEOF_MAXINT __SIZEOF_LONG_LONG__

>> +#endif

>> +

>> +void f ()

>> +{

>> +  T(short)

>> +  T(int)

>> +  T(long)

>> +  T(long long)

>> +

>> +  T_TEST(float)

>> +  T_TEST(double)

>> +  /* Avoid trouble with non-power-of-two sizes.

>> +     Also avoid trouble with long double larger than integral types.  */

>> +#if !defined(__i386__) && !defined(__x86_64__) && !defined(__m68k__) \

>> +    && !defined(__ia64__) && !defined(__hppa__) \

>> +    && (__SIZEOF_LONG_DOUBLE__ & (__SIZEOF_LONG_DOUBLE__ - 1)) == 0 \

>> +    && __SIZEOF_LONG_DOUBLE__ <= 16 \

>> +    && __SIZEOF_LONG_DOUBLE__ <= SIZEOF_MAXINT

>> +  T_TEST(long double)

>> +#endif

>> +}

>> diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c

>> index f8bd26f2156..636104dea13 100644

>> --- a/gcc/tree-vect-generic.c

>> +++ b/gcc/tree-vect-generic.c

>> @@ -415,7 +415,9 @@ expand_vector_comparison (gimple_stmt_iterator *gsi, tree type, tree op0,

>>          }

>>        }

>>

>> -  if (!uses.is_empty () && vec_cond_expr_only)

>> +  if (uses.is_empty ())

>> +    bitmap_set_bit (dce_ssa_names, SSA_NAME_VERSION (lhs));

>> +  else if (vec_cond_expr_only)

>>        return NULL_TREE;

>>

>>      tree t;

>> --

>> 2.27.0

>>
Marek Polacek via Gcc-patches July 27, 2020, 11:22 a.m. | #3
On Mon, Jul 27, 2020 at 11:32 AM Martin Liška <mliska@suse.cz> wrote:
>

> On 7/10/20 10:24 AM, Richard Biener wrote:

> > On Fri, Jul 10, 2020 at 9:50 AM Martin Liška <mliska@suse.cz> wrote:

> >>

> >> As mentioned in the PR, we need to clean up orphan vector comparisons

> >> that tend to happen be gimplification of VEC_COND_EXPR.

> >>

> >> I've done that easily in expand_vector_comparison where I add these

> >> to a bitmap used in simple DCE.

> >>

> >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

> >>

> >> Ready to be installed?

> >

> > I don't like this much - the reason for the dead code is that the gimplifier,

> > while it manages to DCE the VEC_COND_EXPR because the value is not

> > needed, does not apply the same for the operands where only side-effects

> > would need to be kept.

> >

> > But then if the vector comparisons would not be dead, the testcase

> > would still ICE even with your patch.

>

> Hello.

>

> Question here is if one can write such a test-case? I would the target

> would lower a vector comparison directly to a non-vector code?


Possibly you can't (looks like you need boolean vectors for this).  The
GIMPLE FE also does not support this yet (because it relies on the C
frontends type capabilities).

> >  And the reason for the ICE is

> > that vector lowering checks

> >

> >    if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code)

> >        && !expand_vec_cond_expr_p (type, TREE_TYPE (op0), code))

> >      {

> >

> > while RTL expansion has

> >

> >    /* For vector typed comparisons emit code to generate the desired

> >       all-ones or all-zeros mask.  */

> >    if (TREE_CODE (ops->type) == VECTOR_TYPE)

> >      {

> >        tree ifexp = build2 (ops->code, ops->type, arg0, arg1);

> >        if (VECTOR_BOOLEAN_TYPE_P (ops->type)

> >            && expand_vec_cmp_expr_p (TREE_TYPE (arg0), ops->type, ops->code))

> >          return expand_vec_cmp_expr (ops->type, ifexp, target);

> >        else

> >          gcc_unreachable ();

> >

> > so vector lowering doesn't lower vector comparisons when we can expand

> > via a VEC_COND_EXPR but the RTL expansion code asserts this will not

> > be needed.

>

> Ah, ok, now I understand that.

>

> >

> > Thus this should either be fixed by re-instantiating the RTL expansion code

>

> Could you please explain what re-instantiating the RTL means?


Put the code back that predates the gcc_unreachable ().

> > or handling vector comparisons in gimple-isel.cc at least when they need

> > to be expanded as VEC_COND_EXPR.

>

> That's doable but by something like:

>

>    _1 = v_5(D) > { 0, 0, 0, 0, 0, 0, 0, 0 };

>    _10 = VEC_COND_EXPR <_1, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 1, 1, 1, 1, 1, 1 }>;

>

> which will be immediately expanded to in ISEL to:

>

>    _10 = .VCOND (v_5(D), { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 1, 1, 1, 1, 1, 1 }, 109);

>

> But I would need to redirect all uses of _1 to _10, right? Do we prefer to do this?


not sure - it might be that _1 is always unused at least in the for it
appears in the testcase
(with the boolean vector).  Note that the boolean vector case is not
representable by
the .VCOND because of the different result type.  So the separate
comparison looks
like an artifact of the split from the VEC_COND_EXPR after all ...

The gimplifier has

static bool
verify_gimple_comparison (tree type, tree op0, tree op1, enum tree_code code)
{
...
  /* Or a boolean vector type with the same element count
     as the comparison operand types.  */
  else if (TREE_CODE (type) == VECTOR_TYPE
           && TREE_CODE (TREE_TYPE (type)) == BOOLEAN_TYPE)
    {

so it requires a BOOLEAN_TYPE vector.

I wonder what happens if we make vector lowering not allow the compare
expanded via expand_vec_cond_expr_p?

Richard.

> Thanks,

> Martin

>

> >

> > Richard.

> >

> >> Thanks,

> >> Martin

> >>

> >> gcc/ChangeLog:

> >>

> >>          PR tree-optimization/96128

> >>          * tree-vect-generic.c (expand_vector_comparison): Remove vector

> >>          comparisons that don't have a usage.

> >>

> >> gcc/testsuite/ChangeLog:

> >>

> >>          PR tree-optimization/96128

> >>          * gcc.target/s390/vector/pr96128.c: New test.

> >> ---

> >>    .../gcc.target/s390/vector/pr96128.c          | 35 +++++++++++++++++++

> >>    gcc/tree-vect-generic.c                       |  4 ++-

> >>    2 files changed, 38 insertions(+), 1 deletion(-)

> >>    create mode 100644 gcc/testsuite/gcc.target/s390/vector/pr96128.c

> >>

> >> diff --git a/gcc/testsuite/gcc.target/s390/vector/pr96128.c b/gcc/testsuite/gcc.target/s390/vector/pr96128.c

> >> new file mode 100644

> >> index 00000000000..20abe5e515c

> >> --- /dev/null

> >> +++ b/gcc/testsuite/gcc.target/s390/vector/pr96128.c

> >> @@ -0,0 +1,35 @@

> >> +/* PR tree-optimization/96128 */

> >> +/* { dg-options "-march=z13" } */

> >> +

> >> +#define B_TEST(TYPE) { TYPE v __attribute__((vector_size(16))); (void)((v < v) < v); }

> >> +#ifdef __cplusplus

> >> +#define T_TEST(TYPE) { TYPE s; TYPE v __attribute__((vector_size(16))); __typeof((v<v)[0]) iv __attribute__((vector_size(16))); (void)((iv ? s : s) < v); }

> >> +#else

> >> +#define T_TEST(TYPE)

> >> +#endif

> >> +#define T(TYPE) B_TEST(TYPE) T_TEST(TYPE)

> >> +#ifdef __SIZEOF_INT128__

> >> +#define SIZEOF_MAXINT __SIZEOF_INT128__

> >> +#else

> >> +#define SIZEOF_MAXINT __SIZEOF_LONG_LONG__

> >> +#endif

> >> +

> >> +void f ()

> >> +{

> >> +  T(short)

> >> +  T(int)

> >> +  T(long)

> >> +  T(long long)

> >> +

> >> +  T_TEST(float)

> >> +  T_TEST(double)

> >> +  /* Avoid trouble with non-power-of-two sizes.

> >> +     Also avoid trouble with long double larger than integral types.  */

> >> +#if !defined(__i386__) && !defined(__x86_64__) && !defined(__m68k__) \

> >> +    && !defined(__ia64__) && !defined(__hppa__) \

> >> +    && (__SIZEOF_LONG_DOUBLE__ & (__SIZEOF_LONG_DOUBLE__ - 1)) == 0 \

> >> +    && __SIZEOF_LONG_DOUBLE__ <= 16 \

> >> +    && __SIZEOF_LONG_DOUBLE__ <= SIZEOF_MAXINT

> >> +  T_TEST(long double)

> >> +#endif

> >> +}

> >> diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c

> >> index f8bd26f2156..636104dea13 100644

> >> --- a/gcc/tree-vect-generic.c

> >> +++ b/gcc/tree-vect-generic.c

> >> @@ -415,7 +415,9 @@ expand_vector_comparison (gimple_stmt_iterator *gsi, tree type, tree op0,

> >>          }

> >>        }

> >>

> >> -  if (!uses.is_empty () && vec_cond_expr_only)

> >> +  if (uses.is_empty ())

> >> +    bitmap_set_bit (dce_ssa_names, SSA_NAME_VERSION (lhs));

> >> +  else if (vec_cond_expr_only)

> >>        return NULL_TREE;

> >>

> >>      tree t;

> >> --

> >> 2.27.0

> >>

>
Martin Liška July 27, 2020, 12:50 p.m. | #4
On 7/27/20 1:22 PM, Richard Biener wrote:
> I wonder what happens if we make vector lowering not allow the compare

> expanded via expand_vec_cond_expr_p?


So the following patch survives bootstrap and tests on x86_64-linux-gnu:

diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index f8bd26f2156..fe6477c8592 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -419,8 +419,7 @@ expand_vector_comparison (gimple_stmt_iterator *gsi, tree type, tree op0,
      return NULL_TREE;
  
    tree t;
-  if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code)
-      && !expand_vec_cond_expr_p (type, TREE_TYPE (op0), code))
+  if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code))
      {
        if (VECTOR_BOOLEAN_TYPE_P (type)
           && SCALAR_INT_MODE_P (TYPE_MODE (type))

and provides a reasonable BIT_FIELD_REF expansion on the problematic s390x test-case.
Is it a way to go?

Martin
Marek Polacek via Gcc-patches July 27, 2020, 12:54 p.m. | #5
On Mon, Jul 27, 2020 at 2:50 PM Martin Liška <mliska@suse.cz> wrote:
>

> On 7/27/20 1:22 PM, Richard Biener wrote:

> > I wonder what happens if we make vector lowering not allow the compare

> > expanded via expand_vec_cond_expr_p?

>

> So the following patch survives bootstrap and tests on x86_64-linux-gnu:

>

> diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c

> index f8bd26f2156..fe6477c8592 100644

> --- a/gcc/tree-vect-generic.c

> +++ b/gcc/tree-vect-generic.c

> @@ -419,8 +419,7 @@ expand_vector_comparison (gimple_stmt_iterator *gsi, tree type, tree op0,

>       return NULL_TREE;

>

>     tree t;

> -  if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code)

> -      && !expand_vec_cond_expr_p (type, TREE_TYPE (op0), code))

> +  if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code))

>       {

>         if (VECTOR_BOOLEAN_TYPE_P (type)

>            && SCALAR_INT_MODE_P (TYPE_MODE (type))

>

> and provides a reasonable BIT_FIELD_REF expansion on the problematic s390x test-case.

> Is it a way to go?


If it avoids to do this expansion if the compare feeds supported
VEC_COND_EXPRs then
I think yes.

Richard.

>

> Martin

Patch

diff --git a/gcc/testsuite/gcc.target/s390/vector/pr96128.c b/gcc/testsuite/gcc.target/s390/vector/pr96128.c
new file mode 100644
index 00000000000..20abe5e515c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/pr96128.c
@@ -0,0 +1,35 @@ 
+/* PR tree-optimization/96128 */
+/* { dg-options "-march=z13" } */
+
+#define B_TEST(TYPE) { TYPE v __attribute__((vector_size(16))); (void)((v < v) < v); }
+#ifdef __cplusplus
+#define T_TEST(TYPE) { TYPE s; TYPE v __attribute__((vector_size(16))); __typeof((v<v)[0]) iv __attribute__((vector_size(16))); (void)((iv ? s : s) < v); }
+#else
+#define T_TEST(TYPE)
+#endif
+#define T(TYPE) B_TEST(TYPE) T_TEST(TYPE)
+#ifdef __SIZEOF_INT128__
+#define SIZEOF_MAXINT __SIZEOF_INT128__
+#else
+#define SIZEOF_MAXINT __SIZEOF_LONG_LONG__
+#endif
+
+void f ()
+{
+  T(short)
+  T(int)
+  T(long)
+  T(long long)
+
+  T_TEST(float)
+  T_TEST(double)
+  /* Avoid trouble with non-power-of-two sizes.
+     Also avoid trouble with long double larger than integral types.  */
+#if !defined(__i386__) && !defined(__x86_64__) && !defined(__m68k__) \
+    && !defined(__ia64__) && !defined(__hppa__) \
+    && (__SIZEOF_LONG_DOUBLE__ & (__SIZEOF_LONG_DOUBLE__ - 1)) == 0 \
+    && __SIZEOF_LONG_DOUBLE__ <= 16 \
+    && __SIZEOF_LONG_DOUBLE__ <= SIZEOF_MAXINT
+  T_TEST(long double)
+#endif
+}
diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index f8bd26f2156..636104dea13 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -415,7 +415,9 @@  expand_vector_comparison (gimple_stmt_iterator *gsi, tree type, tree op0,
  	}
      }
  
-  if (!uses.is_empty () && vec_cond_expr_only)
+  if (uses.is_empty ())
+    bitmap_set_bit (dce_ssa_names, SSA_NAME_VERSION (lhs));
+  else if (vec_cond_expr_only)
      return NULL_TREE;
  
    tree t;