https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80297

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, it is indeed that
/* Fold (A & ~B) - (A & B) into (A ^ B) - B.  */
(simplify
 (minus (bit_and:cs @0 (bit_not @1)) (bit_and:cs @0 @1))
  (minus (bit_xor @0 @1) @1))
pattern which uses @1 more than once.  For normal generic folding it wouldn't
be as big problem, because we unshare everything before gimplification.
Except that in this case it triggers late, already during gimplification:
#0  generic_simplify_87 (loc=2147483653, type=<integer_type 0x7fffefae0690
unsigned int>, op0=<bit_and_expr 0x7fffefc51398>, 
    op1=<bit_and_expr 0x7fffefc51348>, captures=0x7fffffffb6b0) at
generic-match.c:3644
#1  0x00000000016f22d1 in generic_simplify_MINUS_EXPR (loc=2147483653,
code=MINUS_EXPR, type=<integer_type 0x7fffefae0690 unsigned int>, 
    op0=<bit_and_expr 0x7fffefc51398>, op1=<bit_and_expr 0x7fffefc51348>) at
generic-match.c:12824
#2  0x00000000017406be in generic_simplify (loc=2147483653, code=MINUS_EXPR,
type=<integer_type 0x7fffefae0690 unsigned int>, 
    op0=<bit_and_expr 0x7fffefc51398>, op1=<bit_and_expr 0x7fffefc51348>) at
generic-match.c:33944
#3  0x0000000000d3a0ab in fold_binary_loc (loc=2147483653, code=MINUS_EXPR,
type=<integer_type 0x7fffefae0690 unsigned int>, 
    op0=<bit_and_expr 0x7fffefc51398>, op1=<bit_and_expr 0x7fffefc51348>) at
../../gcc/fold-const.c:9157
#4  0x0000000000d4a1d5 in fold_build2_stat_loc (loc=2147483653,
code=MINUS_EXPR, type=<integer_type 0x7fffefae0690 unsigned int>, 
    op0=<bit_and_expr 0x7fffefc51398>, op1=<bit_and_expr 0x7fffefc51348>) at
../../gcc/fold-const.c:12285
#5  0x0000000000bef110 in convert_to_integer_1 (type=<integer_type
0x7fffefae0690 unsigned int>, expr=<minus_expr 0x7fffefc511b8>, dofold=true)
    at ../../gcc/convert.c:850
#6  0x0000000000befb32 in convert_to_integer_maybe_fold (type=<integer_type
0x7fffefae0690 unsigned int>, expr=<minus_expr 0x7fffefc511b8>, 
    dofold=true) at ../../gcc/convert.c:978
#7  0x0000000000971dc6 in ocp_convert (type=<integer_type 0x7fffefae0690
unsigned int>, expr=<minus_expr 0x7fffefc511b8>, convtype=143, flags=17, 
    complain=3) at ../../gcc/cp/cvt.c:812
#8  0x0000000000974646 in convert (type=<integer_type 0x7fffefae0690 unsigned
int>, expr=<minus_expr 0x7fffefc511b8>) at ../../gcc/cp/cvt.c:1590
#9  0x0000000000adfc72 in c_gimplify_expr (expr_p=0x7fffefc51318,
pre_p=0x7fffffffd988, post_p=0x7fffffffd2a0)
    at ../../gcc/c-family/c-gimplify.c:247
#10 0x0000000000a4ae60 in cp_gimplify_expr (expr_p=0x7fffefc51318,
pre_p=0x7fffffffd988, post_p=0x7fffffffd2a0) at ../../gcc/cp/cp-gimplify.c:863
#11 0x0000000000df0bdd in gimplify_expr (expr_p=0x7fffefc51318,
pre_p=0x7fffffffd988, post_p=0x7fffffffd2a0, 
    gimple_test_f=0xdc4cde <is_gimple_reg_rhs_or_call(tree)>, fallback=1) at
../../gcc/gimplify.c:11145
#12 0x0000000000dd5b63 in gimplify_modify_expr (expr_p=0x7fffffffd3b8,
pre_p=0x7fffffffd988, post_p=0x7fffffffd2a0, want_value=false)
    at ../../gcc/gimplify.c:5465

So, either we need to unshare_expr in GENERIC every time some operand is used
multiple times, or have some flag we set after unsharing fn body and is set
until expansion in case GENERIC folding is used during gimple optimizations
(fold_build* etc.).
So far genmatch.c uses unshare_expr only for COND_EXPR or VEC_COND_EXPR
conditions.
Dunno how many patterns are affected:
(simplify
 (mult (abs@1 @0) @1)
 (mult @0 @0))

(for copysigns (COPYSIGN)
 (simplify
  (mult (copysigns@2 @0 @1) @2)
  (mult @0 @0)))

(simplify
 (bit_ior:c (bit_and:cs @0 (bit_not @2)) (bit_and:cs @1 @2))
 (bit_xor (bit_and (bit_xor @0 @1) @2) @0))

(for cmp (eq ge le)
 (simplify
  (cmp @0 @0)
  (if (! FLOAT_TYPE_P (TREE_TYPE (@0))
       || ! HONOR_NANS (@0))
   { constant_boolean_node (true, type); }
   (if (cmp != EQ_EXPR)
    (eq @0 @0)))))

(for cmp (unlt ungt)
 (simplify
  (cmp @0 @0)
  (unordered @0 @0)))

       (if (! HONOR_NANS (@0))
        { constant_boolean_node (true, type); }
        /* x <= +Inf is the same as x == x, i.e. !isnan(x).  */
        (eq @0 @0)))

(simplify
 (minus (bit_and:cs @0 (bit_not @1)) (bit_and:cs @0 @1))
  (minus (bit_xor @0 @1) @1))
(simplify
 (minus (bit_and:s @0 INTEGER_CST@2) (bit_and:s @0 INTEGER_CST@1))
 (if (wi::bit_not (@2) == @1)
  (minus (bit_xor @0 @1) @1)))

(simplify
 (minus (bit_and:cs @0 @1) (bit_and:cs @0 (bit_not @1)))
  (minus @1 (bit_xor @0 @1)))

are what I found.  So shall genmatch.c watch for captures used multiple times
and in GENERIC emit unshare_expr for the second and further uses in there?

Reply via email to