Re: Can we vectorize the code below ?

2019-06-12 Thread Richard Biener
On Wed, Jun 12, 2019 at 5:22 AM Li Jia He  wrote:
>
> Hi,
>
> I recently did some analysis on the automatic vectorization of gcc, I
> found that singed char can not be vectorized in the following code.
>
> ---
> #define ITERATIONS 100
>
> #if defined(do_reduce_signed_char)
> #define TYPE signed char
> #elif defined(do_reduce_unsigned_char)
> #define TYPE unsigned char
> #else
> #error bad define
> #endif
>
> #define SIZE (16384/sizeof(TYPE))
>
> static TYPE x[SIZE] __attribute__ ((aligned (16)));
>
> void obfuscate(void *a, ...);
>
> static void __attribute__((noinline)) do_one(void)
> {
>  unsigned long i;
>  TYPE a = 0;
>
>  obfuscate(x);
>
>  for (i = 0; i < SIZE; i++)
>  a += x[i];
>
>  obfuscate(x, a);
> }
>
> int main(void)
> {
>  unsigned long i;
>
>  for (i = 0; i < ITERATIONS; i++)
>  do_one();
>
>  return 0;
> }
> ---
> If we use the following command line
>
> gcc reduce.c -Ddo_reduce_unsigned_char -Ofast -c -S -fdump-tree-vect-details
>
> We can see that this code can be vectorized under the unsigned char data
> type.
> If we use the following command
>
> gcc reduce.c -Ddo_reduce_signed_char -Ofast -c -S -fdump-tree-vect-details
>
> We can see that this code cannot be vectorized under the singed char
> data type.
> I found in the below code for singed char
> ---
> a += x[i];
> ---
> Will do something like the following conversion.
> ---
> a = (signed char) ((unsigned char) x[i] + (unsigned char) a);
> ---
> As a result, the reduction in the code cannot be effectively identified.
> Can we vectorize the code like the above when the data type is signed char ?

Probably another case of https://gcc.gnu.org/PR65930

Richard.

> Thanks,
> Lijia He
>


Re: Can we vectorize the code below ?

2019-06-12 Thread Kyrill Tkachov

Hi Lijia,

On 6/12/19 4:22 AM, Li Jia He wrote:

Hi,

I recently did some analysis on the automatic vectorization of gcc, I
found that singed char can not be vectorized in the following code.

---
#define ITERATIONS 100

#if defined(do_reduce_signed_char)
#define TYPE signed char
#elif defined(do_reduce_unsigned_char)
#define TYPE unsigned char
#else
#error bad define
#endif

#define SIZE (16384/sizeof(TYPE))

static TYPE x[SIZE] __attribute__ ((aligned (16)));

void obfuscate(void *a, ...);

static void __attribute__((noinline)) do_one(void)
{
 unsigned long i;
 TYPE a = 0;

 obfuscate(x);

 for (i = 0; i < SIZE; i++)
 a += x[i];

 obfuscate(x, a);
}

int main(void)
{
 unsigned long i;

 for (i = 0; i < ITERATIONS; i++)
 do_one();

 return 0;
}
---
If we use the following command line

gcc reduce.c -Ddo_reduce_unsigned_char -Ofast -c -S 
-fdump-tree-vect-details


We can see that this code can be vectorized under the unsigned char data
type.
If we use the following command

gcc reduce.c -Ddo_reduce_signed_char -Ofast -c -S -fdump-tree-vect-details

We can see that this code cannot be vectorized under the singed char
data type.
I found in the below code for singed char
---
a += x[i];
---
Will do something like the following conversion.
---
a = (signed char) ((unsigned char) x[i] + (unsigned char) a);
---
As a result, the reduction in the code cannot be effectively identified.
Can we vectorize the code like the above when the data type is signed 
char ?


This looks like the known limitation 
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65930


Thanks,

Kyrill




Thanks,
Lijia He



Re: Git 'gcc-9_1_0-release' tag vs. GCC 9.1 release: 'BASE-VER' difference

2019-06-12 Thread Thomas Schwinge
Hi!

On Tue, 11 Jun 2019 16:35:40 +0100, Jonathan Wakely  
wrote:
> On Tue, 11 Jun 2019 at 16:33, Jonathan Wakely  wrote:
> > On Tue, 11 Jun 2019 at 16:29, Thomas Schwinge  
> > wrote:
> > > On Tue, 11 Jun 2019 16:18:51 +0100, Jonathan Wakely 
> > >  wrote:
> > > > On Tue, 11 Jun 2019 at 16:13, Thomas Schwinge  
> > > > wrote:
> > > > > We have found that the Git 'gcc-9_1_0-release' tag doesn't correspond 
> > > > > to
> > > > > the actual GCC 9.1 release.  The GCC 9.1 release (as per 
> > > > > 'gcc-9.1.0.tar'
> > > > > as well as 'svn+ssh://gcc.gnu.org/svn/gcc/tags/gcc_9_1_0_release',
> > > > > r272156)
> > >
> > > (Eh, at the end of that 'svn co [...]', it printed that it "Checked out
> > > revision 272156", but the GCC 9.1 release actually is r270840, and
> > > r272156 is GCC trunk from a moment ago.)
> > >
> > > > > would correspond to Git commit
> > > > > 3defceaa1a2987fa90296abfbcc85d7e9ad59684 "Update ChangeLog and version
> > > > > files for release", but the Git 'gcc-9_1_0-release' tag points one 
> > > > > commit
> > > > > further: Git commit 1f54d412a517f3a4b82f3dd77517842fb4de099a 
> > > > > "BASE-VER:
> > > > > Set to 9.1.1".  (That's not a big problem; the 'BASE-VER' update is
> > > > > indeed the only difference.)
> > > >
> > > > That's probably my fault, I think I created the tag.
> > > >
> > > > > The Git tag can't be corrected now (would it make sense to push a Git
> > > > > 'gcc-9_1_0-release-corrected' tag?), but I wanted to post this, to 
> > > > > get it
> > > > > into the mighty Internet archives; may this note help others who 
> > > > > stumble
> > > > > over the same thing.
> > > >
> > > > Can't we just delete the tag and add it at the right commit?
> > >
> > > I don't think that'll be useful: as far as I remember (but please correct
> > > me if I'm wrong!), a 'git fetch' will not re-fetch changed tags, so

Right, see the "DISCUSSION" "On Re-tagging" in 'git tag --help'.

> > I think that's right, but 'git fetch --tags' would update it.

Sure, but who's running that?  ;-)

(We shall see if the GitHub etc. mirrors will pick up the updated tag
automatically.)

> > > different clones might then have different 'gcc-9_1_0-release' tags.
> >
> > Which doesn't seem like a problem to me.
> >
> > I could create a local tag with that name for any arbitrary revision.
> > It wouldn't match what's in everybody else's clone, but that's fine.
> 
> It seems to me that having the master repo have the correct tag is
> more valuable than everybody having the same tag.
> 
> And because, as you say, the difference is just one commit, it's not
> like doing diffs or other commands using the old value of the tag
> would look at a completely wrong branch or completely different
> histories.

Note that I'm not objecting to re-tagging.  (I had just proposed
'gcc-9_1_0-release-corrected' to make obvious what's going on.)

Is there sufficient consensus, or who's going to make a decision?


Grüße
 Thomas


Re: Can we vectorize the code below ?

2019-06-12 Thread Li Jia He




On 2019/6/12 4:04 PM, Richard Biener wrote:

On Wed, Jun 12, 2019 at 5:22 AM Li Jia He  wrote:


Hi,

I recently did some analysis on the automatic vectorization of gcc, I
found that singed char can not be vectorized in the following code.

---
#define ITERATIONS 100

#if defined(do_reduce_signed_char)
#define TYPE signed char
#elif defined(do_reduce_unsigned_char)
#define TYPE unsigned char
#else
#error bad define
#endif

#define SIZE (16384/sizeof(TYPE))

static TYPE x[SIZE] __attribute__ ((aligned (16)));

void obfuscate(void *a, ...);

static void __attribute__((noinline)) do_one(void)
{
  unsigned long i;
  TYPE a = 0;

  obfuscate(x);

  for (i = 0; i < SIZE; i++)
  a += x[i];

  obfuscate(x, a);
}

int main(void)
{
  unsigned long i;

  for (i = 0; i < ITERATIONS; i++)
  do_one();

  return 0;
}
---
If we use the following command line

gcc reduce.c -Ddo_reduce_unsigned_char -Ofast -c -S -fdump-tree-vect-details

We can see that this code can be vectorized under the unsigned char data
type.
If we use the following command

gcc reduce.c -Ddo_reduce_signed_char -Ofast -c -S -fdump-tree-vect-details

We can see that this code cannot be vectorized under the singed char
data type.
I found in the below code for singed char
---
a += x[i];
---
Will do something like the following conversion.
---
a = (signed char) ((unsigned char) x[i] + (unsigned char) a);
---
As a result, the reduction in the code cannot be effectively identified.
Can we vectorize the code like the above when the data type is signed char ?


Probably another case of https://gcc.gnu.org/PR65930

Richard.

Thanks to Kyrill and Richard, I have subscribed to this issue.



Thanks,
Lijia He







[Combine] Unusual behaviour in combine

2019-06-12 Thread Joel Hutton

Hi all,

This is a patch to demonstrate some unusual behavior I have encountered in 
combine.

A summary of the behaviour is:
when combining A -> B, the register equivalence notes of A are checked, the 
register notes of B are not checked.

Is this expected behaviour?

from combine.c:1484 in combine_instructions

      /* Try this insn with each REG_EQUAL note it links back to.  */
      FOR_EACH_LOG_LINK (links, insn)
    {
      rtx set, note;
      rtx_insn *temp = links->insn;
      if ((set = single_set (temp)) != 0
          && (note = find_reg_equal_equiv_note (temp)) != 0
          && (note = XEXP (note, 0), GET_CODE (note)) != EXPR_LIST

The register equivalance notes of temp are checked, but the register 
equivalence notes of insn are not checked.

To reproduce:
With the patch applied:

Compile the following function
void
bar (float *a, int *b)
{
  int i;
  for (i = 0; i < 1024; i++)
    a[i] = (((float)b[i])/ 4.0f);
}

Combine does not check the REG_EQUAL note on insn 12, and does not try the 
equivalent pattern, using a const_vector instead of register 99.

Trying 10 -> 12:
   10: r97:V4SF=float(r96:V4SI)
  REG_DEAD r96:V4SI
   12: r98:V4SF=r97:V4SF*r99:V4SF
  REG_DEAD r97:V4SF
  REG_EQUAL r97:V4SF*const_vector
Failed to match this instruction:
(set (reg:V4SF 98 [ D.3422 ])
    (mult:V4SF (float:V4SF (reg:V4SI 96 [ D.3420 ]))
    (reg:V4SF 99)))


For comparison, a similar pattern, in which the REG_EQUAL note is attached to 
the first insn, the REG_EQUAL note is checked, and the equivalent constant is 
used.

foo (float *a, int *b)
{
  int i;
  for (i = 0; i < 1024; i++)
    b[i] = a[i] * 4.0f;
}

Trying 11 -> 12:
   11: r97:V4SF=r96:V4SF*r98:V4SF
  REG_DEAD r96:V4SF
  REG_EQUAL r96:V4SF*const_vector
   12: r99:V4SI=fix(unspec[r97:V4SF] 23)
  REG_DEAD r97:V4SF
Failed to match this instruction:
(set (reg:V4SI 99 [ D.3432 ])
    (fix:V4SI (unspec:V4SI [
    (mult:V4SF (reg:V4SF 96 [ D.3430 ])
    (reg:V4SF 98))
    ] UNSPEC_FRINTZ)))

Trying 11 -> 12:
   11: r97:V4SF=r96:V4SF*const_vector
  REG_DEAD r96:V4SF
  REG_EQUAL r96:V4SF*const_vector
   12: r99:V4SI=fix(unspec[r97:V4SF] 23)
  REG_DEAD r97:V4SF
Successfully matched this instruction:
(set (reg:V4SI 99 [ D.3432 ])
    (fix:V4SI (unspec:V4SI [
    (mult:V4SF (reg:V4SF 96 [ D.3430 ])
    (const_vector:V4SF [
    (const_double:SF 4.0e+0 [0x0.8p+3]) repeated x4
    ]))
    ] UNSPEC_FRINTZ)))
    
Built from current trunk
$gcc -v
COLLECT_GCC=$BUILD/install/bin/aarch64-none-elf-gcc
COLLECT_LTO_WRAPPER=$BUILD/install/libexec/gcc/aarch64-none-elf/10.0.0/lto-wrapper
Target: aarch64-none-elf
Configured with: $SRC/gcc/configure --target=aarch64-none-elf 
--prefix=$BUILD/install/ --with-gmp=$BUILD/host-tools 
--with-mpfr=$BUILD/host-tools --with-mpc=$BUILD/host-tools 
--with-isl=$BUILD/host-tools --disable-shared --disable-nls --disable-threads 
--disable-tls --enable-checking=yes --enable-languages=c,c++,fortran 
--with-newlib --with-pkgversion=unknown
Thread model: single
gcc version 10.0.0 20190524 (experimental) (unknown)

Test cases compiled with:
aarch64-none-elf-gcc -S -mcpu=cortex-a53 -O2 tmp.c -ftree-vectorize -fno-inline 
-fdump-rtl-all -fno-vect-cost-model -dp -fdump-rtl-combine-all 
-fdump-tree-optimized -o -
From 7e744509575030ca5b3fa6042d02d27171fbfbfd Mon Sep 17 00:00:00 2001
From: Joel Hutton 
Date: Tue, 11 Jun 2019 10:10:07 +0100
Subject: [PATCH] Minimal pattern to demonstrate combine behaviour

---
 gcc/config/aarch64/aarch64-protos.h |  1 +
 gcc/config/aarch64/aarch64-simd.md  | 13 +
 gcc/config/aarch64/aarch64.c|  6 ++
 gcc/config/aarch64/predicates.md|  3 +++
 4 files changed, 23 insertions(+)

diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index a0723266f22..ff1787c37ed 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -483,6 +483,7 @@ enum aarch64_symbol_type aarch64_classify_tls_symbol (rtx);
 enum reg_class aarch64_regno_regclass (unsigned);
 int aarch64_asm_preferred_eh_data_format (int, int);
 int aarch64_fpconst_pow_of_2 (rtx);
+int aarch64_fp_const_vec (rtx);
 machine_mode aarch64_hard_regno_caller_save_mode (unsigned, unsigned,
 		   machine_mode);
 int aarch64_uxt_size (int, HOST_WIDE_INT);
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index d4c48d2aa61..698b49c006f 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -2133,6 +2133,19 @@
   "TARGET_SIMD"
   {})
 
+(define_insn "*aarch64_combine_scvtf"
+  [(set (match_operand 0 "register_operand" "=w")
+	(mult
+	 (float
+	  (match_operand 1 "" "w"))
+	 (match_operand 2 "aarch64_fp_const_vec" ""))
+	)]
+  ""
+  {
+return "test_match";
+  }
+)
+
 (define_insn "2"
   [(set (match_operand:VHSDF 0 "regi

[PATCH] Do not warn with warn_unused_result for alloca(0).

2019-06-12 Thread Martin Liška
On 6/11/19 6:03 PM, Jakub Jelinek wrote:
> On Tue, Jun 11, 2019 at 03:58:27PM +, Michael Matz wrote:
>> On Tue, 11 Jun 2019, Martin Liška wrote:
>>
>>> I see 3 occurrences of the alloca (0) in libiberty/regex.c, but there are 
>>> properly
>>> guarded within:
>>>
>>> # ifdef C_ALLOCA
>>>   alloca (0);
>>> # endif
>>>
>>> and then I noticed 2 more occurrences in gdb that break build right now:
>>>
>>> gdb/regcache.c:  alloca (0);
>>> gdb/top.c:  alloca (0);
>>>
>>> Is it the right approach to remove these 2 in gdb?
>>
>> It's more an indication that the annotation requesting the warning for 
>> unused results is simply overeager (aka wrong) for alloca.  (sure, the 
>> uses in gdb probably could be cleaned up as well, but that doesn't affect 
>> the wrongness of the warning).
> 
> Yeah.  Either we special-case alloca in the warn_unused_result code
> - if the call flags include ECF_MAY_BE_ALLOCA and argument is 0, don't warn,
> or don't add the attribute to alloca, or add yet another attribute that will
> be used for alloca only.
> 
>   Jakub
> 

Ok, I've got a patch for it.

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

Ready to be installed?
Thanks,
Martin
>From b659c00e54ff3bee736f502e7fa4dc233a814b66 Mon Sep 17 00:00:00 2001
From: Martin Liska 
Date: Wed, 12 Jun 2019 12:22:36 +0200
Subject: [PATCH] Do not warn with warn_unused_result for alloca(0).

gcc/ChangeLog:

2019-06-12  Martin Liska  

	* calls.c (special_function_p): Make it global.
	* calls.h (special_function_p): Declare.
	* tree-cfg.c (do_warn_unused_result): Do not
	warn for alloca(0).

gcc/testsuite/ChangeLog:

2019-06-12  Martin Liska  

	* gcc.dg/pr78902.c: Add testing of alloca(0).
	* gcc.dg/attr-alloc_size-5.c: Do not warn
	about alloca(0).
---
 gcc/calls.c  |  3 +--
 gcc/calls.h  |  1 +
 gcc/testsuite/gcc.dg/attr-alloc_size-5.c |  2 +-
 gcc/testsuite/gcc.dg/pr78902.c   |  1 +
 gcc/tree-cfg.c   | 16 
 5 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/gcc/calls.c b/gcc/calls.c
index c8a42680041..be9b2ff046a 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -153,7 +153,6 @@ static void compute_argument_addresses (struct arg_data *, rtx, int);
 static rtx rtx_for_function_call (tree, tree);
 static void load_register_parameters (struct arg_data *, int, rtx *, int,
   int, int *);
-static int special_function_p (const_tree, int);
 static int check_sibcall_argument_overlap_1 (rtx);
 static int check_sibcall_argument_overlap (rtx_insn *, struct arg_data *, int);
 
@@ -578,7 +577,7 @@ emit_call_1 (rtx funexp, tree fntree ATTRIBUTE_UNUSED, tree fndecl ATTRIBUTE_UNU
Set ECF_MAY_BE_ALLOCA for any memory allocation function that might allocate
space from the stack such as alloca.  */
 
-static int
+int
 special_function_p (const_tree fndecl, int flags)
 {
   tree name_decl = DECL_NAME (fndecl);
diff --git a/gcc/calls.h b/gcc/calls.h
index 128bb513074..0d2bc888b26 100644
--- a/gcc/calls.h
+++ b/gcc/calls.h
@@ -42,5 +42,6 @@ extern tree get_attr_nonstring_decl (tree, tree * = NULL);
 extern void maybe_warn_nonstring_arg (tree, tree);
 extern bool get_size_range (tree, tree[2], bool = false);
 extern rtx rtx_for_static_chain (const_tree, bool);
+extern int special_function_p (const_tree, int);
 
 #endif // GCC_CALLS_H
diff --git a/gcc/testsuite/gcc.dg/attr-alloc_size-5.c b/gcc/testsuite/gcc.dg/attr-alloc_size-5.c
index 7aa7cbf0c72..26ee43f87de 100644
--- a/gcc/testsuite/gcc.dg/attr-alloc_size-5.c
+++ b/gcc/testsuite/gcc.dg/attr-alloc_size-5.c
@@ -230,5 +230,5 @@ test_alloca (size_t n)
 {
   extern void* alloca (size_t);
 
-  alloca (0); /* { dg-warning "ignoring return value of '.*' declared with attribute 'warn_unused_result'" } */
+  alloca (0);
 }
diff --git a/gcc/testsuite/gcc.dg/pr78902.c b/gcc/testsuite/gcc.dg/pr78902.c
index 49efc970475..f0f4314d684 100644
--- a/gcc/testsuite/gcc.dg/pr78902.c
+++ b/gcc/testsuite/gcc.dg/pr78902.c
@@ -7,6 +7,7 @@ void foo(void)
  __builtin_malloc (1); /* { dg-warning "ignoring return value of '__builtin_malloc' declared with attribute 'warn_unused_result'" } */
  __builtin_calloc (10, 20); /* { dg-warning "ignoring return value of '__builtin_calloc' declared with attribute 'warn_unused_result'" } */
  __builtin_alloca (10); /* { dg-warning "ignoring return value of '__builtin_alloca' declared with attribute 'warn_unused_result'" } */
+ __builtin_alloca (0);
  __builtin_realloc (ptr, 100); /* { dg-warning "ignoring return value of '__builtin_realloc' declared with attribute 'warn_unused_result'" } */
  __builtin_aligned_alloc (10, 16); /* { dg-warning "ignoring return value of '__builtin_aligned_alloc' declared with attribute 'warn_unused_result'" } */
  __builtin_strdup ("pes"); /* { dg-warning "ignoring return value of '__builtin_strdup' declared with attribute 'warn_unused_result'" } */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index a585efea3d

Re: [PATCH] Do not warn with warn_unused_result for alloca(0).

2019-06-12 Thread Jakub Jelinek
On Wed, Jun 12, 2019 at 01:11:09PM +0200, Martin Liška wrote:
> 2019-06-12  Martin Liska  
> 
>   * calls.c (special_function_p): Make it global.
>   * calls.h (special_function_p): Declare.

Why?

>   * tree-cfg.c (do_warn_unused_result): Do not
>   warn for alloca(0).
> --- a/gcc/tree-cfg.c
> +++ b/gcc/tree-cfg.c
> @@ -63,6 +63,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "opts.h"
>  #include "asan.h"
>  #include "profile.h"
> +#include "calls.h"
>  
>  /* This file contains functions for building the Control Flow Graph (CFG)
> for a function tree.  */
> @@ -9447,10 +9448,17 @@ do_warn_unused_result (gimple_seq seq)
> location_t loc = gimple_location (g);
>  
> if (fdecl)
> - warning_at (loc, OPT_Wunused_result,
> - "ignoring return value of %qD "
> - "declared with attribute %",
> - fdecl);
> + {
> +   if ((special_function_p (fdecl, 0) & ECF_MAY_BE_ALLOCA)

Why not instead gimple_maybe_alloca_call_p (g) ?
On the other side, you want && gimple_call_num_args (g) == 1,
if some alloca call had wrong declaration, you might ICE otherwise.

> +   && TREE_CODE (gimple_call_arg (g, 0)) == INTEGER_CST
> +   && wi::to_wide (gimple_call_arg (g, 0)) == 0)

&& integer_zerop (gimple_call_arg (g, 0))

instead?

Plus you need a comment explaining why we don't warn about alloca with
constant 0 argument.

Jakub


Re: [PATCH] Do not warn with warn_unused_result for alloca(0).

2019-06-12 Thread Martin Liška
On 6/12/19 1:22 PM, Jakub Jelinek wrote:
> On Wed, Jun 12, 2019 at 01:11:09PM +0200, Martin Liška wrote:
>> 2019-06-12  Martin Liska  
>>
>>  * calls.c (special_function_p): Make it global.
>>  * calls.h (special_function_p): Declare.
> 
> Why?

Not needed any longer.

> 
>>  * tree-cfg.c (do_warn_unused_result): Do not
>>  warn for alloca(0).
>> --- a/gcc/tree-cfg.c
>> +++ b/gcc/tree-cfg.c
>> @@ -63,6 +63,7 @@ along with GCC; see the file COPYING3.  If not see
>>  #include "opts.h"
>>  #include "asan.h"
>>  #include "profile.h"
>> +#include "calls.h"
>>  
>>  /* This file contains functions for building the Control Flow Graph (CFG)
>> for a function tree.  */
>> @@ -9447,10 +9448,17 @@ do_warn_unused_result (gimple_seq seq)
>>location_t loc = gimple_location (g);
>>  
>>if (fdecl)
>> -warning_at (loc, OPT_Wunused_result,
>> -"ignoring return value of %qD "
>> -"declared with attribute %",
>> -fdecl);
>> +{
>> +  if ((special_function_p (fdecl, 0) & ECF_MAY_BE_ALLOCA)
> 
> Why not instead gimple_maybe_alloca_call_p (g) ?

Because I was not aware of the function ;)

> On the other side, you want && gimple_call_num_args (g) == 1,

Sure.

> if some alloca call had wrong declaration, you might ICE otherwise.
> 
>> +  && TREE_CODE (gimple_call_arg (g, 0)) == INTEGER_CST
>> +  && wi::to_wide (gimple_call_arg (g, 0)) == 0)
> 
> && integer_zerop (gimple_call_arg (g, 0))
> 
> instead?

Yep.

> 
> Plus you need a comment explaining why we don't warn about alloca with
> constant 0 argument.

Also done.

Is it fine now?
Martin

> 
>   Jakub
> 

>From dfdb688206cadd7fb9450ba005e8aa465ae61f7e Mon Sep 17 00:00:00 2001
From: Martin Liska 
Date: Wed, 12 Jun 2019 12:22:36 +0200
Subject: [PATCH] Do not warn with warn_unused_result for alloca(0).

gcc/ChangeLog:

2019-06-12  Martin Liska  

	* tree-cfg.c (do_warn_unused_result): Do not
	warn for alloca(0) as it's used by some C
	libraries to release previously allocated memory
	via alloca calls.

gcc/testsuite/ChangeLog:

2019-06-12  Martin Liska  

	* gcc.dg/pr78902.c: Add testing of alloca(0).
	* gcc.dg/attr-alloc_size-5.c: Do not warn
	about alloca(0).
---
 gcc/testsuite/gcc.dg/attr-alloc_size-5.c |  2 +-
 gcc/testsuite/gcc.dg/pr78902.c   |  1 +
 gcc/tree-cfg.c   | 18 ++
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/attr-alloc_size-5.c b/gcc/testsuite/gcc.dg/attr-alloc_size-5.c
index 7aa7cbf0c72..26ee43f87de 100644
--- a/gcc/testsuite/gcc.dg/attr-alloc_size-5.c
+++ b/gcc/testsuite/gcc.dg/attr-alloc_size-5.c
@@ -230,5 +230,5 @@ test_alloca (size_t n)
 {
   extern void* alloca (size_t);
 
-  alloca (0); /* { dg-warning "ignoring return value of '.*' declared with attribute 'warn_unused_result'" } */
+  alloca (0);
 }
diff --git a/gcc/testsuite/gcc.dg/pr78902.c b/gcc/testsuite/gcc.dg/pr78902.c
index 49efc970475..f0f4314d684 100644
--- a/gcc/testsuite/gcc.dg/pr78902.c
+++ b/gcc/testsuite/gcc.dg/pr78902.c
@@ -7,6 +7,7 @@ void foo(void)
  __builtin_malloc (1); /* { dg-warning "ignoring return value of '__builtin_malloc' declared with attribute 'warn_unused_result'" } */
  __builtin_calloc (10, 20); /* { dg-warning "ignoring return value of '__builtin_calloc' declared with attribute 'warn_unused_result'" } */
  __builtin_alloca (10); /* { dg-warning "ignoring return value of '__builtin_alloca' declared with attribute 'warn_unused_result'" } */
+ __builtin_alloca (0);
  __builtin_realloc (ptr, 100); /* { dg-warning "ignoring return value of '__builtin_realloc' declared with attribute 'warn_unused_result'" } */
  __builtin_aligned_alloc (10, 16); /* { dg-warning "ignoring return value of '__builtin_aligned_alloc' declared with attribute 'warn_unused_result'" } */
  __builtin_strdup ("pes"); /* { dg-warning "ignoring return value of '__builtin_strdup' declared with attribute 'warn_unused_result'" } */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index a585efea3d8..0d21f3624d7 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -63,6 +63,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "opts.h"
 #include "asan.h"
 #include "profile.h"
+#include "calls.h"
 
 /* This file contains functions for building the Control Flow Graph (CFG)
for a function tree.  */
@@ -9447,10 +9448,19 @@ do_warn_unused_result (gimple_seq seq)
 	  location_t loc = gimple_location (g);
 
 	  if (fdecl)
-		warning_at (loc, OPT_Wunused_result,
-			"ignoring return value of %qD "
-			"declared with attribute %",
-			fdecl);
+		{
+		  /* Some C libraries use alloca(0) in order to free previously
+		 allocated memory by alloca calls.  */
+		  if (gimple_maybe_alloca_call_p (g)
+		  && gimple_call_num_args (g) == 1
+		  && integer_zerop (gimple_call_arg (g, 0)))
+		;
+		  else
+		warning

Re: [PATCH] Do not warn with warn_unused_result for alloca(0).

2019-06-12 Thread Jakub Jelinek
On Wed, Jun 12, 2019 at 01:30:14PM +0200, Martin Liška wrote:
> @@ -9447,10 +9448,19 @@ do_warn_unused_result (gimple_seq seq)
> location_t loc = gimple_location (g);
>  
> if (fdecl)
> - warning_at (loc, OPT_Wunused_result,
> - "ignoring return value of %qD "
> - "declared with attribute %",
> - fdecl);
> + {
> +   /* Some C libraries use alloca(0) in order to free previously
> +  allocated memory by alloca calls.  */
> +   if (gimple_maybe_alloca_call_p (g)
> +   && gimple_call_num_args (g) == 1
> +   && integer_zerop (gimple_call_arg (g, 0)))
> + ;
> +   else

Wouldn't it be easier to negate the condition and avoid the weird ; else ?
I.e. if (!gimple_maybe... || gimple_call_num != 1 || !integer_zerop?

> + warning_at (loc, OPT_Wunused_result,
> + "ignoring return value of %qD declared "
> + "with attribute %",
> + fdecl);
> + }
> else
>   warning_at (loc, OPT_Wunused_result,
>   "ignoring return value of function "

Otherwise LGTM as the patch, but I'd like to hear from others whether
it is kosher to add such a special case to the warn_unused_result attribute
warning.  And if the agreement is yes, I think it should be documented
somewhere that alloca (0) will not warn even when the call has such an
attribute (probably in the description of warn_unused_result attribute).

Jakub


Re: Committing patches and other conventions (Was: Re: About GSOC)

2019-06-12 Thread Tejas Joshi
Hello.
Is this the correct sequence for regression test:
1. Revert back all the changes I made and then configure, build along with
make bootstrap
make -k check
collect the *.sum files
2. Apply the patch and do the configuration, build as above 1 and then
collect the *.sum files and compare them.

How do I collect and inspect these *.sum files?

Thanks,
-Tejas

On Thu, 6 Jun 2019 at 22:26, Martin Jambor  wrote:
>
> Hi,
>
> On Mon, Jun 03 2019, Tejas Joshi wrote:
> > Hello.
> > I have already sent a patch for roundeven implementation but I do not
> > know how do I commit my changes to GCC. Am I supposed to create a
> > branch or anything etc?
>
> You don't have to create a branch unless you think it would make ease
> your own workflow.  Once a patch is ready to go and has been explicitely
> approved by a corresponding maintainer, you will be expected to commit
> it directly to svn (we'll ask for a svn write access for you when we get
> to that point).  You'll find the list of maintainers in the MAINTAINERS
> file of the gcc repository, I believe your patches will need approval
> from a global reviewer, most probably Joseph.
>
> Before that happens, the code must be of course considered correct but
> also must adhere to some conventions, please see
> https://gcc.gnu.org/codingconventions.html.  Your patches so far lacked
> a ChangeLog and testcases.  Have a look at what other do when they post
> patches to gcc-patches: https://gcc.gnu.org/ml/gcc-patches/2019-06/
>
> ChangeLog has to have the given, fairly strict format, but should be
> very brief.  When posting patches, you don't make it part of the patch
> even though when committing, you are expected it to prepend the
> corresponding ChangeLog file with your bit (see e.g. gcc/ChangeLog and
> gcc/testsuite/ChangeLog).
>
> You have always stated how you tested your patches but you are actually
> supposed to add the testsuite and committed along with the functional
> patch, so that other can then test they do not regress on the
> functionality you have just added.
>
> That is why everybody including you has to test their patches also by
> doing:
>
> make bootstrap
> make -k check
>
> (with a -j level appropriate for your computer) and then collect *.sum
> files from unpatched and patched runs and compare them (see script in
> contrib/compare_tests) to make sure they did not introduce any
> regressions.
>
> See section on "Testing patches" at https://gcc.gnu.org/contribute.html
> for more details.
>
> Please ask about these mechanisms and conventions if anything is not
> clear.  I'll go and find the latest version of your roundeven patch and
> see if I can help you a little (but I am likely to finish that only
> tomorrow morning).
>
> Thanks,
>
> Martin


Re: [PATCH] Do not warn with warn_unused_result for alloca(0).

2019-06-12 Thread Martin Sebor

On 6/12/19 5:37 AM, Jakub Jelinek wrote:

On Wed, Jun 12, 2019 at 01:30:14PM +0200, Martin Liška wrote:

@@ -9447,10 +9448,19 @@ do_warn_unused_result (gimple_seq seq)
  location_t loc = gimple_location (g);
  
  	  if (fdecl)

-   warning_at (loc, OPT_Wunused_result,
-   "ignoring return value of %qD "
-   "declared with attribute %",
-   fdecl);
+   {
+ /* Some C libraries use alloca(0) in order to free previously
+allocated memory by alloca calls.  */
+ if (gimple_maybe_alloca_call_p (g)
+ && gimple_call_num_args (g) == 1
+ && integer_zerop (gimple_call_arg (g, 0)))
+   ;
+ else


Wouldn't it be easier to negate the condition and avoid the weird ; else ?
I.e. if (!gimple_maybe... || gimple_call_num != 1 || !integer_zerop?


+   warning_at (loc, OPT_Wunused_result,
+   "ignoring return value of %qD declared "
+   "with attribute %",
+   fdecl);
+   }
  else
warning_at (loc, OPT_Wunused_result,
"ignoring return value of function "


Otherwise LGTM as the patch, but I'd like to hear from others whether
it is kosher to add such a special case to the warn_unused_result attribute
warning.  And if the agreement is yes, I think it should be documented
somewhere that alloca (0) will not warn even when the call has such an
attribute (probably in the description of warn_unused_result attribute).


I'm not very happy about adding another special case to alloca
(on top of not diagnosing zero allocation by -Walloc-zero).
There is no valid use case for the zero argument, whether or not
the return value is used.  When it is used it's just as dangerous
as allocating a zero-length VLA.  When it isn't used the call is
pointless entirely, and although it might be harmless, it's worth
removing from code just like any other pointless construct GCC
warns about.  So I would prefer not to suppress this warning (from
what I've read in the GDB bug it sounds like its calls to alloca(0)
are being removed).  I would also prefer to re-enable -Walloc-zero
for alloca(0).

But if there is insufficient support for this I agree that
documenting the built-ins GCC applies attribute warn_unused_result
to is a good idea.  (In fact, documenting all the attributes GCC
applies to each built-in would be helpful, but that's a much bigger
project.)

Martin


Re: [PATCH] Do not warn with warn_unused_result for alloca(0).

2019-06-12 Thread Michael Matz
Hi,

On Wed, 12 Jun 2019, Martin Sebor wrote:

> > Otherwise LGTM as the patch, but I'd like to hear from others whether 
> > it is kosher to add such a special case to the warn_unused_result 
> > attribute warning.  And if the agreement is yes, I think it should be 
> > documented somewhere that alloca (0) will not warn even when the call 
> > has such an attribute (probably in the description of 
> > warn_unused_result attribute).
> 
> I'm not very happy about adding another special case to alloca
> (on top of not diagnosing zero allocation by -Walloc-zero).
> There is no valid use case for the zero argument, whether or not
> the return value is used.

That's the thing, there _is_ a valid use case for supplying a zero 
argument and then the returned value should _not_ be used.  There are 
alloca implementations that do something (freeing memory) when 
called with a zero size, so some (older) programs contain such calls.  
Warning on those calls for the unused results is exactly the wrong thing 
to do, if anything if the result is used we'd have to warn.  (That's of 
course non-standard, but so is alloca itself)  And just removing these 
calls isn't correct either except if it's ensured to not use an alloca 
implementation with that behaviour.

(In fact I think our builtin_alloca implementation could benefit when we 
added that behaviour as well; it's a natural wish to be able to free 
memory that you allocated).


Ciao,
Michael.


Re: [PATCH] Do not warn with warn_unused_result for alloca(0).

2019-06-12 Thread Martin Sebor

On 6/12/19 9:25 AM, Michael Matz wrote:

Hi,

On Wed, 12 Jun 2019, Martin Sebor wrote:


Otherwise LGTM as the patch, but I'd like to hear from others whether
it is kosher to add such a special case to the warn_unused_result
attribute warning.  And if the agreement is yes, I think it should be
documented somewhere that alloca (0) will not warn even when the call
has such an attribute (probably in the description of
warn_unused_result attribute).


I'm not very happy about adding another special case to alloca
(on top of not diagnosing zero allocation by -Walloc-zero).
There is no valid use case for the zero argument, whether or not
the return value is used.


That's the thing, there _is_ a valid use case for supplying a zero
argument and then the returned value should _not_ be used.  There are
alloca implementations that do something (freeing memory) when
called with a zero size, so some (older) programs contain such calls.
Warning on those calls for the unused results is exactly the wrong thing
to do, if anything if the result is used we'd have to warn.  (That's of
course non-standard, but so is alloca itself)  And just removing these
calls isn't correct either except if it's ensured to not use an alloca
implementation with that behaviour.


But GCC doesn't support such an implementation, does it?  The only
way to use such an alloca is with -fno-builtin-alloca which should
suppress the warning.

The Linux man page highlights this and the risks of defining one's
own alloca function:

  http://man7.org/linux/man-pages/man3/alloca.3.html

In any event, the warning, just like all others, exists to help
catch common mistakes: "constructions that are not inherently
erroneous but that are risky or suggest there may have been
an error".  It's not meant to accommodate every conceivable
corner case or oddball implementation.  Users of those can
easily disable the warning #pragma GCC diagnostic.  Doing that
makes the intent explicit both to the compiler and to other
tools and programmers.

Martin



(In fact I think our builtin_alloca implementation could benefit when we
added that behaviour as well; it's a natural wish to be able to free
memory that you allocated).


Ciao,
Michael.





Re: [PATCH] Do not warn with warn_unused_result for alloca(0).

2019-06-12 Thread Jakub Jelinek
On Wed, Jun 12, 2019 at 10:13:57AM -0600, Martin Sebor wrote:
> But GCC doesn't support such an implementation, does it?

Why would that be relevant?  The warning would cause people to make portable
code less portable (by removing the alloca (0) calls that were added there
for portability reasons), or add hacks to work around the warning (whether
#pragma GCC diagnostic or something else).  That is something we do not
want people to do.

Jakub


Re: Preventing ISO C errors when using macros for builtin types

2019-06-12 Thread Jozef Lawrynowicz
On Tue, 11 Jun 2019 18:01:55 -0500
Segher Boessenkool  wrote:
> On Tue, Jun 11, 2019 at 09:44:30PM +0100, Jozef Lawrynowicz wrote:
> > --- a/gcc/lto/lto-lang.c
> > +++ b/gcc/lto/lto-lang.c
> > @@ -1260,9 +1260,9 @@ lto_build_c_type_nodes (void)
> > if (int_n_enabled_p[i])
> >   {
> > char name[50];
> > -   sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
> > +   sprintf (name, "int%d", int_n_data[i].bitsize);
> >  
> > -   if (strcmp (name, SIZE_TYPE) == 0)
> > +   if (strstr (SIZE_TYPE, name) != NULL)
> >   {
> > intmax_type_node = int_n_trees[i].signed_type;
> > uintmax_type_node = int_n_trees[i].unsigned_type;  
> 
> I don't think that is correct, strstr allows too much?  If you want to
> allow some variants, you should test for all those variants exactly?

Yeah I'll fix this up in my full patch submission.

> It looks great otherwise :-)
> 
> 
> Segher

Great, thanks for all your help!

Jozef


Re: [PATCH] Do not warn with warn_unused_result for alloca(0).

2019-06-12 Thread Martin Sebor

On 6/12/19 10:40 AM, Jakub Jelinek wrote:

On Wed, Jun 12, 2019 at 10:13:57AM -0600, Martin Sebor wrote:

But GCC doesn't support such an implementation, does it?


Why would that be relevant?


Obviously because it makes no sense to cater to all conceivable
extensions provided by all sorts of implementations out there.

There are libc implementations out there that accept null pointer
arguments to functions like memcpy with zero sizes, for example.
Or those that accept overlapping objects in calls to strcpy.  GCC
itself handles those gracefully, yet warns for such constructs
nonetheless.  It's useful because those misuses are likely hidden
bugs, even if they don't always manifest themselves.


The warning would cause people to make portable
code less portable (by removing the alloca (0) calls that were added there
for portability reasons), or add hacks to work around the warning (whether
#pragma GCC diagnostic or something else).  That is something we do not
want people to do.


You asked for input and I gave it to you.  If your mind was already
made up and you're only willing to accept feedback that agrees with
your view, don't ask.

Martin


Re: About GSOC.

2019-06-12 Thread Tejas Joshi
Hello.

> I don't think you should have the unreachable "return false;" in is_even.
> The last "else if" can just be "else".

I don't think return false in is_even is unreachable. As per my
understanding, when one else if is true in the else if ladder, all the
subsequent "else ifs" including "else" are ignored. When REAL_EXP is
less than SIGNIFICAND_BITS, but the number is odd, the inner "if" for
even-odd will not return true in which case should return false. That
case will ignore next "else if" and will reach return false.

> Suppose REAL_EXP (r) > SIGNIFICAND_BITS.  Then the number is definitely
> even, so you should return true, not false.

for this condition, else if can be modified to just else and return true.
PATCH:

gcc/ChangeLog:

2019-06-12  Tejas Joshi  

* builtins.c (mathfn_built_in_2): Added CASE_MATHFN for ROUNDEVEN.
* builtins.def: Added function definitions for roundeven function
variants.
* fold-const-call.c (fold_const_call_ss): Added case for function
call and fold_const_conversion call for roundeven function.
* fold-const.c (negate_mathfn_p): Added case for roundeven function.
(tree_call_nonnegative_warnv_p): Added case for roundeven function.
(integer_valued_real_call_p): Added case for roundeven function.
* real.c (is_even): New function. Returns true if real number is
even, otherwise returns false.
(is_halfway_below): New function. Returns true if real number is
halfway between two integers, else return false.
(real_roundeven): New function. Round real number to nearest
integer, rounding halfway cases towards even.
* real.h (real_value): Added descriptive comments.
Added function declaration for roundeven function.

gcc/testsuite/ChangeLog:

2019-06-12  Tejas Joshi  

* gcc.dg/torture/builtin-round-roundeven.c: New test.
* gcc.dg/torture/builtin-round-roundevenf128.c: New test.



On Tue, 11 Jun 2019 at 01:56, Joseph Myers  wrote:
>
> On Sun, 9 Jun 2019, Tejas Joshi wrote:
>
> > Hello.
> > I have created another patch which addresses the above points,
> > attached herewith.
>
> I don't think you should have the unreachable "return false;" in is_even.
> The last "else if" can just be "else".
>
> > > a conditional with < not <=; if REAL_EXP (r) == SIGNIFICAND_BITS, the
> > > least significant bit has value 1 and the number must be an integer).
> >
> > The number is integer because of the whole word spaces is occupied by
> > integer part?
> > Also, why would the least significant bit will have value 1 if
> > REAL_EXP (r) == SIGNIFICAND_BITS, as it only concerns with 2^0th
> > position (even or odd)?
>
> My understanding is that the significand is, as per the comments in
> real.c, in the range [0.5, 1.0).  There are SIGNIFICAND_BITS bits.  The
> bit above the most significant one has value 2^REAL_EXP.  The most
> significant one has value 2^(REAL_EXP-1).  The least significant one has
> value 2^(REAL_EXP-SIGNIFICAND_BITS).  If REAL_EXP == SIGNIFICAND_BITS,
> that means the least significant bit has value 2^0 = 1, and there are no
> bits with value 0.5 or below, so the number is an integer.
>
> --
> Joseph S. Myers
> jos...@codesourcery.com
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 3463ffb1539..85a945877a4 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -2085,6 +2085,7 @@ mathfn_built_in_2 (tree type, combined_fn fn)
 CASE_MATHFN (REMQUO)
 CASE_MATHFN_FLOATN (RINT)
 CASE_MATHFN_FLOATN (ROUND)
+CASE_MATHFN (ROUNDEVEN)
 CASE_MATHFN (SCALB)
 CASE_MATHFN (SCALBLN)
 CASE_MATHFN (SCALBN)
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 6d41bdb4f44..8bb7027aac7 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -542,12 +542,18 @@ DEF_C99_BUILTIN(BUILT_IN_RINTL, "rintl", BT_FN_LONGDOUBLE_LONGDOUBLE, AT
 #define RINT_TYPE(F) BT_FN_##F##_##F
 DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_RINT, "rint", RINT_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
 #undef RINT_TYPE
+DEF_EXT_LIB_BUILTIN(BUILT_IN_ROUNDEVEN, "roundeven", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_EXT_LIB_BUILTIN(BUILT_IN_ROUNDEVENF, "roundevenf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_EXT_LIB_BUILTIN(BUILT_IN_ROUNDEVENL, "roundevenl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN(BUILT_IN_ROUND, "round", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN(BUILT_IN_ROUNDF, "roundf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN(BUILT_IN_ROUNDL, "roundl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 #define ROUND_TYPE(F) BT_FN_##F##_##F
 DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_ROUND, "round", ROUND_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
 #undef ROUND_TYPE
+#define ROUNDEVEN_TYPE(F) BT_FN_##F##_##F
+DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_ROUNDEVEN, "roundeven", ROUNDEVEN_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#undef ROUNDEVEN_TYPE
 DEF_EXT_LIB_BUILTIN(BUILT_IN_SCALB, "scal

gcc: -ftest-coverage and -auxbase

2019-06-12 Thread David.Taylor
When doing a build, we use a pipe between GCC and GAS.
And because we wish to do some analysis of the assembly code,
we do not use -pipe but instead do '-S -c -'.  And this has worked
fine for many years.

I was recently looking into collecting some coverage information.
To that end, I added --coverage to the invocation line.  And it slowed
things down by more than an order of magnitude!

Investigating, it appears that the problem is the writing of the GCNO
files.

We do our builds on a build cluster with a lot of parallelism.
With the result that a dozen machines are each doing a bunch
of writes to the file '-.gcno' in an NFS mounted directory.

Rather than have a full, not incremental, build take 5-10 minutes,
It takes 4 hours.  And rather than have each of several thousand
compiles produce their own GCNO file, they all get overwritten...

Grep'ing around, I found '-auxbase'.  If I correctly understand it,
when compiling

some/path/name.c

into

bin/some-product/some/path/name.o,

I could simply say

-auxbase $(@:%.o=%)

The problem is that in common.opt, auxbase is marked RejectDriver.

It looks like removing it would some my problem.  Anyone have a reason
why removing that would be a bad idea?  Or have a different solution?

Thanks.

David