Created attachment 32490 [details] Test case Version: x86_64-w64-mingw32-gcc 4.8.2 (standard Cygwin binaries) Flags: gcc -std=c99 -O3 sum()'s loop is optimized into a single multiply, as it should. But when inlined automatically by the compiler or "manually" by applying restrict qualifiers to local variables, the optimization fails. This is might be the same as bug 58526. However, -fdump-tree-alias shows that inlining removed all restrict qualifiers, whereas they are still present in the type information of bug_when_local_variable(), so perhaps there are two distinct bugs here.
The inline issue is recorded as 58526.
Only restrict on parameters is implemented.
(In reply to Andrew Pinski from comment #1) > The inline issue is recorded as PR 58526. This has been fixed in GCC 5. But the following still applies: (In reply to Richard Biener from comment #2) > Only restrict on parameters is implemented.
No change in GCC 10: $ cat pr60712.c && gcc -O3 -S -Wall -fdump-tree-optimized=/dev/stdout pr60712.c void sum(int *restrict a, int *restrict b) { *a = 0; for (int i=0; i<100; i++) *a += *b; } int *global_a, *global_b; void bug_when_inline() { sum(global_a, global_b); } void bug_when_local_variable() { int* restrict a = global_a; int* restrict b = global_b; *a = 0; for (int i=0; i<100; i++) *a += *b; } ;; Function sum (sum, funcdef_no=0, decl_uid=1931, cgraph_uid=1, symbol_order=0) sum (int * restrict a, int * restrict b) { int _2; int _13; <bb 2> [local count: 10737416]: _2 = *b_9(D); _13 = _2 * 100; *a_7(D) = _13; return; } ;; Function bug_when_inline (bug_when_inline, funcdef_no=1, decl_uid=1939, cgraph_uid=2, symbol_order=3) bug_when_inline () { int * global_b.0_1; int * global_a.1_2; int _5; int _12; <bb 2> [local count: 10737416]: global_b.0_1 = global_b; global_a.1_2 = global_a; _5 = *global_b.0_1; _12 = _5 * 100; *global_a.1_2 = _12; return; } ;; Function bug_when_local_variable (bug_when_local_variable, funcdef_no=2, decl_uid=1941, cgraph_uid=3, symbol_order=4) Removing basic block 5 bug_when_local_variable () { int * restrict b; int * restrict a; int _2; int _3; unsigned int ivtmp_4; unsigned int ivtmp_5; int prephitmp_15; <bb 2> [local count: 10737416]: a_7 = global_a; b_8 = global_b; *a_7 = 0; <bb 3> [local count: 1063004409]: # prephitmp_15 = PHI <0(2), _3(3)> # ivtmp_5 = PHI <100(2), ivtmp_4(3)> _2 = *b_8; _3 = _2 + prephitmp_15; *a_7 = _3; ivtmp_4 = ivtmp_5 + 4294967295; if (ivtmp_4 != 0) goto <bb 3>; [98.99%] else goto <bb 4>; [1.01%] <bb 4> [local count: 10737416]: return; }
After inlining works as expected now (see comment#4 which shows this). We do not honor __restrict on local variables because we cannot adhere to the language constraints within our implementation framework. We only can do that for function parameters.