commit 90c12de20cdc8a8a5e81c25accc640ab517a3f7c
Author: Kyrylo Tkachov <kyrylo.tkachov@arm.com>
Date: Mon Sep 7 14:58:01 2015 +0100
[RTL-ifcvt] PR rtl-optimization/67465: Do not ifcvt complex blocks if the else block is empty
@@ -2043,6 +2043,11 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
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)
@@ -2079,13 +2084,32 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
}
}
- 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);
+ noce_emit_move_insn (tmp_b, b);
+ b = tmp_b;
+ }
+
+ if (a_simple || !then_bb)
+ {
+ rtx tmp_a = gen_reg_rtx (x_mode);
+ noce_emit_move_insn (tmp_a, a);
+ a = tmp_a;
+ }
+
orig_a = a;
orig_b = b;
new file mode 100644
@@ -0,0 +1,53 @@
+/* { 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;
+}
+