On Tue, 16 Jul 2019, Li Jia He wrote:
> Hi,
>
> I made some changes based on the recommendations. Would you like to
> help me to see it again ? Sorry, it took so long time to provide the
> patch.
>
> Note: 1. I keep the code for and_comparisons_1 and or_comparisons_1.
> The reason is that I did not found a good way to handle the
> optimization of '((x CODE1 y) AND (x CODE2 y))' in match.pd.
> Maybe I missing some important information about match.pd.
> 2. The gimple_resimplify2 function is not used. Since stmt1,
> stmt2, lhs1 and lhs2 are allocated on the stack, Is there a
> question with the value on the stack as the return value ?
> I may have misunderstood Richard's intention.
And now for the match.pd patch.
+/* x > y && x != XXX_MIN --> x > y */
+(for and (truth_and bit_and)
+ (simplify
+ (and:c (gt:c@3 @0 @1) (ne @0 INTEGER_CST@2))
+ (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && INTEGRAL_TYPE_P
(TREE_TYPE(@1))
+ && (wi::eq_p (wi::to_wide (@2), wi::min_value (TREE_TYPE (@2)))))
+ @3)))
+
+/* x > y && x == XXX_MIN --> false */
+(for and (truth_and bit_and)
+ (simplify
+ (and:c (gt:c @0 @1) (eq @0 INTEGER_CST@2))
+ (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && INTEGRAL_TYPE_P
(TREE_TYPE(@1))
+ && (wi::eq_p (wi::to_wide (@2), wi::min_value (TREE_TYPE (@2)))))
+ { boolean_false_node; })))
you could merge those two via
(for eqne (eq ne)
(for and (....
(simplify
(and:c (gt:c @0 @1) (eqne @0 INTEGER_CST@2))
(if (...)
(switch
(if (eqne == NE_EXPR)
@3)
(if (eqne == EQ_EXPR)
{ constant_boolean_node (false, type); }))))
notice using constant_boolean_node (false, type); instead of
boolean_false_node. I suspect more unification is possible.
Also you could do
(match min_value
INTEGER_CST
(if (INTEGRAL_TYPE_P (type)
&& wi::eq_p (wi::to_wide (t), wi::min_value (type)))))
and then write
(simplify
(and:c (gt:c @0 @1) (eq @0 min_value))
(...
Your
(if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && INTEGRAL_TYPE_P
(TREE_TYPE(@1))
is redundant, it's enough to check either @0 or @1 given they
have to be compatible for the gt operation. Note you probably
want to use
(and:c (gt:c @0 @1) (eq @@0 min_value))
and verify that types_match (@1, @0) because when @0 are a constant
(and (eq @0 min_value) is not folded which can happen) then they
might have different types and thus you could have
(SHORT_MAX > intvar) && (SHORT_MAX == SHORT_MAX)
That said, the patterns can be quite a bit simplified I think.
Richard.