110 lines
3.6 KiB
Diff
110 lines
3.6 KiB
Diff
From 310eade1450995b55d9f8120561022fbf164b2ec Mon Sep 17 00:00:00 2001
|
|
From: Pronin Alexander 00812787 <pronin.alexander@huawei.com>
|
|
Date: Thu, 12 Jan 2023 14:52:49 +0300
|
|
Subject: [PATCH 03/18] Perform early if-conversion of simple arithmetic
|
|
|
|
---
|
|
gcc/common.opt | 4 ++++
|
|
gcc/match.pd | 25 +++++++++++++++++++
|
|
gcc/testsuite/gcc.dg/ifcvt-gimple.c | 37 +++++++++++++++++++++++++++++
|
|
3 files changed, 66 insertions(+)
|
|
create mode 100644 gcc/testsuite/gcc.dg/ifcvt-gimple.c
|
|
|
|
diff --git a/gcc/common.opt b/gcc/common.opt
|
|
index aa00fb7b0..dac477c04 100644
|
|
--- a/gcc/common.opt
|
|
+++ b/gcc/common.opt
|
|
@@ -1821,6 +1821,10 @@ fif-conversion2
|
|
Common Var(flag_if_conversion2) Optimization
|
|
Perform conversion of conditional jumps to conditional execution.
|
|
|
|
+fif-conversion-gimple
|
|
+Common Var(flag_if_conversion_gimple) Optimization
|
|
+Perform conversion of conditional jumps to branchless equivalents during gimple transformations.
|
|
+
|
|
fstack-reuse=
|
|
Common Joined RejectNegative Enum(stack_reuse_level) Var(flag_stack_reuse) Init(SR_ALL) Optimization
|
|
-fstack-reuse=[all|named_vars|none] Set stack reuse level for local variables.
|
|
diff --git a/gcc/match.pd b/gcc/match.pd
|
|
index 6f24d5079..3cbaf2a5b 100644
|
|
--- a/gcc/match.pd
|
|
+++ b/gcc/match.pd
|
|
@@ -4278,6 +4278,31 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
|
)
|
|
)
|
|
)
|
|
+
|
|
+(if (flag_if_conversion_gimple)
|
|
+ (for simple_op (plus minus bit_and bit_ior bit_xor)
|
|
+ (simplify
|
|
+ (cond @0 (simple_op @1 INTEGER_CST@2) @1)
|
|
+ (switch
|
|
+ /* a = cond ? a + 1 : a -> a = a + ((int) cond) */
|
|
+ (if (integer_onep (@2))
|
|
+ (simple_op @1 (convert (convert:boolean_type_node @0))))
|
|
+ /* a = cond ? a + powerof2cst : a ->
|
|
+ a = a + ((int) cond) << log2 (powerof2cst) */
|
|
+ (if (INTEGRAL_TYPE_P (type) && integer_pow2p (@2))
|
|
+ (with
|
|
+ {
|
|
+ tree shift = build_int_cst (integer_type_node, tree_log2 (@2));
|
|
+ }
|
|
+ (simple_op @1 (lshift (convert (convert:boolean_type_node @0))
|
|
+ { shift; })
|
|
+ )
|
|
+ )
|
|
+ )
|
|
+ )
|
|
+ )
|
|
+ )
|
|
+)
|
|
#endif
|
|
|
|
#if GIMPLE
|
|
diff --git a/gcc/testsuite/gcc.dg/ifcvt-gimple.c b/gcc/testsuite/gcc.dg/ifcvt-gimple.c
|
|
new file mode 100644
|
|
index 000000000..0f7c87e5c
|
|
--- /dev/null
|
|
+++ b/gcc/testsuite/gcc.dg/ifcvt-gimple.c
|
|
@@ -0,0 +1,37 @@
|
|
+/* { dg-do compile } */
|
|
+/* { dg-options "-O2 -fif-conversion-gimple -fdump-tree-optimized" } */
|
|
+
|
|
+int test_int (int optimizable_int) {
|
|
+ if (optimizable_int > 5)
|
|
+ ++optimizable_int;
|
|
+ return optimizable_int;
|
|
+}
|
|
+
|
|
+int test_int_pow2 (int optimizable_int_pow2) {
|
|
+ if (optimizable_int_pow2 <= 4)
|
|
+ optimizable_int_pow2 += 1024;
|
|
+ return optimizable_int_pow2;
|
|
+}
|
|
+
|
|
+int test_int_non_pow2 (int not_optimizable_int_non_pow2) {
|
|
+ if (not_optimizable_int_non_pow2 == 1)
|
|
+ not_optimizable_int_non_pow2 += 513;
|
|
+ return not_optimizable_int_non_pow2;
|
|
+}
|
|
+
|
|
+float test_float (float not_optimizable_float) {
|
|
+ if (not_optimizable_float > 5)
|
|
+ not_optimizable_float += 1;
|
|
+ return not_optimizable_float;
|
|
+}
|
|
+
|
|
+/* Expecting if-else block in test_float and test_int_non_pow2 only. */
|
|
+/* { dg-final { scan-tree-dump-not "if \\(optimizable" "optimized" } } */
|
|
+/* { dg-final { scan-tree-dump "if \\(not_optimizable_int_non_pow2" "optimized" } } */
|
|
+/* { dg-final { scan-tree-dump "if \\(not_optimizable_float" "optimized" } } */
|
|
+/* { dg-final { scan-tree-dump-times "if " 2 "optimized" } } */
|
|
+/* { dg-final { scan-tree-dump-times "else" 2 "optimized" } } */
|
|
+
|
|
+/* Expecting shifted result only for optimizable_int_pow2. */
|
|
+/* { dg-final { scan-tree-dump-times " << " 1 "optimized" } } */
|
|
+/* { dg-final { scan-tree-dump " << 10;" "optimized" } } */
|
|
--
|
|
2.33.0
|
|
|