Add const folding for all the aarch64 __crc32 intrinsics.
Added tests to ensure the values are computed as expected.
gcc/ChangeLog:
* config/aarch64/aarch64-builtins.cc (aarch64_general_fold_builtin): Add
constant folding for crc32 and crc32c intrinsics by invoking
calculate_reversed_crc with the appropriate polynomial.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/crc32-zero.c: Removed constant folding
test cases.
* gcc.target/aarch64/crc32-const-fold.c: New test.
* gcc.target/aarch64/crc32c-const-fold.c: New test.
Signed-off-by: Shreesh Adiga <[email protected]>
---
gcc/config/aarch64/aarch64-builtins.cc | 28 ++++
.../gcc.target/aarch64/crc32-const-fold.c | 147 ++++++++++++++++++
gcc/testsuite/gcc.target/aarch64/crc32-zero.c | 56 -------
.../gcc.target/aarch64/crc32c-const-fold.c | 147 ++++++++++++++++++
4 files changed, 322 insertions(+), 56 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/aarch64/crc32-const-fold.c
create mode 100644 gcc/testsuite/gcc.target/aarch64/crc32c-const-fold.c
diff --git a/gcc/config/aarch64/aarch64-builtins.cc
b/gcc/config/aarch64/aarch64-builtins.cc
index 8a82b131b72..1ed13e80bc6 100644
--- a/gcc/config/aarch64/aarch64-builtins.cc
+++ b/gcc/config/aarch64/aarch64-builtins.cc
@@ -4565,6 +4565,34 @@ aarch64_general_fold_builtin (unsigned int fcode, tree
type,
if (aarch64_fold_builtin_lane_check (args[0], args[1], args[2]))
return void_node;
break;
+ case AARCH64_BUILTIN_crc32b:
+ case AARCH64_BUILTIN_crc32h:
+ case AARCH64_BUILTIN_crc32w:
+ case AARCH64_BUILTIN_crc32x:
+ case AARCH64_BUILTIN_crc32cb:
+ case AARCH64_BUILTIN_crc32ch:
+ case AARCH64_BUILTIN_crc32cw:
+ case AARCH64_BUILTIN_crc32cx:
+ gcc_assert (n_args == 2);
+ if (tree_fits_uhwi_p (args[0]) && tree_fits_uhwi_p (args[1]))
+ {
+ unsigned HOST_WIDE_INT crc = tree_to_uhwi (args[0]);
+ unsigned HOST_WIDE_INT data = tree_to_uhwi (args[1]);
+ unsigned short data_bits = TYPE_PRECISION (TREE_TYPE (args[1]));
+ unsigned HOST_WIDE_INT polynomial;
+ if (fcode == AARCH64_BUILTIN_crc32b
+ || fcode == AARCH64_BUILTIN_crc32h
+ || fcode == AARCH64_BUILTIN_crc32w
+ || fcode == AARCH64_BUILTIN_crc32x)
+ polynomial = 0x04C11DB7;
+ else
+ polynomial = 0x1EDC6F41;
+ unsigned HOST_WIDE_INT res = calculate_reversed_crc (crc, data,
+ polynomial,
+ 32, data_bits);
+ return build_int_cstu (type, res);
+ }
+ break;
default:
break;
}
diff --git a/gcc/testsuite/gcc.target/aarch64/crc32-const-fold.c
b/gcc/testsuite/gcc.target/aarch64/crc32-const-fold.c
new file mode 100644
index 00000000000..bc64d08de8f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/crc32-const-fold.c
@@ -0,0 +1,147 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv8-a+crc -fdump-tree-optimized" } */
+
+unsigned int
+test_crc32_u8_1 ()
+{
+ return __builtin_aarch64_crc32b (0x02a24bf8, 0xba);
+}
+
+unsigned int
+test_crc32_u8_2 ()
+{
+ return __builtin_aarch64_crc32b (0x0cd5e10f, 0xe7);
+}
+
+unsigned int
+test_crc32_u8_3 ()
+{
+ return __builtin_aarch64_crc32b (0x50e739b8, 0x2e);
+}
+
+unsigned int
+test_crc32_u8_4 ()
+{
+ return __builtin_aarch64_crc32b (0x3c2db116, 0x3d);
+}
+
+unsigned int
+test_crc32_u8_5 ()
+{
+ return __builtin_aarch64_crc32b (-1, -1);
+}
+
+unsigned int
+test_crc32_u16_1 ()
+{
+ return __builtin_aarch64_crc32h (0x02a24bf8, 0xd4ba);
+}
+
+unsigned int
+test_crc32_u16_2 ()
+{
+ return __builtin_aarch64_crc32h (0x0cd5e10f, 0x42e7);
+}
+
+unsigned int
+test_crc32_u16_3 ()
+{
+ return __builtin_aarch64_crc32h (0x50e739b8, 0x382e);
+}
+
+unsigned int
+test_crc32_u16_4 ()
+{
+ return __builtin_aarch64_crc32h (0x3c2db116, 0x7f3d);
+}
+
+unsigned int
+test_crc32_u16_5 ()
+{
+ return __builtin_aarch64_crc32h (-1, -1);
+}
+
+unsigned int
+test_crc32_u32_1 ()
+{
+ return __builtin_aarch64_crc32w (0x02a24bf8, 0xf37dd4ba);
+}
+
+unsigned int
+test_crc32_u32_2 ()
+{
+ return __builtin_aarch64_crc32w (0x0cd5e10f, 0x832b42e7);
+}
+
+unsigned int
+test_crc32_u32_3 ()
+{
+ return __builtin_aarch64_crc32w (0x50e739b8, 0xcefb382e);
+}
+
+unsigned int
+test_crc32_u32_4 ()
+{
+ return __builtin_aarch64_crc32w (0x3c2db116, 0xd3947f3d);
+}
+
+unsigned int
+test_crc32_u32_5 ()
+{
+ return __builtin_aarch64_crc32w (-1, -1);
+}
+
+unsigned int
+test_crc32_u64_1 ()
+{
+ return __builtin_aarch64_crc32x (0x02a24bf8, 0x894a58bff37dd4ba);
+}
+
+unsigned int
+test_crc32_u64_2 ()
+{
+ return __builtin_aarch64_crc32x (0x0cd5e10f, 0x24334e2e832b42e7);
+}
+
+unsigned int
+test_crc32_u64_3 ()
+{
+ return __builtin_aarch64_crc32x (0x50e739b8, 0x289ee1b7cefb382e);
+}
+
+unsigned int
+test_crc32_u64_4 ()
+{
+ return __builtin_aarch64_crc32x (0x3c2db116, 0xa89143dad3947f3d);
+}
+
+unsigned int
+test_crc32_u64_5 ()
+{
+ return __builtin_aarch64_crc32x (-1, -1);
+}
+
+/* Test that there is no crc32 instruction emitted. */
+/* { dg-final { scan-assembler-not "crc32\[bhwx\]" } } */
+
+/* Test that the builtins are folded to the expected values. */
+/* { dg-final { scan-tree-dump-times "return 2563801847;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 2933768107;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 423416136;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 2894124273;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 16777215;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 2734662128;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 3648554851;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 1344032237;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 179056371;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 65535;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 189297697;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 1070454892;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 1747531601;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 3920656749;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 0;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 1565043101;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 3369685291;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 2806525577;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 605909632;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 3736805603;" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/crc32-zero.c
b/gcc/testsuite/gcc.target/aarch64/crc32-zero.c
index 4c5bdbef7e1..690445a569a 100644
--- a/gcc/testsuite/gcc.target/aarch64/crc32-zero.c
+++ b/gcc/testsuite/gcc.target/aarch64/crc32-zero.c
@@ -18,12 +18,6 @@ crc32cb_data_zero(uint32_t x)
return __builtin_aarch64_crc32cb(x, 0);
}
-uint32_t
-crc32cb_both_zero(void)
-{
- return __builtin_aarch64_crc32cb(0, 0);
-}
-
uint32_t
crc32ch_init_zero(uint16_t x)
{
@@ -36,12 +30,6 @@ crc32ch_data_zero(uint32_t x)
return __builtin_aarch64_crc32ch(x, 0);
}
-uint32_t
-crc32ch_both_zero(void)
-{
- return __builtin_aarch64_crc32ch(0, 0);
-}
-
uint32_t
crc32cw_init_zero(uint32_t x)
{
@@ -54,12 +42,6 @@ crc32cw_data_zero(uint32_t x)
return __builtin_aarch64_crc32cw(x, 0);
}
-uint32_t
-crc32cw_both_zero(void)
-{
- return __builtin_aarch64_crc32cw(0, 0);
-}
-
uint32_t
crc32cx_data_zero(uint32_t x)
{
@@ -72,12 +54,6 @@ crc32cx_init_zero64(uint64_t x)
return __builtin_aarch64_crc32cx(0, x);
}
-uint32_t
-crc32cx_both_zero64(void)
-{
- return __builtin_aarch64_crc32cx(0, 0);
-}
-
uint32_t
crc32b_init_zero(uint16_t x)
{
@@ -90,12 +66,6 @@ crc32b_data_zero(uint32_t x)
return __builtin_aarch64_crc32b(x, 0);
}
-uint32_t
-crc32b_both_zero(void)
-{
- return __builtin_aarch64_crc32b(0, 0);
-}
-
uint32_t
crc32h_init_zero(uint16_t x)
{
@@ -108,12 +78,6 @@ crc32h_data_zero(uint32_t x)
return __builtin_aarch64_crc32h(x, 0);
}
-uint32_t
-crc32h_both_zero(void)
-{
- return __builtin_aarch64_crc32h(0, 0);
-}
-
uint32_t
crc32w_init_zero(uint32_t x)
{
@@ -126,12 +90,6 @@ crc32w_data_zero(uint32_t x)
return __builtin_aarch64_crc32w(x, 0);
}
-uint32_t
-crc32w_both_zero(void)
-{
- return __builtin_aarch64_crc32w(0, 0);
-}
-
uint32_t
crc32x_data_zero(uint32_t x)
{
@@ -144,12 +102,6 @@ crc32x_init_zero64(uint64_t x)
return __builtin_aarch64_crc32x(0, x);
}
-uint32_t
-crc32x_both_zero64(void)
-{
- return __builtin_aarch64_crc32x(0, 0);
-}
-
/* { dg-final { scan-assembler-times "crc32b\tw\[0-9\]+, wzr, w\[0-9\]+" 1 } }
*/
/* { dg-final { scan-assembler-times "crc32h\tw\[0-9\]+, wzr, w\[0-9\]+" 1 } }
*/
/* { dg-final { scan-assembler-times "crc32w\tw\[0-9\]+, wzr, w\[0-9\]+" 1 } }
*/
@@ -158,10 +110,6 @@ crc32x_both_zero64(void)
/* { dg-final { scan-assembler-times "crc32h\tw\[0-9\]+, w\[0-9\]+, wzr" 1 } }
*/
/* { dg-final { scan-assembler-times "crc32w\tw\[0-9\]+, w\[0-9\]+, wzr" 1 } }
*/
/* { dg-final { scan-assembler-times "crc32x\tw\[0-9\]+, w\[0-9\]+, xzr" 1 } }
*/
-/* { dg-final { scan-assembler-times "crc32b\tw\[0-9\]+, wzr, wzr" 1 } } */
-/* { dg-final { scan-assembler-times "crc32h\tw\[0-9\]+, wzr, wzr" 1 } } */
-/* { dg-final { scan-assembler-times "crc32w\tw\[0-9\]+, wzr, wzr" 1 } } */
-/* { dg-final { scan-assembler-times "crc32x\tw\[0-9\]+, wzr, xzr" 1 } } */
/* { dg-final { scan-assembler-times "crc32cb\tw\[0-9\]+, wzr, w\[0-9\]+" 1 }
} */
/* { dg-final { scan-assembler-times "crc32ch\tw\[0-9\]+, wzr, w\[0-9\]+" 1 }
} */
/* { dg-final { scan-assembler-times "crc32cw\tw\[0-9\]+, wzr, w\[0-9\]+" 1 }
} */
@@ -170,10 +118,6 @@ crc32x_both_zero64(void)
/* { dg-final { scan-assembler-times "crc32ch\tw\[0-9\]+, w\[0-9\]+, wzr" 1 }
} */
/* { dg-final { scan-assembler-times "crc32cw\tw\[0-9\]+, w\[0-9\]+, wzr" 1 }
} */
/* { dg-final { scan-assembler-times "crc32cx\tw\[0-9\]+, w\[0-9\]+, xzr" 1 }
} */
-/* { dg-final { scan-assembler-times "crc32cb\tw\[0-9\]+, wzr, wzr" 1 } } */
-/* { dg-final { scan-assembler-times "crc32ch\tw\[0-9\]+, wzr, wzr" 1 } } */
-/* { dg-final { scan-assembler-times "crc32cw\tw\[0-9\]+, wzr, wzr" 1 } } */
-/* { dg-final { scan-assembler-times "crc32cx\tw\[0-9\]+, wzr, xzr" 1 } } */
/* There should be no moves to a register for zero as it is part of the
* crc instruction now.
diff --git a/gcc/testsuite/gcc.target/aarch64/crc32c-const-fold.c
b/gcc/testsuite/gcc.target/aarch64/crc32c-const-fold.c
new file mode 100644
index 00000000000..f9dda04bd96
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/crc32c-const-fold.c
@@ -0,0 +1,147 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv8-a+crc -fdump-tree-optimized" } */
+
+unsigned int
+test_crc32c_u8_1 ()
+{
+ return __builtin_aarch64_crc32cb (0x02a24bf8, 0xba);
+}
+
+unsigned int
+test_crc32c_u8_2 ()
+{
+ return __builtin_aarch64_crc32cb (0x0cd5e10f, 0xe7);
+}
+
+unsigned int
+test_crc32c_u8_3 ()
+{
+ return __builtin_aarch64_crc32cb (0x50e739b8, 0x2e);
+}
+
+unsigned int
+test_crc32c_u8_4 ()
+{
+ return __builtin_aarch64_crc32cb (0x3c2db116, 0x3d);
+}
+
+unsigned int
+test_crc32c_u8_5 ()
+{
+ return __builtin_aarch64_crc32cb (-1, -1);
+}
+
+unsigned int
+test_crc32c_u16_1 ()
+{
+ return __builtin_aarch64_crc32ch (0x02a24bf8, 0xd4ba);
+}
+
+unsigned int
+test_crc32c_u16_2 ()
+{
+ return __builtin_aarch64_crc32ch (0x0cd5e10f, 0x42e7);
+}
+
+unsigned int
+test_crc32c_u16_3 ()
+{
+ return __builtin_aarch64_crc32ch (0x50e739b8, 0x382e);
+}
+
+unsigned int
+test_crc32c_u16_4 ()
+{
+ return __builtin_aarch64_crc32ch (0x3c2db116, 0x7f3d);
+}
+
+unsigned int
+test_crc32c_u16_5 ()
+{
+ return __builtin_aarch64_crc32ch (-1, -1);
+}
+
+unsigned int
+test_crc32c_u32_1 ()
+{
+ return __builtin_aarch64_crc32cw (0x02a24bf8, 0xf37dd4ba);
+}
+
+unsigned int
+test_crc32c_u32_2 ()
+{
+ return __builtin_aarch64_crc32cw (0x0cd5e10f, 0x832b42e7);
+}
+
+unsigned int
+test_crc32c_u32_3 ()
+{
+ return __builtin_aarch64_crc32cw (0x50e739b8, 0xcefb382e);
+}
+
+unsigned int
+test_crc32c_u32_4 ()
+{
+ return __builtin_aarch64_crc32cw (0x3c2db116, 0xd3947f3d);
+}
+
+unsigned int
+test_crc32c_u32_5 ()
+{
+ return __builtin_aarch64_crc32cw (-1, -1);
+}
+
+unsigned int
+test_crc32c_u64_1 ()
+{
+ return __builtin_aarch64_crc32cx (0x02a24bf8, 0x894a58bff37dd4ba);
+}
+
+unsigned int
+test_crc32c_u64_2 ()
+{
+ return __builtin_aarch64_crc32cx (0x0cd5e10f, 0x24334e2e832b42e7);
+}
+
+unsigned int
+test_crc32c_u64_3 ()
+{
+ return __builtin_aarch64_crc32cx (0x50e739b8, 0x289ee1b7cefb382e);
+}
+
+unsigned int
+test_crc32c_u64_4 ()
+{
+ return __builtin_aarch64_crc32cx (0x3c2db116, 0xa89143dad3947f3d);
+}
+
+unsigned int
+test_crc32c_u64_5 ()
+{
+ return __builtin_aarch64_crc32cx (-1, -1);
+}
+
+/* Test that there is no crc32 instruction emitted. */
+/* { dg-final { scan-assembler-not "crc32c\[bhwx\]" } } */
+
+/* Test that the builtins are folded to the expected values. */
+/* { dg-final { scan-tree-dump-times "return 2688732928;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 1776624948;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 3025796294;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 3104311380;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 16777215;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 350827643;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 1464882880;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 1604487598;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 3113037293;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 65535;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 2122844148;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 881727033;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 139192539;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 1861871255;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 0;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 3230864714;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 337502055;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 712052683;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 1390230251;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 3080238136;" 1 "optimized" } } */
--
2.55.0