- ir_node *const cmp_lo = cpair->cmp_lo;
- ir_node *const cmp_hi = cpair->cmp_hi;
- pn_Cmp const pnc_lo = cpair->pnc_lo;
- pn_Cmp const pnc_hi = cpair->pnc_hi;
- ir_node *const proj_lo = cpair->proj_lo;
- ir_node *const proj_hi = cpair->proj_hi;
- tarval *const tv_lo = cpair->tv_lo;
- tarval *const tv_hi = cpair->tv_hi;
-
- if ((pnc_lo == pn_Cmp_Ge || pnc_lo == pn_Cmp_Gt || pnc_lo == pn_Cmp_Ne) &&
- (pnc_hi == pn_Cmp_Lt || pnc_hi == pn_Cmp_Le || pnc_hi == pn_Cmp_Ne)) {
- /* x >=|>|!= lo | x <|<=|!= hi -> true */
- ir_node *const t = new_Const(mode_b, tarval_b_true);
+ ir_node *const cmp_lo = cpair->cmp_lo;
+ ir_node *const cmp_hi = cpair->cmp_hi;
+ pn_Cmp pnc_lo = cpair->pnc_lo;
+ pn_Cmp const pnc_hi = cpair->pnc_hi;
+ ir_node *const proj_lo = cpair->proj_lo;
+ ir_node *const proj_hi = cpair->proj_hi;
+ ir_tarval * tv_lo = cpair->tv_lo;
+ ir_tarval * tv_hi = cpair->tv_hi;
+ ir_mode * mode = cpair->lo_mode;
+ ir_graph * irg = get_irn_irg(cmp_lo);
+
+ if (pnc_lo == pn_Cmp_Lg && pnc_hi == pn_Cmp_Lg &&
+ tarval_is_null(tv_lo) && tarval_is_null(tv_hi) &&
+ mode == get_tarval_mode(tv_hi)) {
+ /* p != NULL || q != NULL ==> (p|q) != NULL) */
+ ir_node *lol, *hil, *cmp, *c, *p;
+
+ if (mode_is_reference(mode)) {
+ mode = find_unsigned_mode(mode);
+ if (! mode)
+ return NULL;
+ tv_lo = tarval_convert_to(tv_lo, mode);
+ if (tv_lo == tarval_bad)
+ return NULL;
+ }
+ if (mode_is_int(mode)) {
+ lol = get_Cmp_left(cmp_lo);
+ lol = new_r_Conv(dst_block, lol, mode);
+ hil = get_Cmp_left(cmp_hi);
+ hil = new_r_Conv(dst_block, hil, mode);
+ p = new_r_Or(dst_block, lol, hil, mode);
+ c = new_r_Const(irg, tv_lo);
+ cmp = new_r_Cmp(dst_block, p, c);
+ p = new_r_Proj(cmp, mode_b, pn_Cmp_Lg);
+ return p;
+ }
+ }
+
+ /* the following tests expect one common operand */
+ if (get_Cmp_left(cmp_lo) != get_Cmp_left(cmp_hi))
+ return 0;
+
+ /* TODO: for now reject float modes */
+ if (! mode_is_int(mode))
+ return 0;
+
+ /* Beware of NaN's, we can only check for (ordered) != here (which is Lg, not Ne) */
+ if ((pnc_lo == pn_Cmp_Ge || pnc_lo == pn_Cmp_Gt || pnc_lo == pn_Cmp_Lg) &&
+ (pnc_hi == pn_Cmp_Lt || pnc_hi == pn_Cmp_Le || pnc_hi == pn_Cmp_Lg)) {
+ /* x >=|>|!= lo | x <|<=|!= hi ==> true */
+ ir_node *const t = new_r_Const(irg, tarval_b_true);