cleanup: Remove duplicate MIN/MAX macros.
[libfirm] / ir / ana / vrp.c
1 /*
2  * This file is part of libFirm.
3  * Copyright (C) 2012 University of Karlsruhe.
4  */
5
6 /**
7  * @file
8  * @brief   analyze graph to provide value range information
9  * @author  Jonas Fietz
10  */
11 #include "config.h"
12
13 #include "irtypes.h"
14 #include "vrp.h"
15 #include "iroptimize.h"
16 #include "irouts.h"
17 #include "irgraph_t.h"
18 #include "irgopt.h"
19 #include "irpass.h"
20 #include "irgwalk.h"
21 #include "iredges.h"
22 #include "tv.h"
23 #include "irop.h"
24 #include "pdeq.h"
25 #include "irnodemap.h"
26 #include "irhooks.h"
27 #include "bitset.h"
28 #include "debug.h"
29
30 DEBUG_ONLY(static firm_dbg_module_t *dbg;)
31
32 typedef struct vrp_env_t {
33         waitq       *workqueue;
34         bitset_t    *visited;
35         ir_vrp_info *info;
36 } vrp_env_t;
37
38 static vrp_attr *vrp_get_or_set_info(ir_vrp_info *info, const ir_node *node)
39 {
40         vrp_attr *attr = ir_nodemap_get(vrp_attr, &info->infos, node);
41         if (attr == NULL) {
42                 ir_mode *mode = get_irn_mode(node);
43                 assert(mode_is_int(mode));
44
45                 attr = OALLOCZ(&info->obst, vrp_attr);
46                 attr->range_type   = VRP_UNDEFINED;
47                 attr->bits_set     = get_mode_null(mode);
48                 attr->bits_not_set = get_mode_all_one(mode);
49                 attr->range_bottom = get_tarval_top();
50                 attr->range_top    = get_tarval_top();
51
52                 ir_nodemap_insert(&info->infos, node, attr);
53         }
54         return attr;
55 }
56
57 vrp_attr *vrp_get_info(const ir_node *node)
58 {
59         ir_graph *irg = get_irn_irg(node);
60         if (irg->vrp.infos.data == NULL)
61                 return NULL;
62         return ir_nodemap_get(vrp_attr, &irg->vrp.infos, node);
63 }
64
65 static int vrp_update_node(ir_vrp_info *info, ir_node *node)
66 {
67         ir_tarval *new_bits_set = get_tarval_bad();
68         ir_tarval *new_bits_not_set = get_tarval_bad();
69         ir_tarval *new_range_bottom = get_tarval_bad();
70         ir_tarval *new_range_top = get_tarval_bad();
71         enum range_types new_range_type = VRP_UNDEFINED;
72         int something_changed = 0;
73         vrp_attr *vrp;
74
75         if (!mode_is_int(get_irn_mode(node))) {
76                 return 0; /* we don't optimize for non-int-nodes*/
77         }
78
79         vrp = vrp_get_or_set_info(info, node);
80
81         /* TODO: Check if all predecessors have valid VRP information*/
82
83         switch (get_irn_opcode(node)) {
84         case iro_Const: {
85                 ir_tarval *tv = get_Const_tarval(node);
86                 new_bits_set = tv;
87                 new_bits_not_set = tv;
88                 new_range_bottom = tv;
89                 new_range_top = tv;
90                 new_range_type = VRP_RANGE;
91                 break;
92         }
93         case iro_And: {
94                 const vrp_attr *vrp_left, *vrp_right;
95                 const ir_node *left, *right;
96
97                 left = get_And_left(node);
98                 right = get_And_right(node);
99                 vrp_left = vrp_get_or_set_info(info, left);
100                 vrp_right = vrp_get_or_set_info(info, right);
101                 new_bits_set = tarval_and(vrp_left->bits_set, vrp_right->bits_set);
102                 new_bits_not_set = tarval_and(vrp_left->bits_not_set, vrp_right->bits_not_set);
103
104                 break;
105         }
106
107         case iro_Add: {
108                 const vrp_attr *vrp_left  = vrp_get_or_set_info(info, get_Add_left(node));
109                 const vrp_attr *vrp_right = vrp_get_or_set_info(info, get_Add_right(node));
110
111                 if (vrp_left->range_type == VRP_UNDEFINED
112                  || vrp_right->range_type == VRP_UNDEFINED
113                  || vrp_left->range_type == VRP_VARYING
114                  || vrp_right->range_type == VRP_VARYING) {
115                         return 0;
116                 }
117
118                 if (vrp_left->range_type == VRP_RANGE
119                  && vrp_right->range_type == VRP_RANGE) {
120                         tarval_int_overflow_mode_t rem = tarval_get_integer_overflow_mode();
121                         tarval_set_integer_overflow_mode(TV_OVERFLOW_BAD);
122                         ir_tarval *new_top
123                                 = tarval_add(vrp_left->range_top, vrp_right->range_top);
124                         ir_tarval *new_bottom
125                                 = tarval_add(vrp_left->range_bottom, vrp_right->range_bottom);
126                         tarval_set_integer_overflow_mode(rem);
127
128                         if (new_top != tarval_bad && new_bottom != tarval_bad) {
129                                 new_range_bottom = new_bottom;
130                                 new_range_top    = new_top;
131                                 new_range_type   = VRP_RANGE;
132                         } else {
133                                 /* TODO Implement overflow handling*/
134                                 new_range_type = VRP_UNDEFINED;
135                         }
136                 }
137                 break;
138         }
139
140         case iro_Sub: {
141                 ir_node *left  = get_Sub_left(node);
142                 ir_node *right = get_Sub_right(node);
143
144                 if (!mode_is_int(get_irn_mode(left)))
145                         return 0;
146
147                 const vrp_attr *vrp_left  = vrp_get_or_set_info(info, left);
148                 const vrp_attr *vrp_right = vrp_get_or_set_info(info, right);
149
150                 if (vrp_left->range_type == VRP_UNDEFINED
151                  || vrp_right->range_type == VRP_UNDEFINED
152                  || vrp_left->range_type == VRP_VARYING
153                  || vrp_right->range_type == VRP_VARYING) {
154                         return 0;
155                 }
156
157                 if (vrp_left->range_type == VRP_RANGE
158                  && vrp_right->range_type == VRP_RANGE) {
159                         tarval_int_overflow_mode_t rem = tarval_get_integer_overflow_mode();
160                         tarval_set_integer_overflow_mode(TV_OVERFLOW_BAD);
161                         ir_tarval *new_top = tarval_sub(vrp_left->range_top, vrp_right->range_top, NULL);
162                         ir_tarval *new_bottom = tarval_sub(vrp_left->range_bottom, vrp_right->range_bottom, NULL);
163                         tarval_set_integer_overflow_mode(rem);
164
165                         if (new_top != tarval_bad && new_bottom != tarval_bad) {
166                                 new_range_bottom = new_bottom;
167                                 new_range_top = new_top;
168                                 new_range_type = VRP_RANGE;
169                         } else {
170                                 /* TODO Implement overflow handling*/
171                                 new_range_type = VRP_UNDEFINED;
172                         }
173                 }
174                 break;
175         }
176
177         case iro_Or: {
178                 const vrp_attr *vrp_left, *vrp_right;
179
180                 vrp_left = vrp_get_or_set_info(info, get_Or_left(node));
181                 vrp_right = vrp_get_or_set_info(info, get_Or_right(node));
182
183                 new_bits_set = tarval_or(vrp_left->bits_set, vrp_right->bits_set);
184                 new_bits_not_set = tarval_or(vrp_left->bits_not_set, vrp_right->bits_not_set);
185
186                 break;
187         }
188
189         case iro_Rotl: {
190                 const vrp_attr *vrp_left;
191                 const ir_node *right = get_Rotl_right(node);
192
193                 vrp_left = vrp_get_or_set_info(info, get_Rotl_left(node));
194
195                 /* We can only compute this if the right value is a constant*/
196                 if (is_Const(right)) {
197                         new_bits_set = tarval_rotl(vrp_left->bits_set, get_Const_tarval(right));
198                         new_bits_not_set = tarval_rotl(vrp_left->bits_not_set, get_Const_tarval(right));
199                 }
200                 break;
201         }
202
203         case iro_Shl: {
204                 const vrp_attr *vrp_left;
205                 const ir_node *right = get_Shl_right(node);
206                 vrp_left = vrp_get_or_set_info(info, get_Shl_left(node));
207
208                 /* We can only compute this if the right value is a constant*/
209                 if (is_Const(right)) {
210                         new_bits_set = tarval_shl(vrp_left->bits_set, get_Const_tarval(right));
211                         new_bits_not_set = tarval_shl(vrp_left->bits_not_set, get_Const_tarval(right));
212                 }
213                 break;
214         }
215
216         case iro_Shr: {
217                 const vrp_attr *vrp_left;
218                 const ir_node *right = get_Shr_right(node);
219
220                 vrp_left = vrp_get_or_set_info(info, get_Shr_left(node));
221
222                 /* We can only compute this if the right value is a constant*/
223                 if (is_Const(right)) {
224                         new_bits_set = tarval_shr(vrp_left->bits_set, get_Const_tarval(right));
225                         new_bits_not_set = tarval_shr(vrp_left->bits_not_set, get_Const_tarval(right));
226                 }
227                 break;
228         }
229
230         case iro_Shrs: {
231                 const vrp_attr *vrp_left;
232                 const ir_node *right = get_Shrs_right(node);
233
234                 vrp_left = vrp_get_or_set_info(info, get_Shrs_left(node));
235
236                 /* We can only compute this if the right value is a constant*/
237                 if (is_Const(right)) {
238                         new_bits_set = tarval_shrs(vrp_left->bits_set, get_Const_tarval(right));
239                         new_bits_not_set = tarval_shrs(vrp_left->bits_not_set, get_Const_tarval(right));
240                 }
241                 break;
242         }
243
244         case iro_Eor: {
245                 const vrp_attr *vrp_left, *vrp_right;
246
247                 vrp_left = vrp_get_or_set_info(info, get_Eor_left(node));
248                 vrp_right = vrp_get_or_set_info(info, get_Eor_right(node));
249
250                 new_bits_set = tarval_or(
251                                                 tarval_and(vrp_left->bits_set, tarval_not(vrp_right->bits_not_set)),
252                                                 tarval_and(tarval_not(vrp_left->bits_not_set), vrp_right->bits_set));
253
254                 new_bits_not_set = tarval_not(tarval_or(
255                                 tarval_and(vrp_left->bits_set,vrp_right->bits_set),
256                                                         tarval_and(tarval_not(vrp_left->bits_not_set),
257                                                                 tarval_not(vrp_right->bits_not_set))));
258
259                 break;
260         }
261
262         case iro_Id: {
263                 const vrp_attr *vrp_pred = vrp_get_or_set_info(info, get_Id_pred(node));
264                 new_bits_set = vrp_pred->bits_set;
265                 new_bits_not_set = vrp_pred->bits_not_set;
266                 new_range_top = vrp_pred->range_top;
267                 new_range_bottom = vrp_pred->range_bottom;
268                 new_range_type = vrp_pred->range_type;
269                 break;
270         }
271
272         case iro_Not: {
273                 const vrp_attr *vrp_pred = vrp_get_or_set_info(info, get_Not_op(node));
274                 new_bits_set = tarval_not(vrp_pred->bits_not_set);
275                 new_bits_not_set = tarval_not(vrp_pred->bits_set);
276                 break;
277         }
278
279         case iro_Conv: {
280                 const ir_node *pred = get_Conv_op(node);
281                 ir_mode *old_mode = get_irn_mode(pred);
282                 const vrp_attr *vrp_pred;
283
284                 ir_mode *new_mode;
285
286                 if (!mode_is_int(old_mode))
287                         return 0;
288
289                 vrp_pred = vrp_get_or_set_info(info, pred);
290                 new_mode = get_irn_mode(node);
291
292                 /* The second and is needed if target type is smaller*/
293                 new_bits_not_set = tarval_convert_to(get_mode_all_one(old_mode), new_mode);
294                 new_bits_not_set = tarval_and(new_bits_not_set, tarval_convert_to(vrp_pred->bits_not_set, new_mode));
295                 new_bits_set = tarval_and(
296                                 new_bits_not_set, tarval_convert_to(vrp_pred->bits_set, new_mode));
297
298                 /* Matze: TODO, BUGGY, tarval_cmp never returns ir_relation_less_equal */
299                 if (tarval_cmp(vrp_pred->range_top, get_mode_max(new_mode)) == ir_relation_less_equal) {
300                         vrp->range_top = vrp_pred->range_top;
301                 }
302
303                 /* Matze: TODO, BUGGY, tarval_cmp never returns ir_relation_greater_equal */
304                 if (tarval_cmp(vrp_pred->range_bottom, get_mode_min(new_mode)) == ir_relation_greater_equal) {
305                         vrp->range_bottom = vrp_pred->range_bottom;
306                 }
307                 break;
308         }
309
310         case iro_Confirm: {
311                 const ir_relation relation = get_Confirm_relation(node);
312                 const ir_node    *bound    = get_Confirm_bound(node);
313
314
315                 if (relation == ir_relation_less_greater) {
316                         /** @todo: Handle non-Const bounds */
317                         if (is_Const(bound)) {
318                                 new_range_type = VRP_ANTIRANGE;
319                                 new_range_top = get_Const_tarval(bound);
320                                 new_range_bottom = get_Const_tarval(bound);
321                         }
322                 } else if (relation == ir_relation_less_equal) {
323                         if (is_Const(bound)) {
324                                 new_range_type = VRP_RANGE;
325                                 new_range_top = get_Const_tarval(bound);
326                                 new_range_bottom = get_tarval_min(get_irn_mode(node));
327                         }
328                 }
329                 break;
330         }
331
332         case iro_Phi: {
333                 /* combine all ranges*/
334
335                 int num = get_Phi_n_preds(node);
336                 ir_relation relation;
337                 int i;
338
339                 const ir_node *pred = get_Phi_pred(node,0);
340                 const vrp_attr *vrp_pred = vrp_get_or_set_info(info, pred);
341                 new_range_top = vrp_pred->range_top;
342                 new_range_bottom = vrp_pred->range_bottom;
343                 new_range_type = vrp_pred->range_type;
344                 new_bits_set = vrp_pred->bits_set;
345                 new_bits_not_set = vrp_pred->bits_not_set;
346
347                 assert(num > 0);
348
349                 for (i = 1; i < num; i++) {
350                         pred = get_Phi_pred(node, i);
351                         vrp_pred = vrp_get_or_set_info(info, pred);
352                         if (new_range_type == VRP_RANGE && vrp_pred->range_type ==
353                                         VRP_RANGE) {
354                                 relation = tarval_cmp(new_range_top, vrp_pred->range_top);
355                                 if (relation == ir_relation_less) {
356                                         new_range_top = vrp_pred->range_top;
357                                 }
358                                 relation = tarval_cmp(new_range_bottom, vrp_pred->range_bottom);
359                                 if (relation == ir_relation_greater) {
360                                         new_range_bottom = vrp_pred->range_bottom;
361                                 }
362                         } else {
363                                 new_range_type = VRP_VARYING;
364                         }
365                         new_bits_set = tarval_and(new_bits_set, vrp_pred->bits_set);
366                         new_bits_not_set = tarval_or(new_bits_not_set,
367                                         vrp_pred->bits_not_set);
368                 }
369
370                 break;
371         }
372         default:
373                 /* unhandled, therefore never updated */
374                 break;
375         }
376
377
378
379         /* TODO: Check, if there can be information derived from any of these:
380         is_Abs(node) is_Alloc(node) is_Anchor(node) is_Borrow(node) is_Bound(node)
381         is_Break(node) is_Builtin(node) is_Call(node)
382         is_Carry(node) is_Cmp(node) is_Cond(node)
383         is_CopyB(node) is_Div(node) is_Dummy(node)
384         is_End(node) is_Free(node)
385         is_IJmp(node) is_InstOf(node) is_Jmp(node) is_Load(node) is_Minus(node)
386         is_Mod(node) is_Mul(node) is_Mulh(node) is_Mux(node) is_NoMem(node)
387         is_Pin(node) is_Proj(node)
388         is_Raise(node) is_Return(node) is_Sel(node) is_Start(node) is_Store(node)
389         is_SymConst(node) is_Sync(node) is_Tuple(node)
390         */
391
392         /* @todo: At this place, we check if the mode of the variable changed. A
393          * better place for this might be in the convopt.c file
394          */
395
396         if (new_bits_set != tarval_bad && get_tarval_mode(new_bits_set) != get_tarval_mode(vrp->bits_set)) {
397                 vrp->bits_set = tarval_convert_to(vrp->bits_set, get_irn_mode(node));
398         }
399         if (new_bits_not_set != tarval_bad && get_tarval_mode(new_bits_not_set) != get_tarval_mode(vrp->bits_not_set)) {
400                 vrp->bits_not_set = tarval_convert_to(vrp->bits_not_set, get_irn_mode(node));
401         }
402
403         if (vrp->range_type != VRP_UNDEFINED && new_range_type != VRP_UNDEFINED && get_tarval_mode(new_range_top) != get_tarval_mode(vrp->range_top)) {
404                 /* @todo: We might be able to preserve this range information if it
405                  * fits in */
406                 vrp->range_type = VRP_VARYING;
407         }
408
409         /* Merge the newly calculated values with those that might already exist*/
410         if (new_bits_set != tarval_bad) {
411                 new_bits_set = tarval_or(new_bits_set, vrp->bits_set);
412                 if (new_bits_set != vrp->bits_set) {
413                         something_changed = 1;
414                         vrp->bits_set = new_bits_set;
415                 }
416         }
417         if (new_bits_not_set != tarval_bad) {
418                 new_bits_not_set = tarval_and(new_bits_not_set, vrp->bits_not_set);
419
420                 if (new_bits_not_set != vrp->bits_not_set) {
421                         something_changed = 1;
422                         vrp->bits_not_set = new_bits_not_set;
423                 }
424         }
425
426         if (vrp->range_type == VRP_UNDEFINED &&
427                         new_range_type != VRP_UNDEFINED) {
428                 something_changed = 1;
429                 vrp->range_type = new_range_type;
430                 vrp->range_bottom = new_range_bottom;
431                 vrp->range_top = new_range_top;
432
433         } else if (vrp->range_type == VRP_RANGE) {
434                 if (new_range_type == VRP_RANGE) {
435                         if (tarval_cmp(vrp->range_bottom, new_range_bottom) == ir_relation_less) {
436                                 something_changed = 1;
437                                 vrp->range_bottom = new_range_bottom;
438                         }
439                         if (tarval_cmp(vrp->range_top, new_range_top) == ir_relation_greater) {
440                                 something_changed = 1;
441                                 vrp->range_top = new_range_top;
442                         }
443                 }
444
445                 if (new_range_type == VRP_ANTIRANGE) {
446                         /* if they are overlapping, cut the range.*/
447                         /* TODO: Maybe we can preserve more information here*/
448                         if (tarval_cmp(vrp->range_bottom, new_range_top) == ir_relation_greater &&
449                                         tarval_cmp(vrp->range_bottom, new_range_bottom) == ir_relation_greater) {
450                                 something_changed = 1;
451                                 vrp->range_bottom = new_range_top;
452
453                         } else if (tarval_cmp(vrp->range_top, new_range_bottom) == ir_relation_greater &&
454                                         tarval_cmp(vrp->range_top, new_range_top) == ir_relation_less) {
455                                 something_changed = 1;
456                                 vrp->range_top = new_range_bottom;
457                         }
458
459                         /* We can not handle the case where the anti range is in the*/
460                         /* range*/
461
462                 }
463         } else if (vrp->range_type == VRP_ANTIRANGE) {
464                 if (new_range_type == VRP_ANTIRANGE) {
465                         if (tarval_cmp(vrp->range_bottom, new_range_bottom) == ir_relation_greater) {
466                                 something_changed = 1;
467                                 vrp->range_bottom = new_range_bottom;
468                         }
469                         if (tarval_cmp(vrp->range_top, new_range_top) == ir_relation_less) {
470                                 something_changed = 1;
471                                 vrp->range_top = new_range_top;
472                         }
473                 }
474
475                 if (new_range_type == VRP_RANGE) {
476                         if (tarval_cmp(vrp->range_bottom, new_range_top) == ir_relation_greater) {
477                                 something_changed = 1;
478                                 vrp->range_bottom = new_range_top;
479                         }
480                         if (tarval_cmp(vrp->range_top, new_range_bottom) == ir_relation_less) {
481                                 something_changed = 1;
482                                 vrp->range_top = new_range_bottom;
483                         }
484                 }
485         }
486
487         assert(tarval_is_null(
488                                 tarval_and(vrp->bits_set, tarval_not(vrp->bits_not_set))));
489         return something_changed;
490 }
491
492 static void vrp_first_pass(ir_node *n, void *e)
493 {
494         int i;
495         vrp_env_t *env = (vrp_env_t*) e;
496
497         if (is_Block(n))
498                 return;
499
500         bitset_set(env->visited, get_irn_idx(n));
501
502         vrp_update_node(env->info, n);
503
504         for (i = get_irn_n_outs(n) - 1; i >=0; --i) {
505                 ir_node *succ = get_irn_out(n, i);
506                 if (bitset_is_set(env->visited, get_irn_idx(succ))) {
507                         /* we found a loop*/
508                         waitq_put(env->workqueue, succ);
509                 }
510         }
511 }
512
513 static void dump_vrp_info(void *ctx, FILE *F, const ir_node *node)
514 {
515         vrp_attr *vrp;
516
517         (void) ctx;
518         if (!mode_is_int(get_irn_mode(node)))
519                 return;
520
521         vrp = vrp_get_info(node);
522         if (vrp == NULL)
523                 return;
524
525         fprintf(F, "vrp range type: %d\n", (int) vrp->range_type);
526         if (vrp->range_type == VRP_RANGE || vrp->range_type == VRP_ANTIRANGE) {
527                 ir_fprintf(F, "vrp range bottom: %T\n",vrp->range_bottom);
528                 ir_fprintf(F, "vrp range top: %T\n", vrp->range_top);
529         }
530         ir_fprintf(F, "vrp bits set: %T\n", vrp->bits_set);
531         ir_fprintf(F, "vrp bits not set: %T\n", vrp->bits_not_set);
532 }
533
534 static hook_entry_t dump_hook;
535
536 void set_vrp_data(ir_graph *irg)
537 {
538         ir_node *succ, *node;
539         int i;
540         vrp_env_t *env;
541         ir_vrp_info *info;
542
543         if (irg->vrp.infos.data != NULL)
544                 free_vrp_data(irg);
545
546         FIRM_DBG_REGISTER(dbg, "ir.ana.vrp");
547
548         assure_irg_outs(irg); /* ensure that out edges are consistent*/
549         ir_nodemap_init(&irg->vrp.infos, irg);
550         obstack_init(&irg->vrp.obst);
551         info = &irg->vrp;
552
553         if (dump_hook.hook._hook_node_info == NULL) {
554                 dump_hook.hook._hook_node_info = dump_vrp_info;
555                 register_hook(hook_node_info, &dump_hook);
556         }
557
558         env = OALLOCZ(&irg->vrp.obst, vrp_env_t);
559         env->workqueue = new_waitq();
560         env->info      = info;
561
562         env->visited = bitset_malloc(get_irg_last_idx(irg));
563         irg_walk_graph(irg, NULL, vrp_first_pass, env);
564         bitset_free(env->visited);
565
566         /* while there are entries in the worklist, continue*/
567         while (!waitq_empty(env->workqueue)) {
568                 node = (ir_node*) waitq_get(env->workqueue);
569
570                 if (vrp_update_node(info, node)) {
571                         /* if something changed, add successors to worklist*/
572                         for (i = get_irn_n_outs(node) - 1; i >= 0; --i) {
573                                 succ =  get_irn_out(node, i);
574                                 waitq_put(env->workqueue, succ);
575                         }
576                 }
577         }
578         del_waitq(env->workqueue);
579 }
580
581 void free_vrp_data(ir_graph *irg)
582 {
583         if (irg->vrp.infos.data == NULL)
584                 return;
585         obstack_free(&irg->vrp.obst, NULL);
586         ir_nodemap_destroy(&irg->vrp.infos);
587 }
588
589 ir_graph_pass_t *set_vrp_pass(const char *name)
590 {
591         return def_graph_pass(name ? name : "set_vrp", set_vrp_data);
592 }
593
594 ir_relation vrp_cmp(const ir_node *left, const ir_node *right)
595 {
596         vrp_attr *vrp_left, *vrp_right;
597
598         if (!mode_is_int(get_irn_mode(left)))
599                 return ir_relation_true;
600
601         vrp_left = vrp_get_info(left);
602         vrp_right = vrp_get_info(right);
603
604         if (!vrp_left || !vrp_right)
605                 return ir_relation_true;
606
607         if (vrp_left->range_type == VRP_RANGE && vrp_right->range_type == VRP_RANGE) {
608                 if (tarval_cmp(vrp_left->range_top, vrp_right->range_bottom) == ir_relation_less) {
609                         return ir_relation_less;
610                 }
611                 if (tarval_cmp(vrp_left->range_bottom, vrp_right->range_top) == ir_relation_greater) {
612                         return ir_relation_greater;
613                 }
614         }
615
616         if (!tarval_is_null(tarval_and(vrp_left->bits_set, tarval_not(vrp_right->bits_not_set))) ||
617                         !tarval_is_null(tarval_and(tarval_not(vrp_left->bits_not_set), vrp_right->bits_set))) {
618                 return ir_relation_less_greater;
619         }
620
621         /* TODO: We can get way more information here*/
622         return ir_relation_true;
623 }