Bug 66144 - vector element operator produces very bad code
Summary: vector element operator produces very bad code
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: ---
Assignee: Michael Meissner
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2015-05-14 15:43 UTC by Michael Gschwind
Modified: 2017-02-06 21:09 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2015-05-14 00:00:00


Attachments
Potential patch to do the optimization (2.31 KB, patch)
2017-02-02 22:46 UTC, Michael Meissner
Details | Diff
Potential patch to do the optimization (2.34 KB, patch)
2017-02-02 22:49 UTC, Michael Meissner
Details | Diff
Replacement proposed patch (2.35 KB, patch)
2017-02-03 00:41 UTC, Michael Meissner
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Gschwind 2015-05-14 15:43:28 UTC
Compiling the following input
#include <altivec.h>

vector char
test( vector char a, vector char b)
{
        return a == b;
}

generates the following output with gcc from from trunk/head with -O3 


test:
        vcmpequb 2,2,3
        xxlxor 32,32,32
        vspltisw 1,-1
        xxsel 34,32,33,34
        blr

The original first instruction already has the right answer, then it's recomputed!

The inverted condition
#include <altivec.h>

vector char
test( vector char a, vector char b)
{
        return a != b;
}


produces
test:
        vcmpequb 2,2,3
        xxlxor 33,33,33
        vspltisw 0,-1
        xxsel 34,32,33,34
        blr
Comment 1 Andrew Pinski 2015-05-14 15:47:46 UTC
I suspect a == b is all equals and not element by element equals.
Comment 2 Andrew Pinski 2015-05-14 15:49:59 UTC
(In reply to Andrew Pinski from comment #1)
> I suspect a == b is all equals and not element by element equals.

I am wrong.

From the manual:
Vector comparison is supported with standard comparison operators: ==, !=, <, <=, >, >=. Comparison operands can be vector expressions of integer-type or real-type. Comparison between integer-type vectors and real-type vectors are not supported. The result of the comparison is a vector of the same width and number of elements as the comparison operands with a signed integral element type.

Vectors are compared element-wise producing 0 when comparison is false and -1 (constant of the appropriate type where all bits are set) otherwise. Consider the following example.

     typedef int v4si __attribute__ ((vector_size (16)));
     
     v4si a = {1,2,3,4};
     v4si b = {3,2,1,4};
     v4si c;
     
     c = a >  b;     /* The result would be {0, 0,-1, 0}  */
     c = a == b;     /* The result would be {0,-1, 0,-1}  */
Comment 3 Segher Boessenkool 2015-05-14 20:36:34 UTC
Confirmed.  This code is generated by rs6000_emit_vector_cond_expr
and combine doesn't know how to simplify it (it tries though).
Comment 4 Michael Meissner 2017-02-02 22:46:48 UTC
Created attachment 40657 [details]
Potential patch to do the optimization
Comment 5 Michael Meissner 2017-02-02 22:49:47 UTC
Created attachment 40658 [details]
Potential patch to do the optimization
Comment 6 Michael Meissner 2017-02-03 00:41:04 UTC
Created attachment 40660 [details]
Replacement proposed patch
Comment 7 Michael Meissner 2017-02-06 21:08:09 UTC
Author: meissner
Date: Mon Feb  6 21:07:37 2017
New Revision: 245222

URL: https://gcc.gnu.org/viewcvs?rev=245222&root=gcc&view=rev
Log:
[gcc]
2017-02-06  Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/66144
	* config/rs6000/vector.md (vcond<mode><mode>): Allow the true and
	false values to be constant vectors with all 0 or all 1 bits set.
	(vcondu<mode><mode>): Likewise.
	* config/rs6000/predicates.md (vector_int_reg_or_same_bit): New
	predicate.
	(fpmask_comparison_operator): Update comment.
	(vecint_comparison_operator): New predicate.
	* config/rs6000/rs6000.c (rs6000_emit_vector_cond_expr): Optimize
	vector conditionals when the true and false values are constant
	vectors with all 0 bits or all 1 bits set.

[gcc/testsuite]
2017-02-06  Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/66144
	* gcc.target/powerpc/pr66144-1.c: New test.
	* gcc.target/powerpc/pr66144-2.c: Likewise.
	* gcc.target/powerpc/pr66144-3.c: Likewise.


Added:
    trunk/gcc/testsuite/gcc.target/powerpc/pr66144-1.c
    trunk/gcc/testsuite/gcc.target/powerpc/pr66144-2.c
    trunk/gcc/testsuite/gcc.target/powerpc/pr66144-3.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/rs6000/predicates.md
    trunk/gcc/config/rs6000/rs6000.c
    trunk/gcc/config/rs6000/vector.md
    trunk/gcc/testsuite/ChangeLog
Comment 8 Michael Meissner 2017-02-06 21:09:38 UTC
Fixed in subversion id 245222.