assert(is_op_commutative(get_irn_op(binop)));
switch (class_a + 2*class_b) {
- case REAL_CONSTANT + 2*NO_CONSTANT:
case REAL_CONSTANT + 2*REAL_CONSTANT:
+ /* if both are constants, one might be a
+ * pointer constant like NULL, return the other
+ */
+ if (mode_is_reference(get_irn_mode(op_a))) {
+ *a = op_a;
+ *c = op_b;
+ }
+ else {
+ *a = op_b;
+ *c = op_a;
+ }
+ break;
+ case REAL_CONSTANT + 2*NO_CONSTANT:
case REAL_CONSTANT + 2*REGION_CONST:
case REGION_CONST + 2*NO_CONSTANT:
*a = op_b;
static int reassoc_Sub(ir_node **in)
{
ir_node *n = *in;
- ir_node *block = get_nodes_block(n);
ir_node *right = get_Sub_right(n);
+ ir_mode *rmode = get_irn_mode(right);
+ ir_node *block;
- /* FIXME: Do not apply this rule for unsigned Sub's because our code
- * generation is currently buggy :-)
- */
- if (! mode_is_signed(get_irn_mode(n)))
- return 0;
+ /* cannot handle SubIs(P, P) */
+ if (mode_is_reference(rmode))
+ return 0;
+
+ block = get_nodes_block(n);
/* handles rule R6:
* convert x - c => (-c) + x
* */
if (get_const_class(right, block) == REAL_CONSTANT) {
ir_node *left = get_Sub_left(n);
- ir_node *block = get_nodes_block(n);
- ir_mode *mode = get_irn_mode(n);
- dbg_info *dbi = get_irn_dbg_info(n);
+ ir_mode *mode;
+ dbg_info *dbi;
ir_node *irn, *c;
switch (get_const_class(left, block)) {
/* already constant, nothing to do */
return 0;
}
+ mode = get_irn_mode(n);
+ dbi = get_irn_dbg_info(n);
- c = new_r_Const(current_ir_graph, block, mode, get_mode_null(mode));
- irn = new_rd_Sub(dbi, current_ir_graph, block, c, right, mode);
+ /* Beware of SubP(P, Is) */
+ c = new_r_Const(current_ir_graph, block, rmode, get_mode_null(rmode));
+ irn = new_rd_Sub(dbi, current_ir_graph, block, c, right, rmode);
irn = new_rd_Add(dbi, current_ir_graph, block, left, irn, get_irn_mode(n));
res = 0;
- /* reassociation works only for integer or reference modes */
- if (op->ops.reassociate && (mode_is_int(mode) || mode_is_reference(mode))) {
+ /* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
+ if (mode_is_float(mode) && get_irg_fp_model(current_ir_graph) & fp_strict_algebraic)
+ break;
+
+ if (op->ops.reassociate) {
res = op->ops.reassociate(&n);
wenv->changes |= res;