From 1dd5d4807ad3334b710ef22b53bba1cc4268a45d Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Sat, 28 May 2011 16:59:47 +0200 Subject: [PATCH] implement Cmp(Conv(x),Const) => Cmp(x,Const) --- ir/ir/iropt.c | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index 79d096067..541e40694 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -3632,30 +3632,50 @@ static ir_node *transform_node_Cmp(ir_node *n) } /* Remove unnecessary conversions */ - /* TODO handle conv+constant */ if (is_Conv(left) && is_Conv(right)) { - ir_node *op_left = get_Conv_op(left); - ir_node *op_right = get_Conv_op(right); - ir_mode *mode_left = get_irn_mode(op_left); - ir_mode *mode_right = get_irn_mode(op_right); + ir_node *op_left = get_Conv_op(left); + ir_node *op_right = get_Conv_op(right); + ir_mode *mode_left = get_irn_mode(op_left); + ir_mode *mode_right = get_irn_mode(op_right); if (smaller_mode(mode_left, mode) && smaller_mode(mode_right, mode) && mode_left != mode_b && mode_right != mode_b) { - ir_node *block = get_nodes_block(n); + ir_node *block = get_nodes_block(n); if (mode_left == mode_right) { - left = op_left; - right = op_right; + left = op_left; + right = op_right; changed = true; DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV_CONV); } else if (smaller_mode(mode_left, mode_right)) { - left = new_r_Conv(block, op_left, mode_right); - right = op_right; + left = new_r_Conv(block, op_left, mode_right); + right = op_right; changed = true; DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV); } else if (smaller_mode(mode_right, mode_left)) { - left = op_left; - right = new_r_Conv(block, op_right, mode_left); + left = op_left; + right = new_r_Conv(block, op_right, mode_left); + changed = true; + DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV); + } + mode = get_irn_mode(left); + } + } + if (is_Conv(left) && is_Const(right)) { + ir_node *op_left = get_Conv_op(left); + ir_mode *mode_left = get_irn_mode(op_left); + if (smaller_mode(mode_left, mode) && mode_left != mode_b) { + ir_tarval *tv = get_Const_tarval(right); + tarval_int_overflow_mode_t last_mode + = tarval_get_integer_overflow_mode(); + ir_tarval *new_tv; + tarval_set_integer_overflow_mode(TV_OVERFLOW_BAD); + new_tv = tarval_convert_to(tv, mode_left); + tarval_set_integer_overflow_mode(last_mode); + if (new_tv != tarval_bad) { + ir_graph *irg = get_irn_irg(n); + left = op_left; + right = new_r_Const(irg, new_tv); changed = true; DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV); } -- 2.20.1