+ if (is_irg_state(irg, IR_GRAPH_STATE_KEEP_MUX))
+ return n;
+
+ if (is_Mux(t)) {
+ ir_node* block = get_nodes_block(n);
+ ir_node* c0 = sel;
+ ir_node* c1 = get_Mux_sel(t);
+ ir_node* t1 = get_Mux_true(t);
+ ir_node* f1 = get_Mux_false(t);
+ if (f == f1) {
+ /* Mux(cond0, Mux(cond1, x, y), y) -> typical if (cond0 && cond1) x else y */
+ ir_node* and_ = new_r_And(block, c0, c1, mode_b);
+ ir_node* new_mux = new_r_Mux(block, and_, f1, t1, mode);
+ n = new_mux;
+ sel = and_;
+ f = f1;
+ t = t1;
+ DBG_OPT_ALGSIM0(oldn, t, FS_OPT_MUX_COMBINE);
+ } else if (f == t1) {
+ /* Mux(cond0, Mux(cond1, x, y), x) */
+ ir_node* not_c1 = new_r_Not(block, c1, mode_b);
+ ir_node* and_ = new_r_And(block, c0, not_c1, mode_b);
+ ir_node* new_mux = new_r_Mux(block, and_, t1, f1, mode);
+ n = new_mux;
+ sel = and_;
+ f = t1;
+ t = f1;
+ DBG_OPT_ALGSIM0(oldn, t, FS_OPT_MUX_COMBINE);
+ }
+ } else if (is_Mux(f)) {
+ ir_node* block = get_nodes_block(n);
+ ir_node* c0 = sel;
+ ir_node* c1 = get_Mux_sel(f);
+ ir_node* t1 = get_Mux_true(f);
+ ir_node* f1 = get_Mux_false(f);
+ if (t == t1) {
+ /* Mux(cond0, x, Mux(cond1, x, y)) -> typical if (cond0 || cond1) x else y */
+ ir_node* or_ = new_r_Or(block, c0, c1, mode_b);
+ ir_node* new_mux = new_r_Mux(block, or_, f1, t1, mode);
+ n = new_mux;
+ sel = or_;
+ f = f1;
+ t = t1;
+ DBG_OPT_ALGSIM0(oldn, f, FS_OPT_MUX_COMBINE);
+ } else if (t == f1) {
+ /* Mux(cond0, x, Mux(cond1, y, x)) */
+ ir_node* not_c1 = new_r_Not(block, c1, mode_b);
+ ir_node* or_ = new_r_Or(block, c0, not_c1, mode_b);
+ ir_node* new_mux = new_r_Mux(block, or_, t1, f1, mode);
+ n = new_mux;
+ sel = or_;
+ f = t1;
+ t = f1;
+ DBG_OPT_ALGSIM0(oldn, f, FS_OPT_MUX_COMBINE);
+ }
+ }
+