aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorliuhongt <hongtao.liu@intel.com>2024-04-19 10:29:34 +0800
committerliuhongt <hongtao.liu@intel.com>2024-06-06 08:34:13 +0800
commit7876cde25cbd2f026a0ae488e5263e72f8e9bfa0 (patch)
tree3238e6ab9a5e72c32a1f723ad62874ee868b879a /gcc
parent10cb3336ba1ac89b258f627222e668b023a6d3d4 (diff)
downloadgcc-7876cde25cbd2f026a0ae488e5263e72f8e9bfa0.zip
gcc-7876cde25cbd2f026a0ae488e5263e72f8e9bfa0.tar.gz
gcc-7876cde25cbd2f026a0ae488e5263e72f8e9bfa0.tar.bz2
Simplify (AND (ASHIFTRT A imm) mask) to (LSHIFTRT A imm) for vector mode.
When mask is (1 << (prec - imm) - 1) which is used to clear upper bits of A, then it can be simplified to LSHIFTRT. i.e Simplify (and:v8hi (ashifrt:v8hi A 8) (const_vector 0xff x8)) to (lshifrt:v8hi A 8) gcc/ChangeLog: PR target/114428 * simplify-rtx.cc (simplify_context::simplify_binary_operation_1): Simplify (AND (ASHIFTRT A imm) mask) to (LSHIFTRT A imm) for specific mask. gcc/testsuite/ChangeLog: * gcc.target/i386/pr114428-1.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/simplify-rtx.cc25
-rw-r--r--gcc/testsuite/gcc.target/i386/pr114428-1.c39
2 files changed, 64 insertions, 0 deletions
diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index f6b4d73..9bc3ef9 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -4065,6 +4065,31 @@ simplify_context::simplify_binary_operation_1 (rtx_code code,
return tem;
}
+ /* (and:v4si
+ (ashiftrt:v4si A 16)
+ (const_vector: 0xffff x4))
+ is just (lshiftrt:v4si A 16). */
+ if (VECTOR_MODE_P (mode) && GET_CODE (op0) == ASHIFTRT
+ && (CONST_INT_P (XEXP (op0, 1))
+ || (GET_CODE (XEXP (op0, 1)) == CONST_VECTOR
+ && CONST_VECTOR_DUPLICATE_P (XEXP (op0, 1))))
+ && GET_CODE (op1) == CONST_VECTOR
+ && CONST_VECTOR_DUPLICATE_P (op1))
+ {
+ unsigned HOST_WIDE_INT shift_count
+ = (CONST_INT_P (XEXP (op0, 1))
+ ? UINTVAL (XEXP (op0, 1))
+ : UINTVAL (XVECEXP (XEXP (op0, 1), 0, 0)));
+ unsigned HOST_WIDE_INT inner_prec
+ = GET_MODE_PRECISION (GET_MODE_INNER (mode));
+
+ /* Avoid UD shift count. */
+ if (shift_count < inner_prec
+ && (UINTVAL (XVECEXP (op1, 0, 0))
+ == (HOST_WIDE_INT_1U << (inner_prec - shift_count)) - 1))
+ return simplify_gen_binary (LSHIFTRT, mode, XEXP (op0, 0), XEXP (op0, 1));
+ }
+
tem = simplify_byte_swapping_operation (code, mode, op0, op1);
if (tem)
return tem;
diff --git a/gcc/testsuite/gcc.target/i386/pr114428-1.c b/gcc/testsuite/gcc.target/i386/pr114428-1.c
new file mode 100644
index 0000000..927476f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr114428-1.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2" } */
+/* { dg-final { scan-assembler-times "psrlw" 1 } } */
+/* { dg-final { scan-assembler-times "psrld" 1 } } */
+/* { dg-final { scan-assembler-times "psrlq" 1 { target { ! ia32 } } } } */
+
+
+#define SHIFTC 12
+
+typedef int v4si __attribute__((vector_size(16)));
+typedef short v8hi __attribute__((vector_size(16)));
+typedef long long v2di __attribute__((vector_size(16)));
+
+v8hi
+foo1 (v8hi a)
+{
+ return
+ (a >> (16 - SHIFTC)) & (__extension__(v8hi){(1<<SHIFTC)-1, (1<<SHIFTC)-1,
+ (1<<SHIFTC)-1,(1<<SHIFTC)-1,
+ (1<<SHIFTC)-1, (1<<SHIFTC)-1,
+ (1<<SHIFTC)-1,(1<<SHIFTC)-1});
+}
+
+v4si
+foo2 (v4si a)
+{
+ return
+ (a >> (32 - SHIFTC)) & (__extension__(v4si){(1<<SHIFTC)-1, (1<<SHIFTC)-1,
+ (1<<SHIFTC)-1,(1<<SHIFTC)-1});
+}
+
+v2di
+__attribute__((target("avx512vl")))
+foo3 (v2di a)
+{
+ return
+ (a >> (long long)(64 - SHIFTC)) & (__extension__(v2di){(1ULL<<SHIFTC)-1,
+ (1ULL<<SHIFTC)-1});
+}