diff options
author | Bill Schmidt <wschmidt@linux.vnet.ibm.com> | 2014-05-20 14:14:21 +0000 |
---|---|---|
committer | William Schmidt <wschmidt@gcc.gnu.org> | 2014-05-20 14:14:21 +0000 |
commit | ec217bd88a7f9ac30e05ff43de51dda5e4b001d2 (patch) | |
tree | c70cebb42d5110d8ce5aba1d0dec49af965a4b52 /gcc/simplify-rtx.c | |
parent | b2b222b31138eb3772cfd648ff2cf31be27ee30b (diff) | |
download | gcc-ec217bd88a7f9ac30e05ff43de51dda5e4b001d2.zip gcc-ec217bd88a7f9ac30e05ff43de51dda5e4b001d2.tar.gz gcc-ec217bd88a7f9ac30e05ff43de51dda5e4b001d2.tar.bz2 |
simplify-rtx.c (simplify_binary_operation_1): Optimize case of nested VEC_SELECTs that are inverses of each other.
[gcc]
2014-05-20 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
* simplify-rtx.c (simplify_binary_operation_1): Optimize case of
nested VEC_SELECTs that are inverses of each other.
[gcc/testsuite]
2014-05-20 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
* gcc.target/powerpc/vsxcopy.c: New test.
From-SVN: r210644
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r-- | gcc/simplify-rtx.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 27e04f5..181b56f 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -3419,6 +3419,31 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode, } } + /* If we have two nested selects that are inverses of each + other, replace them with the source operand. */ + if (GET_CODE (trueop0) == VEC_SELECT + && GET_MODE (XEXP (trueop0, 0)) == mode) + { + rtx op0_subop1 = XEXP (trueop0, 1); + gcc_assert (GET_CODE (op0_subop1) == PARALLEL); + gcc_assert (XVECLEN (trueop1, 0) == GET_MODE_NUNITS (mode)); + + /* Apply the outer ordering vector to the inner one. (The inner + ordering vector is expressly permitted to be of a different + length than the outer one.) If the result is { 0, 1, ..., n-1 } + then the two VEC_SELECTs cancel. */ + for (int i = 0; i < XVECLEN (trueop1, 0); ++i) + { + rtx x = XVECEXP (trueop1, 0, i); + if (!CONST_INT_P (x)) + return 0; + rtx y = XVECEXP (op0_subop1, 0, INTVAL (x)); + if (!CONST_INT_P (y) || i != INTVAL (y)) + return 0; + } + return XEXP (trueop0, 0); + } + return 0; case VEC_CONCAT: { |