Bug 60712 - "restrict" qualifier ignored on local variable
Summary: "restrict" qualifier ignored on local variable
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.8.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks: restrict
  Show dependency treegraph
 
Reported: 2014-03-30 17:51 UTC by gbugcc
Modified: 2022-12-26 06:39 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 10.0, 4.8.5, 4.9.4, 5.4.0, 6.4.0, 7.3.0, 8.3.0, 9.1.0
Last reconfirmed: 2020-02-28 00:00:00


Attachments
Test case (164 bytes, text/x-csrc)
2014-03-30 17:51 UTC, gbugcc
Details

Note You need to log in before you can comment on or make changes to this bug.
Description gbugcc 2014-03-30 17:51:43 UTC
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.
Comment 1 Andrew Pinski 2014-03-31 01:09:17 UTC
The inline issue is recorded as 58526.
Comment 2 Richard Biener 2014-03-31 08:21:31 UTC
Only restrict on parameters is implemented.
Comment 3 Tobias Burnus 2019-11-22 10:14:40 UTC
(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.
Comment 4 Martin Sebor 2020-02-29 00:45:26 UTC
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;

}
Comment 5 Richard Biener 2022-02-10 08:16:15 UTC
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.