+ case iro_Cmp: {
+ bitinfo* const l = get_bitinfo(get_Cmp_left(irn));
+ bitinfo* const r = get_bitinfo(get_Cmp_right(irn));
+ if (l == NULL || r == NULL) {
+ goto result_unknown; // Cmp compares something we cannot evaluate.
+ } 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;
+ }