This patch adds a new if-conversion pattern for the following case: if (test) x = A; else x = B;
A and B are constants, abs(A - B) == 2^N, A != 0, B != 0 Bootstrapped and regtested on x86_64-linux. OK for trunk? -- Regards, Mikhail Maltsev gcc/testsuite/ChangeLog: 2016-05-23 Mikhail Maltsev <malts...@gmail.com> * gcc.dg/ifcvt-6.c: New test. gcc/ChangeLog: 2016-05-23 Mikhail Maltsev <malts...@gmail.com> * ifcvt.c (noce_try_store_flag_constants): Add new pattern.
From 32ef17083d1ca6222e4befb1e1d8bae42d71db3b Mon Sep 17 00:00:00 2001 From: Mikhail Maltsev <maltsevm@gmail.com> Date: Thu, 12 May 2016 15:23:03 +0300 Subject: [PATCH 2/2] Add ifcvt pattern diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index a9c146b..f06b05d 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -1260,6 +1260,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) { ST_ADD_FLAG, ST_SHIFT_FLAG, + ST_SHIFT_ADD_FLAG, ST_IOR_FLAG }; @@ -1384,6 +1385,12 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) normalize = -1; reversep = true; } + else if (exact_log2 (abs_hwi (diff)) >= 0 + && (STORE_FLAG_VALUE == 1 || if_info->branch_cost >= 2)) + { + strategy = ST_SHIFT_ADD_FLAG; + normalize = 1; + } else return FALSE; @@ -1453,6 +1460,19 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) gen_int_mode (ifalse, mode), if_info->x, 0, OPTAB_WIDEN); break; + case ST_SHIFT_ADD_FLAG: + { + /* if (test) x = 5; else x = 1; + => x = (test != 0) << 2 + 1; */ + HOST_WIDE_INT diff_log = exact_log2 (abs_hwi (diff)); + rtx diff_rtx + = expand_simple_binop (mode, ASHIFT, target, GEN_INT (diff_log), + if_info->x, 0, OPTAB_WIDEN); + target = expand_simple_binop (mode, (diff < 0) ? MINUS : PLUS, + gen_int_mode (ifalse, mode), diff_rtx, + if_info->x, 0, OPTAB_WIDEN); + break; + } } if (! target) diff --git a/gcc/testsuite/gcc.dg/ifcvt-6.c b/gcc/testsuite/gcc.dg/ifcvt-6.c new file mode 100644 index 0000000..c2cfb17 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ifcvt-6.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target x86_64-*-* } } */ +/* { dg-options "-fdump-rtl-ce1 -O2" } */ + +int +test1 (int a) +{ + return a % 2 != 0 ? 7 : 3; +} + +/* { dg-final { scan-rtl-dump "3 true changes made" "ce1" } } */ +/* { dg-final { scan-assembler-not "sbbl" } } */ -- 2.1.4