aboutsummaryrefslogtreecommitdiff
path: root/gcc/simplify-rtx.c
diff options
context:
space:
mode:
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>2014-05-20 14:14:21 +0000
committerWilliam Schmidt <wschmidt@gcc.gnu.org>2014-05-20 14:14:21 +0000
commitec217bd88a7f9ac30e05ff43de51dda5e4b001d2 (patch)
treec70cebb42d5110d8ce5aba1d0dec49af965a4b52 /gcc/simplify-rtx.c
parentb2b222b31138eb3772cfd648ff2cf31be27ee30b (diff)
downloadgcc-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.c25
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:
{