[v2] gimple-match.pd Add more optimization for gimple_cond
Checks
Commit Message
The link of PATCH v1: https://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg326661.html
This patch add another condition for gimple-cond optimization. Refer to
the following test case.
int foo1 (int data, int res)
{
res = data & 0xf;
res |= res << 4;
if (res < 0x22)
return 0x22;
return res;
}
with the compilation flag "-O2",
before this patch the log info of phiopt2 pass is
<bb 2> [local count: 1073741824]:
res_5 = data_1(D) & 15;
_6 = (unsigned int) res_5;
_7 = _6 * 17;
res_8 = (int) _7;
if (_7 <= 33)
goto <bb 3>; [21.72%]
else
goto <bb 4>; [78.28%]
<bb 3> [local count: 233216728]:
<bb 4> [local count: 1073741824]:
# _9 = PHI <res_8(2), 34(3)>
return _9;
after this patch the the log info of phiopt2 pass is
<bb 2> [local count: 1073741824]:
res_5 = data_1(D) & 15;
_6 = (unsigned int) res_5;
_7 = _6 * 17;
res_8 = (int) _7;
_10 = MAX_EXPR <_7, 34>;
_3 = (int) _10;
return _3;
This patch optimizes the phi node to generate "MAX_EXPR".
The root cause of minmax replacement failure is the type of "_7"
is unsigned, but the type of const_int "34" is signed. It makes
types_match (c2_type, from_type) return false. So I add another
condition to process this scenario.
gcc/ChangeLog:
* match.pd: Add another condition to process type mismatch.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/phi-opt-41.c: New test.
---
gcc/match.pd | 5 ++++-
gcc/testsuite/gcc.dg/tree-ssa/phi-opt-41.c | 24 ++++++++++++++++++++++
2 files changed, 28 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-41.c
@@ -5419,7 +5419,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& (types_match (c2_type, from_type)
|| (TYPE_PRECISION (c2_type) > TYPE_PRECISION (from_type)
&& (TYPE_UNSIGNED (from_type)
- || TYPE_SIGN (c2_type) == TYPE_SIGN (from_type)))))
+ || TYPE_SIGN (c2_type) == TYPE_SIGN (from_type)))
+ || (TYPE_UNSIGNED (from_type) != TYPE_UNSIGNED (c2_type)
+ && TYPE_PRECISION (c2_type) == TYPE_PRECISION (from_type)
+ && !TYPE_OVERFLOW_WRAPS (c2_type))))
{
if (cmp != EQ_EXPR)
code = minmax_from_comparison (cmp, @1, @3, @1, @2);
new file mode 100644
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-phiopt2" } */
+
+int foo1 (int data, int res)
+{
+ res = data & 0xf;
+ res |= res << 4;
+ if (res < 0x22)
+ return 0x22;
+ return res;
+}
+
+int foo2 (int data, int res)
+{
+ res = data & 0xf;
+ unsigned int r = res;
+ r*=17;
+ res = r;
+ if (r < 0x22)
+ return 0x22;
+ return res;
+}
+
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 2 "phiopt2" } } */
\ No newline at end of file