In the test case below, the subtraction can safely be folded to zero because a is a restricted pointer (as is effectively also b), *a is read, and if (a == b) were true, the call g(b) couldn't also modify *a either via *(int*)b or by any other means; as a result, a == b must either be false or g(b) cannot modify *a. Clang folds the subtraction but GCC does not. $ cat c.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout c.c void g (void *); int f (int * restrict a, void * /* restrict */ b) { int t = *a; g (b); return *a - t; // can be folded to zero } ;; Function f (f, funcdef_no=0, decl_uid=1933, cgraph_uid=1, symbol_order=0) f (int * restrict a, void * restrict b) { int t; int _1; int _7; <bb 2> [local count: 1073741824]: t_4 = *a_3(D); g (b_5(D)); _1 = *a_3(D); _7 = _1 - t_4; return _7; }
I think there's a duplicate somewhere. We currently cannot encode "restrict" into the "accesses" implied by a call. Note there's slight complication when g (b) eventually recurses into 'f' passing this 'b' as 'a'. Recursion makes the interpretation of the lexically defined restrict concept a bit weird. So I think this bug can be closed as duplicate of the "restrict and calls" bug. *** This bug has been marked as a duplicate of bug 89479 ***