8 typedef struct cond_pair {
19 static int find_cond_pair(ir_node *const l, ir_node *const r, cond_pair *const res)
21 if (is_Proj(l) && is_Proj(r)) {
22 ir_node *const lo = get_Proj_pred(l);
23 ir_node *const ro = get_Proj_pred(r);
25 if (is_Cmp(lo) && is_Cmp(ro)) {
26 ir_node *const lol = get_Cmp_left(lo);
27 ir_node *const lor = get_Cmp_right(lo);
28 ir_node *const rol = get_Cmp_left(ro);
29 ir_node *const ror = get_Cmp_right(ro);
32 /* The constants shall be unequal. Local optimisations handle the equal
34 if (lol == rol && mode_is_int(get_irn_mode(lol)) && lor != ror && is_Const(lor) && is_Const(ror)) {
35 tarval *const tv_l = get_Const_tarval(lor);
36 tarval *const tv_r = get_Const_tarval(ror);
37 pn_Cmp const pnc_l = get_Proj_proj(l);
38 pn_Cmp const pnc_r = get_Proj_proj(r);
39 pn_Cmp const rel = tarval_cmp(tv_l, tv_r);
41 assert(rel != pn_Cmp_Eq);
43 if (rel == pn_Cmp_Lt) {
53 assert(rel == pn_Cmp_Gt);
70 static void bool_and(ir_node *const n)
72 ir_node *const l = get_And_left(n);
73 ir_node *const r = get_And_right(n);
75 if (find_cond_pair(l, r, &res)) {
76 ir_node *const cmp_lo = res.cmp_lo;
77 ir_node *const cmp_hi = res.cmp_hi;
78 pn_Cmp const pnc_lo = res.pnc_lo;
79 pn_Cmp const pnc_hi = res.pnc_hi;
80 ir_node *const proj_lo = res.proj_lo;
81 ir_node *const proj_hi = res.proj_hi;
82 tarval *const tv_lo = res.tv_lo;
83 tarval *const tv_hi = res.tv_hi;
85 if ((pnc_lo == pn_Cmp_Lt || pnc_lo == pn_Cmp_Le || pnc_lo == pn_Cmp_Eq) &&
86 (pnc_hi == pn_Cmp_Eq || pnc_hi == pn_Cmp_Ge || pnc_hi == pn_Cmp_Gt)) {
87 /* x <|<=|== lo | x ==|>=|> hi -> false */
88 ir_node *const t = new_Const(mode_b, tarval_b_false);
90 } else if ((pnc_lo == pn_Cmp_Lt || pnc_lo == pn_Cmp_Le || pnc_lo == pn_Cmp_Eq) &&
91 (pnc_hi == pn_Cmp_Lt || pnc_hi == pn_Cmp_Le || pnc_hi == pn_Cmp_Ne)) {
92 /* x <|<=|== lo && x <|<=|!= hi -> x <|<=|== lo */
94 } else if ((pnc_lo == pn_Cmp_Ge || pnc_lo == pn_Cmp_Gt || pnc_lo == pn_Cmp_Ne) &&
95 (pnc_hi == pn_Cmp_Eq || pnc_hi == pn_Cmp_Ge || pnc_hi == pn_Cmp_Gt)) {
96 /* x >=|>|!= lo || x ==|>=|> hi -> x ==|>=|> hi */
98 } else if (tarval_is_one(tarval_sub(tv_hi, tv_lo))) { /* lo + 1 == hi */
99 if (pnc_lo == pn_Cmp_Ge && pnc_hi == pn_Cmp_Lt) {
100 /* x >= c || x < c + 1 -> x == c */
101 ir_graph *const irg = current_ir_graph;
102 ir_node *const block = get_nodes_block(cmp_lo);
103 ir_node *const p = new_r_Proj(irg, block, cmp_lo, mode_b, pn_Cmp_Eq);
105 } else if (pnc_lo == pn_Cmp_Gt) {
106 if (pnc_hi == pn_Cmp_Ne) {
107 /* x > c || x != c + 1 -> x > c + 1 */
108 ir_graph *const irg = current_ir_graph;
109 ir_node *const block = get_nodes_block(cmp_hi);
110 ir_node *const p = new_r_Proj(irg, block, cmp_hi, mode_b, pn_Cmp_Gt);
112 } else if (pnc_hi == pn_Cmp_Lt) {
113 /* x > c || x < c + 1 -> false */
114 ir_node *const t = new_Const(mode_b, tarval_b_false);
116 } else if (pnc_hi == pn_Cmp_Le) {
117 /* x > c || x <= c + 1 -> x != c + 1 */
118 ir_graph *const irg = current_ir_graph;
119 ir_node *const block = get_nodes_block(cmp_hi);
120 ir_node *const p = new_r_Proj(irg, block, cmp_hi, mode_b, pn_Cmp_Eq);
123 } else if (pnc_lo == pn_Cmp_Ne && pnc_hi == pn_Cmp_Lt) {
124 /* x != c || c < c + 1 -> x < c */
125 ir_graph *const irg = current_ir_graph;
126 ir_node *const block = get_nodes_block(cmp_lo);
127 ir_node *const p = new_r_Proj(irg, block, cmp_lo, mode_b, pn_Cmp_Lt);
134 static void bool_or(ir_node *const n)
136 ir_node *const l = get_Or_left(n);
137 ir_node *const r = get_Or_right(n);
139 if (find_cond_pair(l, r, &res)) {
140 ir_node *const cmp_lo = res.cmp_lo;
141 ir_node *const cmp_hi = res.cmp_hi;
142 pn_Cmp const pnc_lo = res.pnc_lo;
143 pn_Cmp const pnc_hi = res.pnc_hi;
144 ir_node *const proj_lo = res.proj_lo;
145 ir_node *const proj_hi = res.proj_hi;
146 tarval *const tv_lo = res.tv_lo;
147 tarval *const tv_hi = res.tv_hi;
149 if ((pnc_lo == pn_Cmp_Ge || pnc_lo == pn_Cmp_Gt || pnc_lo == pn_Cmp_Ne) &&
150 (pnc_hi == pn_Cmp_Lt || pnc_hi == pn_Cmp_Le || pnc_hi == pn_Cmp_Ne)) {
151 /* x >=|>|!= lo | x <|<=|!= hi -> true */
152 ir_node *const t = new_Const(mode_b, tarval_b_true);
154 } else if ((pnc_lo == pn_Cmp_Lt || pnc_lo == pn_Cmp_Le || pnc_lo == pn_Cmp_Eq) &&
155 (pnc_hi == pn_Cmp_Lt || pnc_hi == pn_Cmp_Le || pnc_hi == pn_Cmp_Ne)) {
156 /* x <|<=|== lo || x <|<=|!= hi -> x <|<=|!= hi */
157 exchange(n, proj_hi);
158 } else if ((pnc_lo == pn_Cmp_Ge || pnc_lo == pn_Cmp_Gt || pnc_lo == pn_Cmp_Ne) &&
159 (pnc_hi == pn_Cmp_Eq || pnc_hi == pn_Cmp_Ge || pnc_hi == pn_Cmp_Gt)) {
160 /* x >=|>|!= lo || x ==|>=|> hi -> x >=|>|!= lo */
161 exchange(n, proj_lo);
162 } else if (tarval_is_one(tarval_sub(tv_hi, tv_lo))) { /* lo + 1 == hi */
163 if (pnc_lo == pn_Cmp_Lt && pnc_hi == pn_Cmp_Ge) {
164 /* x < c || x >= c + 1 -> x != c */
165 ir_graph *const irg = current_ir_graph;
166 ir_node *const block = get_nodes_block(cmp_lo);
167 ir_node *const p = new_r_Proj(irg, block, cmp_lo, mode_b, pn_Cmp_Ne);
169 } else if (pnc_lo == pn_Cmp_Le) {
170 if (pnc_hi == pn_Cmp_Eq) {
171 /* x <= c || x == c + 1 -> x <= c + 1 */
172 ir_graph *const irg = current_ir_graph;
173 ir_node *const block = get_nodes_block(cmp_hi);
174 ir_node *const p = new_r_Proj(irg, block, cmp_hi, mode_b, pn_Cmp_Le);
176 } else if (pnc_hi == pn_Cmp_Ge) {
177 /* x <= c || x >= c + 1 -> true */
178 ir_node *const t = new_Const(mode_b, tarval_b_true);
180 } else if (pnc_hi == pn_Cmp_Gt) {
181 /* x <= c || x > c + 1 -> x != c + 1 */
182 ir_graph *const irg = current_ir_graph;
183 ir_node *const block = get_nodes_block(cmp_hi);
184 ir_node *const p = new_r_Proj(irg, block, cmp_hi, mode_b, pn_Cmp_Ne);
187 } else if (pnc_lo == pn_Cmp_Eq && pnc_hi == pn_Cmp_Ge) {
188 /* x == c || c >= c + 1 -> x >= c */
189 ir_graph *const irg = current_ir_graph;
190 ir_node *const block = get_nodes_block(cmp_lo);
191 ir_node *const p = new_r_Proj(irg, block, cmp_lo, mode_b, pn_Cmp_Ge);
198 static void bool_walk(ir_node *n, void *env)
202 if (get_irn_mode(n) != mode_b) return;
206 } else if (is_Or(n)) {
211 void opt_bool(ir_graph *irg)
213 irg_walk_graph(irg, NULL, bool_walk, NULL);