distinguishing gcc compilation valgrind false positives

2021-11-24 Thread Zdenek Sojka via Gcc
Hello,

from time to time, I come upon a testcase that failed during the automated
runs, but passes during reduction; there are valgrind warnings present, 
however. How do I distinguish what warnings are valid and which are false 
positives? Is there any way gcc could prevent generating the false
positives?

The compiler is configured as:
$ x86_64-pc-linux-gnu-gcc -v
Using built-in specs.
COLLECT_GCC=/repo/gcc-trunk/binary-latest-amd64/bin/x86_64-pc-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/repo/gcc-trunk/binary-trunk-r12-5505-20211124090307-g5
deacf6058d-checking-yes-rtl-df-extra-nobootstrap-amd64/bin/../libexec/gcc/x
86_64-pc-linux-gnu/12.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /repo/gcc-trunk//configure --enable-languages=c,c++ --
enable-valgrind-annotations --disable-nls --enable-checking=yes,rtl,df,extra
--disable-bootstrap --with-cloog --with-ppl --with-isl --build=x86_64-pc-
linux-gnu --host=x86_64-pc-linux-gnu --target=x86_64-pc-linux-gnu --with-ld=
/usr/bin/x86_64-pc-linux-gnu-ld --with-as=/usr/bin/x86_64-pc-linux-gnu-as --
disable-libstdcxx-pch --prefix=/repo/gcc-trunk//binary-trunk-r12-5505-
20211124090307-g5deacf6058d-checking-yes-rtl-df-extra-nobootstrap-amd64
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.0.0 20211124 (experimental) (GCC)


The output is:

$ x86_64-pc-linux-gnu-gcc `cat flags` -c -w mcf.ii -wrapper valgrind,-q,--
track-origins=yes
==5404== Invalid read of size 4
==5404==    at 0x197B210: put (hash-map.h:179)
==5404==    by 0x197B210: void copy_warning
(tree_node*, tree_node const*) (warning-control.cc:209)
==5404==    by 0xE40CB6: cp_fold(tree_node*) (cp-gimplify.c:2837)
==5404==    by 0xE413A9: cp_fold(tree_node*) (cp-gimplify.c:2679)
==5404==    by 0xE42BAC: cp_fold_maybe_rvalue(tree_node*, bool) (cp-
gimplify.c:2186)
==5404==    by 0xE408C5: cp_fold(tree_node*) (cp-gimplify.c:2501)
==5404==    by 0xE42BAC: cp_fold_maybe_rvalue(tree_node*, bool) (cp-
gimplify.c:2186)
==5404==    by 0xE410DD: cp_fold_rvalue (cp-gimplify.c:2209)
==5404==    by 0xE410DD: cp_fold(tree_node*) (cp-gimplify.c:2568)
==5404==    by 0xE42BAC: cp_fold_maybe_rvalue(tree_node*, bool) (cp-
gimplify.c:2186)
==5404==    by 0xEA8B34: fold_for_warn(tree_node*) (expr.c:418)
==5404==    by 0x103F890: maybe_warn_about_returning_address_of_local
(typeck.c:9994)
==5404==    by 0x103F890: check_return_expr(tree_node*, bool*) (typeck.c:
10657)
==5404==    by 0xFEC75F: finish_return_stmt(tree_node*) (semantics.c:1193)
==5404==    by 0xF4DCEE: cp_parser_jump_statement (parser.c:14198)
==5404==    by 0xF4DCEE: cp_parser_statement(cp_parser*, tree_node*, bool,
bool*, vec*, unsigned int*) (parser.c:12200)
==5404==  Address 0x572ca94 is in a rw- anonymous segment
==5404==
==5404== Invalid read of size 4
==5404==    at 0x197B210: put (hash-map.h:179)
==5404==    by 0x197B210: void copy_warning
(tree_node*, tree_node const*) (warning-control.cc:209)
==5404==    by 0x12B2343: fold_truth_not_expr(unsigned int, tree_node*)
(fold-const.c:4288)
==5404==    by 0x12A4B51: fold_unary_loc(unsigned int, tree_code, tree_
node*, tree_node*) (fold-const.c:9560)
==5404==    by 0x12B2F6E: fold_build1_loc (fold-const.c:13728)
==5404==    by 0x12B2F6E: invert_truthvalue_loc (fold-const.c:4425)
==5404==    by 0x12B2F6E: invert_truthvalue_loc(unsigned int, tree_node*)
(fold-const.c:4419)
==5404==    by 0x1032CC2: cp_build_unary_op(tree_code, tree_node*, bool,
int) (typeck.c:7007)
==5404==    by 0xDE05F2: build_new_op(op_location_t const&, tree_code, int,
tree_node*, tree_node*, tree_node*, tree_node**, int) (call.c:6912)
==5404==    by 0x10314C6: build_x_unary_op(unsigned int, tree_code, cp_expr,
int) (typeck.c:6433)
==5404==    by 0xFF09D1: finish_unary_op_expr(unsigned int, tree_code, cp_
expr, int) (semantics.c:3044)
==5404==    by 0xF6AB9B: cp_parser_unary_expression(cp_parser*, cp_id_kind*,
bool, bool, bool) (parser.c:8900)
==5404==    by 0xF3B14A: cp_parser_binary_expression(cp_parser*, bool, bool,
bool, cp_parser_prec, cp_id_kind*) (parser.c:9925)
==5404==    by 0xF3BA7C: cp_parser_assignment_expression(cp_parser*, cp_id_
kind*, bool, bool) (parser.c:10229)
==5404==    by 0xF3D592: cp_parser_expression(cp_parser*, cp_id_kind*, bool,
bool, bool) (parser.c:10399)
==5404==  Address 0x5857ee4 is in a rw- anonymous segment
==5404==
==5404== Conditional jump or move depends on uninitialised value(s)
==5404==    at 0x25DAAD7: incorporate_penalties (ipa-cp.c:3282)
==5404==    by 0x25DAAD7: good_cloning_opportunity_p(cgraph_node*, sreal,
sreal, profile_count, int) (ipa-cp.c:3340)
==5404==    by 0x25DBA04: estimate_local_effects(cgraph_node*) (ipa-cp.c:
3560)
==5404==    by 0x25E5DD3: propagate_constants_topo (ipa-cp.c:3871)
==5404==    by 0x25E5DD3: ipcp_propagate_stage (ipa-cp.c:4058)
==5404==    by 0x25E5DD3: ipcp_driver (ipa-cp.c:6541)
==5404==    by 0x25E5DD3: (anonymous namespace)::pass_ipa_cp::execute
(function*) (ipa-cp.c:6618)
==5404==    by 0x1538C3C: execute_one_pass(opt_

Re: distinguishing gcc compilation valgrind false positives

2021-11-24 Thread Paul Floyd via Gcc



On 24/11/2021 20:05, Zdenek Sojka via Gcc wrote:

Hello,

from time to time, I come upon a testcase that failed during the automated
runs, but passes during reduction; there are valgrind warnings present,
however. How do I distinguish what warnings are valid and which are false
positives? Is there any way gcc could prevent generating the false
positives?



What makes you think that any are false positives?

Memcheck generally has a low false positive rate (though I am little 
biased).


You need to read the source and decide based on that.


A+

Paul



Re: distinguishing gcc compilation valgrind false positives

2021-11-24 Thread Jeff Law via Gcc




On 11/24/2021 12:15 PM, Paul Floyd via Gcc wrote:


On 24/11/2021 20:05, Zdenek Sojka via Gcc wrote:

Hello,

from time to time, I come upon a testcase that failed during the 
automated

runs, but passes during reduction; there are valgrind warnings present,
however. How do I distinguish what warnings are valid and which are 
false

positives? Is there any way gcc could prevent generating the false
positives?



What makes you think that any are false positives?

Memcheck generally has a low false positive rate (though I am little 
biased).


You need to read the source and decide based on that.
Agreed.  Work from the assumption it's a real GCC issue until proven 
otherwise.


I believe GCC has annotations to help valgrind that are turned on by a 
magic configuration option as well.


Finally, there is an issue with sparsesets that will trigger a warning 
from valgrind.  Those are the only ones I would consistently ignore from 
GCC.


Jeff


Re: distinguishing gcc compilation valgrind false positives

2021-11-24 Thread Zdenek Sojka via Gcc
Hello Paul,

(sorry for re-post, I didn't include the ML in the original reply)

-- Původní e-mail --
Od: Paul Floyd via Gcc 
Komu: gcc@gcc.gnu.org
Datum: 24. 11. 2021 20:16:33
Předmět: Re: distinguishing gcc compilation valgrind false positives
"
On 24/11/2021 20:05, Zdenek Sojka via Gcc wrote:
> Hello,
>
> from time to time, I come upon a testcase that failed during the automated

> runs, but passes during reduction; there are valgrind warnings present, 
> however. How do I distinguish what warnings are valid and which are false
> positives? Is there any way gcc could prevent generating the false
> positives?


What makes you think that any are false positives?

Memcheck generally has a low false positive rate (though I am little
biased).

You need to read the source and decide based on that.


A+

Paul
"



the main reason why it looks like a false positive is that I've had these 
valgrind warnings ... since probably ever, but it was never causing issues.




I cannot tell from the sources if there is anything wrong, so I am better 
asking here.




Thanks!
Zdenek

 
"
"


Re: distinguishing gcc compilation valgrind false positives

2021-11-24 Thread Jakub Jelinek via Gcc
On Wed, Nov 24, 2021 at 12:31:53PM -0700, Jeff Law via Gcc wrote:
> Agreed.  Work from the assumption it's a real GCC issue until proven
> otherwise.
> 
> I believe GCC has annotations to help valgrind that are turned on by a magic
> configuration option as well.

True, but Zdenek has them turned on based on the posted configure options.
That is the --enable-valgrind-annotations in there...

Jakub



Re: distinguishing gcc compilation valgrind false positives

2021-11-24 Thread Zdenek Sojka via Gcc
Hello Jeff,

-- Původní e-mail --
Od: Jeff Law via Gcc 
Komu: Paul Floyd , gcc@gcc.gnu.org
Datum: 24. 11. 2021 20:33:02
Předmět: Re: distinguishing gcc compilation valgrind false positives
"

On 11/24/2021 12:15 PM, Paul Floyd via Gcc wrote:
>
> On 24/11/2021 20:05, Zdenek Sojka via Gcc wrote:
>> Hello,
>>
>> from time to time, I come upon a testcase that failed during the
>> automated
>> runs, but passes during reduction; there are valgrind warnings present,
>> however. How do I distinguish what warnings are valid and which are
>> false
>> positives? Is there any way gcc could prevent generating the false
>> positives?
>
>
> What makes you think that any are false positives?
>
> Memcheck generally has a low false positive rate (though I am little
> biased).
>
> You need to read the source and decide based on that.
Agreed.  Work from the assumption it's a real GCC issue until proven 
otherwise.

I believe GCC has annotations to help valgrind that are turned on by a
magic configuration option as well.
"



I have gcc configured with --enable-valgrind-annotations , if that is the 
one you are talking about?


 
"
Finally, there is an issue with sparsesets that will trigger a warning
from valgrind.  Those are the only ones I would consistently ignore from
GCC.

Jeff "






Yes I remember those - but it would be nice to get rid of them anyway, at 
least to simplify testcase reduction by having no valgrind warning on a 
clean build.




I could also use a valgrind suppression file; this is also part of my
question, if there is one readily available




Thanks,
Zdenek




 
"
"


Re: distinguishing gcc compilation valgrind false positives

2021-11-24 Thread Jan Hubicka via Gcc
> ==5404== Conditional jump or move depends on uninitialised value(s)
> ==5404==    at 0x25DAAD7: incorporate_penalties (ipa-cp.c:3282)
> ==5404==    by 0x25DAAD7: good_cloning_opportunity_p(cgraph_node*, sreal,
> sreal, profile_count, int) (ipa-cp.c:3340)

I looked at this one (since it is in code I am familiar with) and I
think it may be real bug.  There are flags node_is_self_scc which does
not seem to be initialized in the constructor.

diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 42842d9466a..1d0c115465c 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -623,8 +623,8 @@ ipa_node_params::ipa_node_params ()
 : descriptors (NULL), lattices (NULL), ipcp_orig_node (NULL),
   known_csts (vNULL), known_contexts (vNULL), analysis_done (0),
   node_enqueued (0), do_clone_for_all_contexts (0), is_all_contexts_clone (0),
-  node_dead (0), node_within_scc (0), node_calling_single_call (0),
-  versionable (0)
+  node_dead (0), node_within_scc (0), node_is_self_scc (0),
+  node_calling_single_call (0), versionable (0)
 {
 }
 
Honza


Re: distinguishing gcc compilation valgrind false positives

2021-11-24 Thread Paul Floyd via Gcc

Hi


the main reason why it looks like a false positive is that I've had 
these valgrind warnings ... since probably ever, but it was never 
causing issues.



I cannot tell from the sources if there is anything wrong, so I am 
better asking here.





Well, that's the nature of undefined behaviour. Undefined doesn't mean 
that it is non-deterministic.



And if you really do find false positives (which is always possible, 
especially with new compiler releases) then please report them to us at



https://bugs.kde.org/enter_bug.cgi?product=valgrind


A+

Paul




Question about match.pd

2021-11-24 Thread Navid Rahimi via Gcc
Hi GCC community,

I have a question about pattern matching in match.pd.

So I have a pattern like this [1]:
#define CMP !=
bool f(bool c, int i) { return (c << i) CMP 0; }
bool g(bool c, int i) { return c CMP 0;}

It is verifiably correct to transfer f to g [2]. Although this pattern looks 
simple, but the problem rises because GIMPLE converts booleans to int before 
"<<" operation.
So at the end you have boolean->integer->boolean conversion and the shift will 
happen on the integer in the middle.

For example, for something like:

bool g(bool c){return (c << 22);}

The GIMPLE is:
_Bool g (_Bool c)
{
  int _1;
  int _2;
  _Bool _4;

   [local count: 1073741824]:
  _1 = (int) c_3(D);
  _2 = _1 << 22;
  _4 = _2 != 0;
  return _4;
}

I wrote a patch to fix this problem in match.pd:

+(match boolean_valued_p
+ @0
+ (if (TREE_CODE (type) == BOOLEAN_TYPE
+  && TYPE_PRECISION (type) == 1)))
+(for op (tcc_comparison truth_and truth_andif truth_or truth_orif truth_xor)
+ (match boolean_valued_p
+  (op @0 @1)))
+(match boolean_valued_p
+  (truth_not @0))

+/* cmp : ==, != */
+/* ((B0 << x) cmp 0) -> B0 cmp 0 */
+(for cmp (eq ne)
+ (simplify
+  (cmp (lshift (convert@3 boolean_valued_p@0) @1) integer_zerop@2)
+   (if (TREE_CODE (TREE_TYPE (@3)) == INTEGER_TYPE
+   && (GIMPLE || !TREE_SIDE_EFFECTS (@1)))
+(cmp @0 @2


But the problem is I am not able to restrict to the cases I am interested in. 
There are many hits in other libraries I have tried compiling with trunk+patch.

Any feedback? 

1) https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98956
2) https://alive2.llvm.org/ce/z/UUTJ_v

Best wishes,
Navid.

Re: distinguishing gcc compilation valgrind false positives

2021-11-24 Thread Thomas Schwinge
Hi!

On 2021-11-24T20:05:56+0100, Zdenek Sojka via Gcc  wrote:
> from time to time, I come upon a testcase that failed during the automated
> runs, but passes during reduction; there are valgrind warnings present,
> however.

Thanks for looking into this.  Please collect any Valgrind notes at
.


> $ x86_64-pc-linux-gnu-gcc `cat flags` -c -w mcf.ii -wrapper valgrind,-q,--
> track-origins=yes
> ==5404== Invalid read of size 4
> ==5404==at 0x197B210: put (hash-map.h:179)
> ==5404==by 0x197B210: void copy_warning
> (tree_node*, tree_node const*) (warning-control.cc:209)
> ==5404==by 0xE40CB6: cp_fold(tree_node*) (cp-gimplify.c:2837)
> [...]

That's  "recent valgrind error in
warning-control.cc since
r12-1804-g65870e75616ee4359d1c13b99be794e6a577bc65".

> ==5404== Invalid read of size 4
> ==5404==at 0x197B210: put (hash-map.h:179)
> ==5404==by 0x197B210: void copy_warning
> (tree_node*, tree_node const*) (warning-control.cc:209)
> ==5404==by 0x12B2343: fold_truth_not_expr(unsigned int, tree_node*)
> (fold-const.c:4288)
> [...]

Same/similar, i suppose.


Grüße
 Thomas
-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955


Re: Question about match.pd

2021-11-24 Thread Jeff Law via Gcc




On 11/24/2021 2:19 PM, Navid Rahimi via Gcc wrote:

Hi GCC community,

I have a question about pattern matching in match.pd.

So I have a pattern like this [1]:
#define CMP !=
bool f(bool c, int i) { return (c << i) CMP 0; }
bool g(bool c, int i) { return c CMP 0;}

It is verifiably correct to transfer f to g [2]. Although this pattern looks simple, but the 
problem rises because GIMPLE converts booleans to int before "<<" operation.
So at the end you have boolean->integer->boolean conversion and the shift will 
happen on the integer in the middle.

For example, for something like:

bool g(bool c){return (c << 22);}

The GIMPLE is:
_Bool g (_Bool c)
{
   int _1;
   int _2;
   _Bool _4;

[local count: 1073741824]:
   _1 = (int) c_3(D);
   _2 = _1 << 22;
   _4 = _2 != 0;
   return _4;
}

I wrote a patch to fix this problem in match.pd:

+(match boolean_valued_p
+ @0
+ (if (TREE_CODE (type) == BOOLEAN_TYPE
+  && TYPE_PRECISION (type) == 1)))
+(for op (tcc_comparison truth_and truth_andif truth_or truth_orif truth_xor)
+ (match boolean_valued_p
+  (op @0 @1)))
+(match boolean_valued_p
+  (truth_not @0))

+/* cmp : ==, != */
+/* ((B0 << x) cmp 0) -> B0 cmp 0 */
+(for cmp (eq ne)
+ (simplify
+  (cmp (lshift (convert@3 boolean_valued_p@0) @1) integer_zerop@2)
+   (if (TREE_CODE (TREE_TYPE (@3)) == INTEGER_TYPE
+   && (GIMPLE || !TREE_SIDE_EFFECTS (@1)))
+(cmp @0 @2


But the problem is I am not able to restrict to the cases I am interested in. 
There are many hits in other libraries I have tried compiling with trunk+patch.

Any feedback?

1) https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98956
2) https://alive2.llvm.org/ce/z/UUTJ_v
It would help to also see the cases you're triggering that you do not 
want to trigger.


Could we think of the optimization opportunity in a different way?


(A << B) eq/ne 0  -> A eq/ne (0U >> B)

And I would expect the 0U >> B to get simplified to 0.

Would looking at things that way help?

jeff


Re: distinguishing gcc compilation valgrind false positives

2021-11-24 Thread Jeff Law via Gcc




On 11/24/2021 12:41 PM, Zdenek Sojka wrote:

Hello Jeff,

-- Původní e-mail --
Od: Jeff Law via Gcc 
Komu: Paul Floyd , gcc@gcc.gnu.org
Datum: 24. 11. 2021 20:33:02
Předmět: Re: distinguishing gcc compilation valgrind false positives




On 11/24/2021 12:15 PM, Paul Floyd via Gcc wrote:
>
> On 24/11/2021 20:05, Zdenek Sojka via Gcc wrote:
>> Hello,
>>
>> from time to time, I come upon a testcase that failed during the
>> automated
>> runs, but passes during reduction; there are valgrind warnings
present,
>> however. How do I distinguish what warnings are valid and which
are
>> false
>> positives? Is there any way gcc could prevent generating the false
>> positives?
>
>
> What makes you think that any are false positives?
>
> Memcheck generally has a low false positive rate (though I am
little
> biased).
>
> You need to read the source and decide based on that.
Agreed.  Work from the assumption it's a real GCC issue until proven
otherwise.

I believe GCC has annotations to help valgrind that are turned on
by a
magic configuration option as well.


I have gcc configured with --enable-valgrind-annotations , if that is 
the one you are talking about?



Almost certainly.  I



I could also use a valgrind suppression file; this is also part of my 
question, if there is one readily available



I'm not aware of a suppression file, but it'd be nice to have one.

jeff