remove the concept of a strictconv
authorMatthias Braun <matthias.braun@kit.edu>
Tue, 21 Aug 2012 13:49:02 +0000 (15:49 +0200)
committerMatthias Braun <matthias.braun@kit.edu>
Tue, 21 Aug 2012 14:51:27 +0000 (16:51 +0200)
This means floatingpoint calculation in a firm graph must be performed
in the mode specified (and may not be performed in a wider mode as
before).

13 files changed:
include/libfirm/ircons.h
include/libfirm/irnode.h
ir/be/ia32/ia32_transform.c
ir/ir/ircons.c
ir/ir/irdump.c
ir/ir/irnode.c
ir/ir/irnode_t.h
ir/ir/irop.c
ir/ir/iropt.c
ir/ir/irtypes.h
ir/lower/lower_intrinsics.c
ir/opt/opt_blocks.c
scripts/ir_spec.py

index 209411f..c825b38 100644 (file)
@@ -557,45 +557,6 @@ FIRM_API ir_node *new_SymConst(ir_mode *mode, union symconst_symbol value,
 
 /** @} */
 
-/** @addtogroup Conv
- * @{
- */
-
-/** Constructor for a strictConv node.
- *
- * @param db    A pointer for debug information.
- * @param block The IR block the node belongs to.
- * @param op    The operand.
- * @param mode  The mode of this the operand muss be converted .
- */
-FIRM_API ir_node *new_rd_strictConv(dbg_info *db, ir_node *block,
-                                    ir_node *op, ir_mode *mode);
-
-/** Constructor for a strictConv node.
- *
- * @param block The IR block the node belongs to.
- * @param op    The operand.
- * @param mode  The mode of this the operand muss be converted .
- */
-FIRM_API ir_node *new_r_strictConv(ir_node *block, ir_node *op, ir_mode *mode);
-
-/** Constructor for a strict Conv node.
- *
- * @param db    A pointer for debug information.
- * @param op    The operand.
- * @param mode  The mode of this the operand muss be converted .
- */
-FIRM_API ir_node *new_d_strictConv(dbg_info *db, ir_node *op, ir_mode *mode);
-
-/** Constructor for a strict Conv node.
- *
- * @param op    The operand.
- * @param mode  The mode of this the operand muss be converted .
- */
-FIRM_API ir_node *new_strictConv(ir_node *op, ir_mode *mode);
-
-/** @} */
-
 /** @addtogroup Sel
  * @{
  */
index 9c6d33a..6a2ca9a 100644 (file)
@@ -383,12 +383,6 @@ FIRM_API int is_Const_all_one(const ir_node *node);
 
 /** @} */
 
-/**
- * @ingroup Conv
- * Returns true if a node is a Conv node with strict attribute set.
- */
-FIRM_API int is_strictConv(const ir_node *node);
-
 /**
  * @addtogroup SymConst
  * @{
index bb1da2d..8f1017c 100644 (file)
@@ -1017,6 +1017,13 @@ static ir_node *skip_float_upconv(ir_node *node)
        return node;
 }
 
+static void check_x87_floatmode(ir_mode *mode)
+{
+       if (mode != ia32_mode_E) {
+               panic("ia32: x87 only supports x86 extended float mode");
+       }
+}
+
 /**
  * Construct a standard binary operation, set AM and immediate if required.
  *
@@ -1038,6 +1045,9 @@ static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
        /* All operations are considered commutative, because there are reverse
         * variants */
        match_flags_t        flags = match_commutative | match_am;
+       ir_mode             *mode
+               = is_Div(node) ? get_Div_resmode(node) : get_irn_mode(node);
+       check_x87_floatmode(mode);
 
        op1 = skip_float_upconv(op1);
        op2 = skip_float_upconv(op2);
@@ -1907,6 +1917,7 @@ static ir_node *gen_Minus(ir_node *node)
                        set_ia32_op_type(new_node, ia32_AddrModeS);
                        set_ia32_ls_mode(new_node, mode);
                } else {
+                       check_x87_floatmode(mode);
                        new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
                }
        } else {
@@ -1963,6 +1974,7 @@ static ir_node *create_float_abs(dbg_info *dbgi, ir_node *block, ir_node *op,
                /* TODO, implement -Abs case */
                assert(!negate);
        } else {
+               check_x87_floatmode(mode);
                new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
                SET_IA32_ORIG_NODE(new_node, node);
                if (negate) {
@@ -2693,8 +2705,7 @@ static ir_node *gen_general_Store(ir_node *node)
        addr.mem = be_transform_node(mem);
 
        if (mode_is_float(mode)) {
-               /* Convs (and strict-Convs) before stores are unnecessary if the mode
-                  is the same. */
+               /* Convs before stores are unnecessary if the mode is the same. */
                while (is_Conv(val) && mode == get_irn_mode(val)) {
                        ir_node *op = get_Conv_op(val);
                        if (!mode_is_float(get_irn_mode(op)))
@@ -2713,8 +2724,7 @@ static ir_node *gen_general_Store(ir_node *node)
                val = get_Conv_op(val);
 
                /* TODO: is this optimisation still necessary at all (middleend)? */
-               /* We can skip ALL float->float up-Convs (and strict-up-Convs) before
-                * stores. */
+               /* We can skip ALL float->float up-Convs before stores. */
                while (is_Conv(val)) {
                        ir_node *op = get_Conv_op(val);
                        if (!mode_is_float(get_irn_mode(op)))
@@ -2855,8 +2865,10 @@ static ir_node *create_Fucom(ir_node *node)
        ir_node  *left      = get_Cmp_left(node);
        ir_node  *new_left  = be_transform_node(left);
        ir_node  *right     = get_Cmp_right(node);
+       ir_mode  *cmp_mode  = get_irn_mode(left);
        ir_node  *new_right;
        ir_node  *new_node;
+       check_x87_floatmode(cmp_mode);
 
        if (ia32_cg_config.use_fucomi) {
                new_right = be_transform_node(right);
@@ -3654,9 +3666,9 @@ static ir_node *gen_x87_fp_to_gp(ir_node *node)
 }
 
 /**
- * Creates a x87 strict Conv by placing a Store and a Load
+ * Creates a x87 Conv by placing a Store and a Load
  */
-static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
+static ir_node *gen_x87_conv(ir_mode *tgt_mode, ir_node *node)
 {
        ir_node  *block    = get_nodes_block(node);
        ir_graph *irg      = get_Block_irg(block);
@@ -3869,17 +3881,10 @@ static ir_node *gen_Conv(ir_node *node)
        }
 
        if (src_mode == tgt_mode) {
-               if (get_Conv_strict(node)) {
-                       if (ia32_cg_config.use_sse2) {
-                               /* when we are in SSE mode, we can kill all strict no-op conversion */
-                               return be_transform_node(op);
-                       }
-               } else {
-                       /* this should be optimized already, but who knows... */
-                       DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node);)
+               /* this should be optimized already, but who knows... */
+               DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node);)
                        DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
-                       return be_transform_node(op);
-               }
+               return be_transform_node(op);
        }
 
        if (mode_is_float(src_mode)) {
@@ -3893,21 +3898,14 @@ static ir_node *gen_Conv(ir_node *node)
                                                             nomem, new_op);
                                set_ia32_ls_mode(res, tgt_mode);
                        } else {
-                               if (get_Conv_strict(node)) {
-                                       /* if fp_no_float_fold is not set then we assume that we
-                                        * don't have any float operations in a non
-                                        * mode_float_arithmetic mode and can skip strict upconvs */
-                                       if (src_bits < tgt_bits) {
-                                               DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
-                                               return new_op;
-                                       } else {
-                                               res = gen_x87_strict_conv(tgt_mode, new_op);
-                                               SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
-                                               return res;
-                                       }
+                               if (src_bits < tgt_bits) {
+                                       DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
+                                       return new_op;
+                               } else {
+                                       res = gen_x87_conv(tgt_mode, new_op);
+                                       SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
+                                       return res;
                                }
-                               DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
-                               return new_op;
                        }
                } else {
                        /* ... to int */
@@ -3935,10 +3933,10 @@ static ir_node *gen_Conv(ir_node *node)
                                unsigned float_mantissa = get_mode_mantissa_size(tgt_mode);
                                res = gen_x87_gp_to_fp(node, src_mode);
 
-                               /* we need a strict-Conv, if the int mode has more bits than the
+                               /* we need a float-conv, if the int mode has more bits than the
                                 * float mantissa */
                                if (float_mantissa < int_mantissa) {
-                                       res = gen_x87_strict_conv(tgt_mode, res);
+                                       res = gen_x87_conv(tgt_mode, res);
                                        SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
                                }
                                return res;
index f3b3889..cd3864f 100644 (file)
@@ -404,39 +404,6 @@ ir_node *new_d_ASM(dbg_info *db, ir_node *mem, int arity, ir_node *in[],
                          inputs, n_outs, outputs, n_clobber, clobber, text);
 }
 
-ir_node *new_rd_strictConv(dbg_info *dbgi, ir_node *block, ir_node * irn_op, ir_mode * mode)
-{
-       ir_node *res;
-       ir_graph *irg = get_Block_irg(block);
-
-       ir_node *in[1];
-       in[0] = irn_op;
-
-       res = new_ir_node(dbgi, irg, block, op_Conv, mode, 1, in);
-       res->attr.conv.strict = 1;
-       irn_verify_irg(res, irg);
-       res = optimize_node(res);
-       return res;
-}
-
-ir_node *new_r_strictConv(ir_node *block, ir_node * irn_op, ir_mode * mode)
-{
-       return new_rd_strictConv(NULL, block, irn_op, mode);
-}
-
-ir_node *new_d_strictConv(dbg_info *dbgi, ir_node * irn_op, ir_mode * mode)
-{
-       ir_node *res;
-       assert(get_irg_phase_state(current_ir_graph) == phase_building);
-       res = new_rd_strictConv(dbgi, current_ir_graph->current_block, irn_op, mode);
-       return res;
-}
-
-ir_node *new_strictConv(ir_node * irn_op, ir_mode * mode)
-{
-       return new_d_strictConv(NULL, irn_op, mode);
-}
-
 ir_node *new_rd_DivRL(dbg_info *dbgi, ir_node *block, ir_node * irn_mem, ir_node * irn_left, ir_node * irn_right, ir_mode* resmode, op_pin_state pin_state)
 {
        ir_node *res;
index a2cde19..222bd35 100644 (file)
@@ -674,11 +674,6 @@ void dump_node_opcode(FILE *F, const ir_node *n)
                fprintf(F, "%s%s", get_irn_opname(n),
                        (flags & ir_dump_flag_show_marks) ? (get_Block_mark(n) ? "*" : "") : "");
                break;
-       case iro_Conv:
-               if (get_Conv_strict(n))
-                       fprintf(F, "strict");
-               fprintf(F, "%s", get_irn_opname(n));
-               break;
        case iro_Div:
                fprintf(F, "%s", get_irn_opname(n));
                if (get_Div_no_remainder(n))
index b476e9c..e4bd620 100644 (file)
@@ -1397,11 +1397,6 @@ ir_node *skip_Id(ir_node *node)
        }
 }
 
-int (is_strictConv)(const ir_node *node)
-{
-       return is_strictConv_(node);
-}
-
 int (is_SymConst_addr_ent)(const ir_node *node)
 {
        return is_SymConst_addr_ent_(node);
index c32ad54..afc4dab 100644 (file)
@@ -311,11 +311,6 @@ static inline int is_binop_(const ir_node *node)
        return (node->op->opar == oparity_binary);
 }
 
-static inline int is_strictConv_(const ir_node *node)
-{
-       return is_Conv_(node) && get_Conv_strict(node);
-}
-
 static inline int is_SymConst_addr_ent_(const ir_node *node)
 {
        return is_SymConst(node) && get_SymConst_kind(node) == symconst_addr_ent;
@@ -592,7 +587,6 @@ void init_irnode(void);
 #define is_binop(node)                        is_binop_(node)
 #define is_Proj(node)                         is_Proj_(node)
 #define is_Phi(node)                          is_Phi_(node)
-#define is_strictConv(node)                   is_strictConv_(node)
 #define is_SymConst_addr_ent(node)            is_SymConst_addr_ent_(node)
 #define get_Block_n_cfgpreds(node)            get_Block_n_cfgpreds_(node)
 #define get_Block_cfgpred(node, pos)          get_Block_cfgpred_(node, pos)
index 7e799fc..ba3e476 100644 (file)
@@ -341,12 +341,6 @@ static int node_cmp_attr_Phi(const ir_node *a, const ir_node *b)
        return 0;
 }
 
-/** Compares the attributes of two Conv nodes. */
-static int node_cmp_attr_Conv(const ir_node *a, const ir_node *b)
-{
-       return get_Conv_strict(a) != get_Conv_strict(b);
-}
-
 /** Compares the attributes of two Cast nodes. */
 static int node_cmp_attr_Cast(const ir_node *a, const ir_node *b)
 {
@@ -610,7 +604,6 @@ void firm_init_op(void)
        register_node_cmp_func(op_Cmp,      node_cmp_attr_Cmp);
        register_node_cmp_func(op_Confirm,  node_cmp_attr_Confirm);
        register_node_cmp_func(op_Const,    node_cmp_attr_Const);
-       register_node_cmp_func(op_Conv,     node_cmp_attr_Conv);
        register_node_cmp_func(op_CopyB,    node_cmp_attr_CopyB);
        register_node_cmp_func(op_Div,      node_cmp_attr_Div);
        register_node_cmp_func(op_Dummy,    node_cmp_attr_Dummy);
index 5ff0f84..0667f74 100644 (file)
@@ -1101,99 +1101,24 @@ static ir_node *equivalent_node_Conv(ir_node *n)
        ir_mode *n_mode = get_irn_mode(n);
        ir_mode *a_mode = get_irn_mode(a);
 
-restart:
        if (n_mode == a_mode) { /* No Conv necessary */
-               if (get_Conv_strict(n)) {
-                       ir_node *p = a;
-
-                       /* neither Minus nor Confirm change the precision,
-                          so we can "look-through" */
-                       for (;;) {
-                               if (is_Minus(p)) {
-                                       p = get_Minus_op(p);
-                               } else if (is_Confirm(p)) {
-                                       p = get_Confirm_value(p);
-                               } else {
-                                       /* stop here */
-                                       break;
-                               }
-                       }
-                       if (is_Conv(p) && get_Conv_strict(p)) {
-                               /* we known already, that a_mode == n_mode, and neither
-                                  Minus change the mode, so the second Conv
-                                  can be kicked */
-                               assert(get_irn_mode(p) == n_mode);
-                               n = a;
-                               DBG_OPT_ALGSIM0(oldn, n, FS_OPT_CONV);
-                               return n;
-                       }
-                       if (is_Proj(p)) {
-                               ir_node *pred = get_Proj_pred(p);
-                               if (is_Load(pred)) {
-                                       /* Loads always return with the exact precision of n_mode */
-                                       assert(get_Load_mode(pred) == n_mode);
-                                       n = a;
-                                       DBG_OPT_ALGSIM0(oldn, n, FS_OPT_CONV);
-                                       return n;
-                               }
-                               if (is_Proj(pred) && get_Proj_proj(pred) == pn_Start_T_args) {
-                                       pred = get_Proj_pred(pred);
-                                       if (is_Start(pred)) {
-                                               /* Arguments always return with the exact precision,
-                                                  as strictConv's are place before Call -- if the
-                                                  caller was compiled with the same setting.
-                                                  Otherwise, the semantics is probably still right. */
-                                               assert(get_irn_mode(p) == n_mode);
-                                               n = a;
-                                               DBG_OPT_ALGSIM0(oldn, n, FS_OPT_CONV);
-                                               return n;
-                                       }
-                               }
-                       }
-                       if (is_Conv(a)) {
-                               /* special case: the immediate predecessor is also a Conv */
-                               if (! get_Conv_strict(a)) {
-                                       /* first one is not strict, kick it */
-                                       a = get_Conv_op(a);
-                                       a_mode = get_irn_mode(a);
-                                       set_Conv_op(n, a);
-                                       goto restart;
-                               }
-                               /* else both are strict conv, second is superfluous */
-                               n = a;
-                               DBG_OPT_ALGSIM0(oldn, n, FS_OPT_CONV);
-                               return n;
-                       }
-               } else {
-                       n = a;
-                       DBG_OPT_ALGSIM0(oldn, n, FS_OPT_CONV);
-                       return n;
-               }
+               n = a;
+               DBG_OPT_ALGSIM0(oldn, n, FS_OPT_CONV);
+               return n;
        } else if (is_Conv(a)) { /* Conv(Conv(b)) */
                ir_node *b      = get_Conv_op(a);
                ir_mode *b_mode = get_irn_mode(b);
 
-               if (get_Conv_strict(n) && get_Conv_strict(a)) {
-                       /* both are strict conv */
-                       if (smaller_mode(a_mode, n_mode)) {
-                               /* both are strict, but the first is smaller, so
-                                  the second cannot remove more precision, remove the
-                                  strict bit */
-                               set_Conv_strict(n, 0);
-                       }
-               }
                if (n_mode == b_mode) {
-                       if (! get_Conv_strict(n) && ! get_Conv_strict(a)) {
-                               if (n_mode == mode_b) {
-                                       n = b; /* Convb(Conv*(xxxb(...))) == xxxb(...) */
+                       if (n_mode == mode_b) {
+                               n = b; /* Convb(Conv*(xxxb(...))) == xxxb(...) */
+                               DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_CONV);
+                               return n;
+                       } else if (get_mode_arithmetic(n_mode) == get_mode_arithmetic(a_mode)) {
+                               if (values_in_mode(b_mode, a_mode)) {
+                                       n = b;        /* ConvS(ConvL(xxxS(...))) == xxxS(...) */
                                        DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_CONV);
                                        return n;
-                               } else if (get_mode_arithmetic(n_mode) == get_mode_arithmetic(a_mode)) {
-                                       if (values_in_mode(b_mode, a_mode)) {
-                                               n = b;        /* ConvS(ConvL(xxxS(...))) == xxxS(...) */
-                                               DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_CONV);
-                                               return n;
-                                       }
                                }
                        }
                        if (mode_is_int(n_mode) && get_mode_arithmetic(a_mode) == irma_ieee754) {
@@ -1207,14 +1132,10 @@ restart:
                                        return n;
                                }
                        }
-                       if (is_Conv(b)) {
-                               if (smaller_mode(b_mode, a_mode)) {
-                                       if (get_Conv_strict(n))
-                                               set_Conv_strict(b, 1);
-                                       n = b; /* ConvA(ConvB(ConvA(...))) == ConvA(...) */
-                                       DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_CONV);
-                                       return n;
-                               }
+                       if (is_Conv(b) && smaller_mode(b_mode, a_mode)) {
+                               n = b; /* ConvA(ConvB(ConvA(...))) == ConvA(...) */
+                               DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_CONV);
+                               return n;
                        }
                }
        }
@@ -4213,53 +4134,56 @@ static ir_node *transform_node_Cmp(ir_node *n)
        }
 
        /* Remove unnecessary conversions */
-       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);
-
-               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);
-
-                       if (mode_left == mode_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;
-                               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);
-                               changed = true;
-                               DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV);
+       if (!mode_is_float(mode)
+           || be_get_backend_param()->mode_float_arithmetic == NULL) {
+               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);
+
+                       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);
+
+                               if (mode_left == mode_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;
+                                       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);
+                                       changed = true;
+                                       DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV);
+                               }
+                               mode = get_irn_mode(left);
                        }
-                       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);
-                               mode    = get_irn_mode(left);
-                               changed = true;
-                               DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV);
+               }
+               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);
+                                       mode    = get_irn_mode(left);
+                                       changed = true;
+                                       DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV);
+                               }
                        }
                }
        }
index e69392c..eeff0db 100644 (file)
@@ -329,11 +329,6 @@ typedef struct bound_attr {
        except_attr exc;              /**< The exception attribute. MUST be the first one. */
 } bound_attr;
 
-/** Conv attribute. */
-typedef struct conv_attr {
-       char           strict;        /**< If set, this is a strict Conv that cannot be removed. */
-} conv_attr;
-
 /** Div attribute. */
 typedef struct div_attr {
        except_attr    exc;           /**< The exception attribute. MUST be the first one. */
@@ -392,7 +387,6 @@ typedef union ir_attr {
        except_attr    except;        /**< For Phi node construction in case of exceptions */
        copyb_attr     copyb;         /**< For CopyB operation */
        bound_attr     bound;         /**< For Bound operation */
-       conv_attr      conv;          /**< For Conv operation */
        div_attr       div;           /**< For Div operation */
        mod_attr       mod;           /**< For Mod operation */
        asm_attr       assem;         /**< For ASM operation. */
index f11f39b..2e33ce8 100644 (file)
@@ -391,9 +391,16 @@ int i_mapper_pow(ir_node *call, void *ctx)
        dbg = get_irn_dbg_info(call);
 
        if (irn == NULL) {
-               ir_mode *mode = get_irn_mode(left);
+               ir_mode *result_mode = get_irn_mode(left);
                ir_node *div;
 
+               ir_mode *mode             = result_mode;
+               ir_mode *float_arithmetic = be_get_backend_param()->mode_float_arithmetic;
+               if (float_arithmetic != NULL) {
+                       left = new_r_Conv(block, left, float_arithmetic);
+                       mode = float_arithmetic;
+               }
+
                irn  = new_r_Const(irg, get_mode_one(mode));
                div  = new_rd_Div(dbg, block, mem, irn, left, mode, op_pin_state_pinned);
                mem  = new_r_Proj(div, mode_M, pn_Div_M);
@@ -403,6 +410,9 @@ int i_mapper_pow(ir_node *call, void *ctx)
                        exc_jmp = new_r_Proj(div, mode_X, pn_Div_X_except);
                        ir_set_throws_exception(div, true);
                }
+               if (result_mode != mode) {
+                       irn = new_r_Conv(block, irn, result_mode);
+               }
        }
        DBG_OPT_ALGSIM0(call, irn, FS_OPT_RTS_POW);
        replace_call(irn, call, mem, reg_jmp, exc_jmp);
@@ -487,7 +497,7 @@ static int i_mapper_symmetric_zero_to_one(ir_node *call, void *ctx, int reason)
        ir_node *val     = get_Call_param(call, 0);
        (void) ctx;
 
-       if (is_strictConv(val)) {
+       if (is_Conv(val)) {
                ir_node *op = get_Conv_op(val);
                if (is_Minus(op)) {
                        /* f(-x) = f(x) with strictConv */
@@ -497,10 +507,6 @@ static int i_mapper_symmetric_zero_to_one(ir_node *call, void *ctx, int reason)
 
                        op = get_Minus_op(op);
                        val = new_rd_Conv(dbg, block, op, mode);
-                       if (is_Conv(val)) {
-                               /* still a Conv ? */
-                               set_Conv_strict(val, 1);
-                       }
                        DBG_OPT_ALGSIM2(call, op, call, FS_OPT_RTS_SYMMETRIC);
                        set_Call_param(call, 0, val);
                        changed = 1;
index 98970f2..a7f652f 100644 (file)
@@ -421,9 +421,6 @@ static opcode_key_t *opcode(const node_t *node, environment_t *env)
        case iro_Const:
                key.u.tv  = get_Const_tarval(irn);
                break;
-       case iro_Conv:
-               key.u.intVal = get_Conv_strict(irn);
-               break;
        case iro_Load:
                key.mode = get_Load_mode(irn);
                break;
index 4d35001..d4b18ce 100755 (executable)
@@ -465,15 +465,6 @@ class Const:
 class Conv(Unop):
        """Converts values between modes"""
        flags = []
-       attrs = [
-               dict(
-                       name    = "strict",
-                       type    = "int",
-                       init    = "0",
-                       comment = "force floating point to restrict precision even if backend computes in higher precision (deprecated)",
-               )
-       ]
-       attr_struct = "conv_attr"
 
 @op
 class CopyB: