(pnc_hi == pn_Cmp_Gt || pnc_lo == pn_Cmp_Ge) &&
get_mode_arithmetic(mode) == irma_twos_complement) {
/* works for two-complements only */
- /* x <|\= lo || x >|>= hi ==> (x - lo) >u|>=u (hi-lo) */
- if (pnc_lo == pn_Cmp_Lt) {
- /* must convert to <= */
+ /* x <|<= lo || x >|>= hi ==> (x - lo) >u|>=u (hi-lo) */
+ if (pnc_lo == pn_Cmp_Le) {
+ /* must convert to < */
ir_mode *mode = get_tarval_mode(tv_lo);
- tarval *n = tarval_sub(tv_lo, get_mode_one(mode), NULL);
- if (n != tarval_bad && tarval_cmp(n, tv_lo) == pn_Cmp_Lt) {
+ tarval *n = tarval_add(tv_lo, get_mode_one(mode));
+ if (n != tarval_bad && tarval_cmp(n, tv_lo) == pn_Cmp_Gt) {
/* no overflow */
tv_lo = n;
- pnc_lo = pn_Cmp_Le;
+ pnc_lo = pn_Cmp_Lt;
}
}
- if (pnc_lo == pn_Cmp_Le) {
+ if (pnc_lo == pn_Cmp_Lt) {
/* all fine */
ir_node *const block = get_nodes_block(cmp_hi);
ir_node * x = get_Cmp_left(cmp_hi);
upper_block = get_nodes_block(upper_cf);
if (upper_block != lower_pred)
continue;
+ if (!block_dominates(upper_block, block))
+ continue;
assert(is_Proj(upper_cf));
upper_cond = get_Proj_pred(upper_cf);
env->changed = 1;
+ DB((dbg, LEVEL_1, "boolopt: %+F: fusing (ub %+F lb %+F)\n",
+ current_ir_graph, upper_block, lower_block));
+
/* move all expressions on the path to lower/upper block */
move_nodes_to_block(get_Block_cfgpred(block, up_idx), upper_block);
move_nodes_to_block(get_Block_cfgpred(block, low_idx), lower_block);
}
set_Cond_selector(cond, replacement);
- DB((dbg, LEVEL_1, "%+F: replaced (ub %+F)\n", current_ir_graph, upper_block));
goto restart;
}
}