diff options
author | Kyrylo Tkachov <kyrylo.tkachov@arm.com> | 2016-06-06 16:06:05 +0000 |
---|---|---|
committer | Kyrylo Tkachov <ktkachov@gcc.gnu.org> | 2016-06-06 16:06:05 +0000 |
commit | 36f9ad69336aeee0aa7cf2d8640fccbec8d659e1 (patch) | |
tree | bcfb07a9b834a240baa5c8658d3bcc74e6499f2b /gcc/ifcvt.c | |
parent | e8536e2b9f96f42d7f12f13254300476debd283a (diff) | |
download | gcc-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.c | 34 |
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)) |