On Thu, 11 Feb 2016, Christophe Lyon wrote: > On 9 February 2016 at 13:42, Richard Biener <rguent...@suse.de> wrote: > > > > It turns out if-conversions poor job on > > > > if (a) > > x[i] = ...; > > else > > x[i] = ...; > > > > results in bogus uninit warnings of x[i] for a variety of reasons. > > First of all forwprop (aka match.pd simplification) doesn't fixup > > all of if-conversions poor job as canonicalization sometimes > > inverts the condition in [VEC_]COND_EXPRs and thus the existing > > A ? B : (A ? X : C) -> A ? B : C pattern doesn't apply. The match.pd > > hunk fixes this (albeit in an awkward way - I don't feel like mucking > > with genmatch at this stage, nor exactly for the poor [VEC_]COND_EXPR > > IL we should rather fix). Second, the late uninit pass is confused > > by the left-over dead code, in this case dead load feeding a dead > > VEC_COND_EXPR. Adding a DCE pass before late uninit as the comment > > in passes.def suggests fixes this and also should avoid creating the dead > > RTL I've sometimes seen. > > > > Due to the PR69719 fix we're now over the alias-test limit for the > > testcase (well, all alias tests are bogus, see PR69732), so I upped > > that limit for the testcase. I'm investigating the Job done there. > > > > Bootstrap and regtest is currently running on x86_64-unknown-linux-gnu. > > > Hi, > > After this patch, I noticed that > g++.dg/tree-ssa/pr61034.C -std=gnu++11 scan-tree-dump-times > optimized "free" 4 > now fails on arm* and aarch64* > The dump contains no occurrence of "free". > > Is this just a matter of adjusting the test-case or an unexpected > problem with this patch?
Yeah, I fixed the testcase up this morning. Richard. > Christophe. > > > Richard. > > > > 2016-02-09 Richard Biener <rguent...@suse.de> > > > > PR tree-optimization/69726 > > * passes.def: Add DCE pass before late uninit. > > * match.pd: Add A ? B : (!A ? C : X) -> A ? B : C patterns to > > really fixup if-conversions job. > > > > * gcc.dg/uninit-22.c: New testcase. > > > > Index: gcc/passes.def > > =================================================================== > > *** gcc/passes.def (revision 233241) > > --- gcc/passes.def (working copy) > > *************** along with GCC; see the file COPYING3. > > *** 322,336 **** > > NEXT_PASS (pass_fold_builtins); > > NEXT_PASS (pass_optimize_widening_mul); > > NEXT_PASS (pass_tail_calls); > > ! /* FIXME: If DCE is not run before checking for uninitialized uses, > > we may get false warnings (e.g., testsuite/gcc.dg/uninit-5.c). > > However, this also causes us to misdiagnose cases that should be > > ! real warnings (e.g., testsuite/gcc.dg/pr18501.c). > > ! > > ! To fix the false positives in uninit-5.c, we would have to > > ! account for the predicates protecting the set and the use of each > > ! variable. Using a representation like Gated Single Assignment > > ! may help. */ > > /* Split critical edges before late uninit warning to reduce the > > number of false positives from it. */ > > NEXT_PASS (pass_split_crit_edges); > > --- 322,332 ---- > > NEXT_PASS (pass_fold_builtins); > > NEXT_PASS (pass_optimize_widening_mul); > > NEXT_PASS (pass_tail_calls); > > ! /* If DCE is not run before checking for uninitialized uses, > > we may get false warnings (e.g., testsuite/gcc.dg/uninit-5.c). > > However, this also causes us to misdiagnose cases that should be > > ! real warnings (e.g., testsuite/gcc.dg/pr18501.c). */ > > ! NEXT_PASS (pass_dce); > > /* Split critical edges before late uninit warning to reduce the > > number of false positives from it. */ > > NEXT_PASS (pass_split_crit_edges); > > Index: gcc/match.pd > > =================================================================== > > *** gcc/match.pd (revision 233241) > > --- gcc/match.pd (working copy) > > *************** DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > > *** 1717,1722 **** > > --- 1717,1745 ---- > > (simplify > > (cnd @0 @1 (cnd @0 @2 @3)) > > (cnd @0 @1 @3)) > > + /* A ? B : (!A ? C : X) -> A ? B : C. */ > > + /* ??? This matches embedded conditions open-coded because genmatch > > + would generate matching code for conditions in separate stmts only. > > + The following is still important to merge then and else arm cases > > + from if-conversion. */ > > + (simplify > > + (cnd @0 @1 (cnd @2 @3 @4)) > > + (if (COMPARISON_CLASS_P (@0) > > + && COMPARISON_CLASS_P (@2) > > + && invert_tree_comparison > > + (TREE_CODE (@0), HONOR_NANS (TREE_OPERAND (@0, 0))) == > > TREE_CODE (@2) > > + && operand_equal_p (TREE_OPERAND (@0, 0), TREE_OPERAND (@2, 0), 0) > > + && operand_equal_p (TREE_OPERAND (@0, 1), TREE_OPERAND (@2, 1), 0)) > > + (cnd @0 @1 @3))) > > + (simplify > > + (cnd @0 (cnd @1 @2 @3) @4) > > + (if (COMPARISON_CLASS_P (@0) > > + && COMPARISON_CLASS_P (@1) > > + && invert_tree_comparison > > + (TREE_CODE (@0), HONOR_NANS (TREE_OPERAND (@0, 0))) == > > TREE_CODE (@1) > > + && operand_equal_p (TREE_OPERAND (@0, 0), TREE_OPERAND (@1, 0), 0) > > + && operand_equal_p (TREE_OPERAND (@0, 1), TREE_OPERAND (@1, 1), 0)) > > + (cnd @0 @3 @4))) > > > > /* A ? B : B -> B. */ > > (simplify > > Index: gcc/testsuite/gcc.dg/uninit-22.c > > =================================================================== > > *** gcc/testsuite/gcc.dg/uninit-22.c (revision 0) > > --- gcc/testsuite/gcc.dg/uninit-22.c (revision 0) > > *************** > > *** 0 **** > > --- 1,69 ---- > > + /* { dg-do compile } */ > > + /* { dg-options "-O3 -Wuninitialized --param > > vect-max-version-for-alias-checks=20" } */ > > + > > + #include <stdint.h> > > + > > + #define A1 2896 /* (1/sqrt(2))<<12 */ > > + #define A2 2217 > > + #define A3 3784 > > + #define A4 -5352 > > + > > + #define > > IDCT_TRANSFORM(dest,s0,s1,s2,s3,s4,s5,s6,s7,d0,d1,d2,d3,d4,d5,d6,d7,munge,src) > > {\ > > + const int a0 = (src)[s0] + (src)[s4]; \ > > + const int a1 = (src)[s0] - (src)[s4]; \ > > + const int a2 = (src)[s2] + (src)[s6]; \ > > + const int a3 = (A1*((src)[s2] - (src)[s6])) >> 11; \ > > + const int a4 = (src)[s5] + (src)[s3]; \ > > + const int a5 = (src)[s5] - (src)[s3]; \ > > + const int a6 = (src)[s1] + (src)[s7]; \ > > + const int a7 = (src)[s1] - (src)[s7]; \ > > + const int b0 = a4 + a6; \ > > + const int b1 = (A3*(a5 + a7)) >> 11; \ > > + const int b2 = ((A4*a5) >> 11) - b0 + b1; \ > > + const int b3 = (A1*(a6 - a4) >> 11) - b2; \ > > + const int b4 = ((A2*a7) >> 11) + b3 - b1; \ > > + (dest)[d0] = munge(a0+a2 +b0); \ > > + (dest)[d1] = munge(a1+a3-a2+b2); \ > > + (dest)[d2] = munge(a1-a3+a2+b3); \ > > + (dest)[d3] = munge(a0-a2 -b4); \ > > + (dest)[d4] = munge(a0-a2 +b4); \ > > + (dest)[d5] = munge(a1-a3+a2-b3); \ > > + (dest)[d6] = munge(a1+a3-a2-b2); \ > > + (dest)[d7] = munge(a0+a2 -b0); \ > > + } > > + > > + #define MUNGE_NONE(x) (x) > > + #define IDCT_COL(dest,src) > > IDCT_TRANSFORM(dest,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,MUNGE_NONE,src) > > + > > + #define MUNGE_ROW(x) (((x) + 0x7F)>>8) > > + #define IDCT_ROW(dest,src) > > IDCT_TRANSFORM(dest,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,MUNGE_ROW,src) > > + > > + static inline void bink_idct_col(int *dest, const int32_t *src) > > + { > > + if ((src[8]|src[16]|src[24]|src[32]|src[40]|src[48]|src[56])==0) { > > + dest[0] = > > + dest[8] = > > + dest[16] = > > + dest[24] = > > + dest[32] = > > + dest[40] = > > + dest[48] = > > + dest[56] = src[0]; > > + } else { > > + IDCT_COL(dest, src); > > + } > > + } > > + > > + int bink_idct_put_c(uint8_t *dest, int linesize, int32_t *block) > > + { > > + int i; > > + int temp[64]; > > + for (i = 0; i < 8; i++) > > + bink_idct_col(&temp[i], &block[i]); > > + for (i = 0; i < 8; i++) { > > + IDCT_ROW( (&dest[i*linesize]), (&temp[8*i]) ); > > + } > > + > > + return 0; > > + } > > + > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)