+/**
+ * Check if an offset is a constant and these constant is bigger or equal
+ * than a given size.
+ */
+static int check_const_offset(ir_node *offset, int size) {
+ ir_mode *mode = get_irn_mode(offset);
+
+ /* ok, we found an offset, check for constant */
+ if (is_Const(offset) && mode_is_int(mode)) {
+ tarval *tv = new_tarval_from_long(size, mode);
+
+ /* size <= offset ? */
+ if (tarval_cmp(tv, get_Const_tarval(offset)) & (pn_Cmp_Eq|pn_Cmp_Lt))
+ return 1;
+ }
+ return 0;
+} /* check_const_offset */
+
+/**
+ * Check if we can determine that the two pointers always have an offset bigger then size
+ */
+static ir_alias_relation _different_pointer(ir_node *adr1, ir_node *adr2, int size) {
+ int found = 0;
+
+ if (is_Add(adr1)) {
+ /* first address is the result of a pointer addition */
+ ir_node *l1 = get_Add_left(adr1);
+ ir_node *r1 = get_Add_right(adr1);
+
+ if (l1 == adr2) {
+ found = check_const_offset(r1, size);
+ } else if (r1 == adr2) {
+ found = check_const_offset(l1, size);
+ } else if (is_Add(adr2)) {
+ /* second address is the result of a pointer addition */
+ ir_node *l2 = get_Add_left(adr2);
+ ir_node *r2 = get_Add_right(adr2);
+
+ if (l1 == l2) {
+ return _different_pointer(r1, r2, size);
+ } else if (l1 == r2) {
+ return _different_pointer(r1, l2, size);
+ } else if (r1 == l2) {
+ return _different_pointer(l1, r2, size);
+ } else if (r1 == r2) {
+ return _different_pointer(l1, l2, size);
+ }
+ }
+ } else if (is_Add(adr2)) {
+ /* second address is the result of a pointer addition */
+ ir_node *l2 = get_Add_left(adr2);
+ ir_node *r2 = get_Add_right(adr2);
+
+ if (l2 == adr1) {
+ found = check_const_offset(r2, size);
+ } else if (r2 == adr1) {
+ found = check_const_offset(l2, size);
+ }
+ } else {
+ return different_index(adr1, adr2, size);
+ }
+ return found ? no_alias : may_alias;
+} /* _different_pointer */
+
+/**
+ * Check if we can determine that the two pointers always have an offset bigger then the maximum size of mode1, mode2
+ */
+static ir_alias_relation different_pointer(ir_node *adr1, ir_mode *mode1, ir_node *adr2, ir_mode *mode2) {
+ int size = get_mode_size_bytes(mode1);
+ int n = get_mode_size_bytes(mode2);
+
+ if (n > size)
+ size = n;
+ return _different_pointer(adr1, adr2, size);
+} /* different_pointer */
+