Commit bc96c024 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

opt: Add local optimization `a * b [-1 <= b <= 0] -> -(a & b)`.

parent 6b988438
......@@ -45,6 +45,7 @@ libFirm 1.22.1 (2016-01-07)
* amd64: Improve block schedule by removing empty basic blocks
* amd64: Use cltd/cqto for sign extension before a division
* amd64: Use store with immediate for call arguments
* opt: Add local optimization `a * b [-1 <= b <= 0] -> -(a & b)`
* Bugfixes
libFirm 1.22.0 (2015-12-31)
......
......@@ -3658,6 +3658,19 @@ static ir_node *can_negate_cheaply(dbg_info *const dbgi, ir_node *const node)
return NULL;
}
static bool is_zero_or_all_one(ir_node const *const n)
{
if (is_Shrs(n)) {
ir_node *const r = get_Shrs_right(n);
if (is_Const(r)) {
long const v = get_Const_long(r);
if (v == (long)get_mode_size_bits(get_irn_mode(n)) - 1)
return true;
}
}
return false;
}
static ir_node *transform_node_shl_shr(ir_node *n);
static ir_node *transform_node_Mul(ir_node *n)
......@@ -3732,6 +3745,14 @@ static ir_node *transform_node_Mul(ir_node *n)
ir_node *minus = new_rd_Minus(dbgi, block, bit);
return new_rd_And(dbgi, block, other, minus);
}
if (is_zero_or_all_one(a) || is_zero_or_all_one(b)) {
/* a * b [-1 <= b <= 0] -> -(a & b) */
dbg_info *const dbgi = get_irn_dbg_info(n);
ir_node *const block = get_nodes_block(n);
ir_node *const and = new_rd_And(dbgi, block, a, b);
return new_rd_Minus(dbgi, block, and);
}
}
/* distribute minus:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment