public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Qing Zhao <qing.zhao@oracle.com>
To: Richard Biener <rguenther@suse.de>
Cc: gcc-patches <gcc-patches@gcc.gnu.org>
Subject: Re: [GCC13][Patch][PR106457]improve array_at_struct_end_p for array objects (PR106457)
Date: Thu, 11 Aug 2022 13:26:51 +0000	[thread overview]
Message-ID: <71C7EEA6-2D60-49F1-BB9C-8EDF98DEBAB6@oracle.com> (raw)
In-Reply-To: <nycvar.YFH.7.77.849.2208110725270.13569@jbgna.fhfr.qr>



> On Aug 11, 2022, at 3:40 AM, Richard Biener <rguenther@suse.de> wrote:
> 
> On Wed, 10 Aug 2022, Qing Zhao wrote:
> 
>> Hi,
>> 
>> As mentioned in the bug report, I reopened this bug since the previous patch:
>> 
>> commit r13-1875-gff26f0ba68fe6e870f315d0601b596f889b89680
>> Author: Richard Biener <rguenther@suse.de>
>> Date:   Thu Jul 28 10:07:32 2022 +0200
>> 
>>    middle-end/106457 - improve array_at_struct_end_p for array objects
>>    Array references to array objects are never at struct end.
>> 
>> 
>> Didn’t resolve this bug.
>> 
>> This is a new patch, and my current work on -fstrict-flex-array depends on this patch.
>> 
>> Please take a look at the patch and let me know whether it’s good for committing.
>> 
>> Thanks.
>> 
>> Qing.
>> 
>> 
>> ======================================
>> 
>> [PATCH] middle-end/106457 - improve array_at_struct_end_p for array
>> objects (PR106457)
>> 
>> Array references are not handled correctly by current array_at_struct_end_p,
>> for the following array references:
>> 
>> Example 1: (from gcc/testsuite/gcc.dg/torture/pr50067-[1|2].c):
>> 
>> short a[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
>>                 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
>> ... = (*((char(*)[32])&a[0]))[i+8];  // this array reference
> 
> For this one we have
> 
> (gdb) p debug_generic_expr (ref_to_array)
> MEM[(char[32] *)&a]
> 
> at the
> 
> 12782         if (DECL_P (ref_to_array))
> 
> check.  The array referenced (char[32]) isn't the decl (which is 
> short[32]), so the referenced array (char[32]) _is_ at struct end
> since accessing index 48 is OK - it won't exceed the decl boundary.

> In fact that -Waggressive-loop-optimizations triggers with your
> patch shows it is wrong in this case - the code is perfectly
> OK, no out-of-bound access occurs.  When this warning triggers it
> hints at the code being miscompiled (we usually elide the exit
> test).

Okay, I see. 
> 
>> Example 2: (from gcc/testsuite/gcc.target/aarch64/vadd_reduc-2.c):
>> 
>> int test (uint8_t *p, uint32_t t[1][1], int n) {
>>  for (int i = 0; i < 4; i++, p++)
>>    t[i][0] = ...;  // this array reference
>> ...
>> }
> 
> The parameter declaration uint32_t t[1][1] doesn't guarantee
> anything - it's just a pointer.  So we cannot reasonably
> constrain accesses to sizeof(uint32_t).  That means
> array_at_struct_end_p has to return true.

Okay.  Then again, the name of the routine “array_at_struct_end_p” is really confusing. -:)
> 
>> Example 3: (from gcc/testsuite/g++.dg/debug/debug5.C):
>> 
>>  int a = 1;
>>  int b = 1;
>>  int e[a][b];
>>  e[0][0] = 0;  // this array reference
> 
> That might be the only case we'd be allowed to say false.  I see
> a single call with
> 
> MEM[(int[0:D.1989][0:D.1986] *)&e.4][0]{lb: 0 sz: 4}
> 
> that is, the caller has stripped the outermost [0] already.
> The issue here is unfortunate lowering of the alloca
> with constant size we originally have here.  The array typed
> decl has type int[1] but we access it with type
> int[0:D.1989][0:D.1986].  We'd now have to prove that
> D.1989 and D.1986 are '1' (and not less).  That doesn't look
> possible in general.  Not sure if it is worth the trobble here.

Okay. 
> 
> Eventually array_at_struct_end_p isn't the correct vehicle for
> diagnostics if you desparately need to avoid 'true' for the above
> cases.  Note for the first case it's more about treating
> pointer to array with bounds in a stricter way than we do
> at the moment, not so much about arrays at struct end.  But
> array_at_struct_end_p is used to query whether we have to assume
> there's storage beyond the declared bound of an array that is
> "valid" to access (and it's valid from the middle-end point of
> view in this case).

Then, this is really NOT “array_at_struct_end_p”, it’s “array_is_flexible_p”, which mixes the concept of “array_at_struct_end” and array is flexible (or extendable).
I am Okay with the name right now in this patch, I will update the comments of this routine in the current patch. And update the name of the routine in a later cleanup patch.


Since the new FIELD DECL_NOT_FLEXARRAY for the patch -fstrict-flex-arrays:

+/* Used in a FIELD_DECL to indicate whether this field is not a flexible
+   array member.  */
+#define DECL_NOT_FLEXARRAY(NODE) \
+  (FIELD_DECL_CHECK (NODE)->decl_common.decl_not_flexarray)
+

Is ONLY for field in a structure, so it will NOT control the result for such flexible array access.  i.e, for all the flexible array access similar as in the Example 1, 2, or 3, 
They are always flexible,  -fstrict-flex-arrays should NOT control them, right?

Thanks

Qing

> 
> Richard.
> 
>> All the above array references are identified as TRUE by the current
>> array_at_struct_end_p, therefore treated as flexible array members.
>> Obviously, they are just simple array references, not an array refs
>> to the last field of a struture. The current array_at_struct_end_p handles
>> such array references incorrectly.
>> 
>> In order to handle array references correctly, we could recursively check
>> its first operand if it's a MEM_REF or COMPONENT_REF and stop as FALSE
>> when otherwise. This resolved all the issues for ARRAY_REF.
>> 
>> bootstrapped and regression tested on both X86 and Aarch64.
>> Multiple testing cases behave differently due to array_at_struct_end_p now
>> behave correctly (return FALSE now, then they are not flexible array member
>> anymore). Adjust these testing cases.
>> 
>> There is one regression for gcc/target/aarch64/vadd_reduc-2.c is left
>> unresolved since the loop transformation is changed due to the changed behavior
>> of array_at_struct_end_p, simple adjustment of the testing case doesnt work.
>> I will file a bug to record this regression.
>> 
>> gcc/ChangeLog:
>> 
>>        PR middle-end/106457
>>        * tree.cc (array_at_struct_end_p): Handle array objects recursively
>>        through its first operand.
>> 
>> gcc/testsuite/ChangeLog:
>> 
>>        PR middle-end/106457
>>        * gcc.dg/torture/pr50067-1.c: Add -Wno-aggressive-loop-optimizations
>>        to suppress warnings.
>>        * gcc.dg/torture/pr50067-2.c: Likewise.
>>        * gcc.target/aarch64/vadd_reduc-2.c: Likewise.
>>        * gcc.target/i386/pr104059.c: Likewise.
>> 
>> 
>> The complete patch is at:
>> 
>> 
>> 
> 
> -- 
> Richard Biener <rguenther@suse.de>
> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg,
> Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman;
> HRB 36809 (AG Nuernberg)


  reply	other threads:[~2022-08-11 13:26 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-10 21:39 Qing Zhao
2022-08-11  7:40 ` Richard Biener
2022-08-11 13:26   ` Qing Zhao [this message]
2022-08-12  6:46     ` Richard Biener

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=71C7EEA6-2D60-49F1-BB9C-8EDF98DEBAB6@oracle.com \
    --to=qing.zhao@oracle.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=rguenther@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).