aboutsummaryrefslogtreecommitdiff
path: root/gcc/ifcvt.c
diff options
context:
space:
mode:
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>2016-06-06 16:06:05 +0000
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>2016-06-06 16:06:05 +0000
commit36f9ad69336aeee0aa7cf2d8640fccbec8d659e1 (patch)
treebcfb07a9b834a240baa5c8658d3bcc74e6499f2b /gcc/ifcvt.c
parente8536e2b9f96f42d7f12f13254300476debd283a (diff)
downloadgcc-36f9ad69336aeee0aa7cf2d8640fccbec8d659e1.zip
gcc-36f9ad69336aeee0aa7cf2d8640fccbec8d659e1.tar.gz
gcc-36f9ad69336aeee0aa7cf2d8640fccbec8d659e1.tar.bz2
[3/3][RTL ifcvt] PR middle-end/37780: Conditional expression with __builtin_clz() should be optimized out
PR middle-end/37780 * ifcvt.c (noce_try_ifelse_collapse): New function. Declare prototype. (noce_process_if_block): Call noce_try_ifelse_collapse. * simplify-rtx.c (simplify_cond_clz_ctz): New function. (simplify_ternary_operation): Use the above to simplify conditional CLZ/CTZ expressions. * gcc.c-torture/execute/pr37780.c: New test. * gcc.target/aarch64/pr37780_1.c: Likewise. * gcc.target/arm/pr37780_1.c: Likewise. From-SVN: r237141
Diffstat (limited to 'gcc/ifcvt.c')
-rw-r--r--gcc/ifcvt.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 44ae020..05fac71 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -817,6 +817,7 @@ struct noce_if_info
static rtx noce_emit_store_flag (struct noce_if_info *, rtx, int, int);
static int noce_try_move (struct noce_if_info *);
+static int noce_try_ifelse_collapse (struct noce_if_info *);
static int noce_try_store_flag (struct noce_if_info *);
static int noce_try_addcc (struct noce_if_info *);
static int noce_try_store_flag_constants (struct noce_if_info *);
@@ -1120,6 +1121,37 @@ noce_try_move (struct noce_if_info *if_info)
return FALSE;
}
+/* Try forming an IF_THEN_ELSE (cond, b, a) and collapsing that
+ through simplify_rtx. Sometimes that can eliminate the IF_THEN_ELSE.
+ If that is the case, emit the result into x. */
+
+static int
+noce_try_ifelse_collapse (struct noce_if_info * if_info)
+{
+ if (!noce_simple_bbs (if_info))
+ return FALSE;
+
+ machine_mode mode = GET_MODE (if_info->x);
+ rtx if_then_else = simplify_gen_ternary (IF_THEN_ELSE, mode, mode,
+ if_info->cond, if_info->b,
+ if_info->a);
+
+ if (GET_CODE (if_then_else) == IF_THEN_ELSE)
+ return FALSE;
+
+ rtx_insn *seq;
+ start_sequence ();
+ noce_emit_move_insn (if_info->x, if_then_else);
+ seq = end_ifcvt_sequence (if_info);
+ if (!seq)
+ return FALSE;
+
+ emit_insn_before_setloc (seq, if_info->jump,
+ INSN_LOCATION (if_info->insn_a));
+ return TRUE;
+}
+
+
/* Convert "if (test) x = 1; else x = 0".
Only try 0 and STORE_FLAG_VALUE here. Other combinations will be
@@ -3497,6 +3529,8 @@ noce_process_if_block (struct noce_if_info *if_info)
if (noce_try_move (if_info))
goto success;
+ if (noce_try_ifelse_collapse (if_info))
+ goto success;
if (noce_try_store_flag (if_info))
goto success;
if (noce_try_bitop (if_info))