- switch (get_Proj_proj(irn)) {
- case pn_Cmp_Lg: {
- tarval* const lz = l->z;
- tarval* const lo = l->o;
- tarval* const rz = r->z;
- tarval* const ro = r->o;
- if (!tarval_is_null(tarval_andnot(ro, lz)) ||
- !tarval_is_null(tarval_andnot(lo, rz))) {
- // At least one bit differs.
- z = o = get_tarval_b_true();
- } else if (lz == lo && rz == ro && lz == rz) {
- z = o = get_tarval_b_false();
- } else {
- goto result_unknown;
- }
- break;
- }
-
- case pn_Cmp_Eq: {
- tarval* const lz = l->z;
- tarval* const lo = l->o;
- tarval* const rz = r->z;
- tarval* const ro = r->o;
- if (!tarval_is_null(tarval_andnot(ro, lz)) ||
- !tarval_is_null(tarval_andnot(lo, rz))) {
- // At least one bit differs.
- z = o = get_tarval_b_false();
- } else if (lz == lo && rz == ro && lz == rz) {
- z = o = get_tarval_b_true();
- } else {
- goto result_unknown;
- }
- break;
+ } else {
+ ir_tarval* const lz = l->z;
+ ir_tarval* const lo = l->o;
+ ir_tarval* const rz = r->z;
+ ir_tarval* const ro = r->o;
+ ir_relation const relation = get_Cmp_relation(irn);
+ switch (relation) {
+ case ir_relation_less_greater:
+ if (!tarval_is_null(tarval_andnot(ro, lz)) ||
+ !tarval_is_null(tarval_andnot(lo, rz))) {
+ // At least one bit differs.
+ z = o = t;
+ } else if (lz == lo && rz == ro && lz == rz) {
+ z = o = f;
+ } else {
+ goto result_unknown;
+ }
+ break;
+
+ case ir_relation_equal:
+ if (!tarval_is_null(tarval_andnot(ro, lz)) ||
+ !tarval_is_null(tarval_andnot(lo, rz))) {
+ // At least one bit differs.
+ z = o = f;
+ } else if (lz == lo && rz == ro && lz == rz) {
+ z = o = t;
+ } else {
+ goto result_unknown;
+ }
+ break;
+
+ case ir_relation_less_equal:
+ case ir_relation_less:
+ /* TODO handle negative values */
+ if (tarval_is_negative(lz) || tarval_is_negative(lo) ||
+ tarval_is_negative(rz) || tarval_is_negative(ro))
+ goto result_unknown;
+
+ if (tarval_cmp(lz, ro) & relation) {
+ /* Left upper bound is smaller(/equal) than right lower bound. */
+ z = o = t;
+ } else if (!(tarval_cmp(lo, rz) & relation)) {
+ /* Left lower bound is not smaller(/equal) than right upper bound. */
+ z = o = f;
+ } else {
+ goto result_unknown;
+ }
+ break;
+
+ case ir_relation_greater_equal:
+ case ir_relation_greater:
+ /* TODO handle negative values */
+ if (tarval_is_negative(lz) || tarval_is_negative(lo) ||
+ tarval_is_negative(rz) || tarval_is_negative(ro))
+ goto result_unknown;
+
+ if (!(tarval_cmp(lz, ro) & relation)) {
+ /* Left upper bound is not greater(/equal) than right lower bound. */
+ z = o = f;
+ } else if (tarval_cmp(lo, rz) & relation) {
+ /* Left lower bound is greater(/equal) than right upper bound. */
+ z = o = t;
+ } else {
+ goto result_unknown;
+ }
+ break;
+
+ default:
+ goto cannot_analyse;