+2015-09-28 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR rtl-optimization/67456
+ PR rtl-optimization/67464
+ PR rtl-optimization/67465
+ * ifcvt.c (noce_try_cmove_arith): Bail out if cannot conditionally
+ move in the mode of x. Handle combination of complex and simple
+ block pairs as well as the case when one is empty.
+
2015-09-28 Trevor Saunders <tbsaunde+gcc@tbsaunde.org>
* doc/gimple.texi: Update references to gimple_statement_base.
insn_a = if_info->insn_a;
insn_b = if_info->insn_b;
+ machine_mode x_mode = GET_MODE (x);
+
+ if (!can_conditionally_move_p (x_mode))
+ return FALSE;
+
unsigned int then_cost;
unsigned int else_cost;
if (insn_a)
}
}
- if (!a_simple && then_bb && !b_simple && else_bb
+ if (then_bb && else_bb && !a_simple && !b_simple
&& (!bbs_ok_for_cmove_arith (then_bb, else_bb)
|| !bbs_ok_for_cmove_arith (else_bb, then_bb)))
return FALSE;
start_sequence ();
+ /* If one of the blocks is empty then the corresponding B or A value
+ came from the test block. The non-empty complex block that we will
+ emit might clobber the register used by B or A, so move it to a pseudo
+ first. */
+
+ if (b_simple || !else_bb)
+ {
+ rtx tmp_b = gen_reg_rtx (x_mode);
+ /* Perform the simplest kind of set. The register allocator
+ should remove it if it's not actually needed. If this set is not
+ a valid insn (can happen on the is_mem path) then end_ifcvt_sequence
+ will cancel the whole sequence. Don't try any of the fallback paths
+ from noce_emit_move_insn since we want this to be the simplest kind
+ of move. */
+ emit_insn (gen_rtx_SET (tmp_b, b));
+ b = tmp_b;
+ }
+
+ if (a_simple || !then_bb)
+ {
+ rtx tmp_a = gen_reg_rtx (x_mode);
+ emit_insn (gen_rtx_SET (tmp_a, a));
+ a = tmp_a;
+ }
+
orig_a = a;
orig_b = b;
+2015-09-28 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR rtl-optimization/67456
+ PR rtl-optimization/67464
+ PR rtl-optimization/67465
+ * gcc.dg/pr67465.c: New test.
+
2015-09-28 Tom de Vries <tom@codesourcery.com>
* gcc.dg/vect/pr62171.c: New test.
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-O3 -std=gnu99" } */
+
+int a, b, c, d, e, h;
+
+int
+fn1 (int p1)
+{
+ {
+ int g[2];
+ for (int i = 0; i < 1; i++)
+ g[i] = 0;
+ if (g[0] < c)
+ {
+ a = (unsigned) (1 ^ p1) % 2;
+ return 0;
+ }
+ }
+ return 0;
+}
+
+void
+fn2 ()
+{
+ for (h = 0; h < 1; h++)
+ {
+ for (int j = 0; j < 2; j++)
+ {
+ for (b = 1; b; b = 0)
+ a = 1;
+ for (; b < 1; b++)
+ ;
+ if (e)
+ continue;
+ a = 2;
+ }
+ fn1 (h);
+ short k = -16;
+ d = k > a;
+ }
+}
+
+int
+main ()
+{
+ fn2 ();
+
+ if (a != 2)
+ __builtin_abort ();
+
+ return 0;
+}
+