Hello,
Le 31/07/2023 à 19:07, Andrew Pinski via Gcc-patches a écrit :
diff --git a/gcc/generic-match-head.cc b/gcc/generic-match-head.cc
index a71c0727b0b..ddaf22f2179 100644
--- a/gcc/generic-match-head.cc
+++ b/gcc/generic-match-head.cc
@@ -121,3 +121,45 @@ bitwise_equal_p (tree expr1, tree expr2)
return wi::to_wide (expr1) == wi::to_wide (expr2);
return operand_equal_p (expr1, expr2, 0);
}
+
+/* Return true if EXPR1 and EXPR2 have the bitwise opposite value,
+ but not necessarily same type.
+ The types can differ through nop conversions. */
+
+static inline bool
+bitwise_inverted_equal_p (tree expr1, tree expr2)
+{
+ STRIP_NOPS (expr1);
+ STRIP_NOPS (expr2);
+ if (expr1 == expr2)
+ return false;
+ if (!tree_nop_conversion_p (TREE_TYPE (expr1), TREE_TYPE (expr2)))
+ return false;
+ if (TREE_CODE (expr1) == INTEGER_CST && TREE_CODE (expr2) == INTEGER_CST)
+ return wi::to_wide (expr1) == ~wi::to_wide (expr2);
+ if (operand_equal_p (expr1, expr2, 0))
+ return false;
+ if (TREE_CODE (expr1) == BIT_NOT_EXPR
+ && bitwise_equal_p (TREE_OPERAND (expr1, 0), expr2))
+ return true;
+ if (TREE_CODE (expr2) == BIT_NOT_EXPR
+ && bitwise_equal_p (expr1, TREE_OPERAND (expr2, 0)))
+ return true;
+ if (COMPARISON_CLASS_P (expr1)
+ && COMPARISON_CLASS_P (expr2))
+ {
+ tree op10 = TREE_OPERAND (expr1, 0);
+ tree op20 = TREE_OPERAND (expr2, 0);
+ if (!operand_equal_p (op10, op20))
+ return false;
+ tree op11 = TREE_OPERAND (expr1, 1);
+ tree op21 = TREE_OPERAND (expr2, 1);
+ if (!operand_equal_p (op11, op21))
+ return false;
+ if (invert_tree_comparison (TREE_CODE (expr1),
+ HONOR_NANS (op10))
+ == TREE_CODE (expr2))
+ return true;
So this is trying to match a == b against a != b, or a < b against a >=
b, or similar; correct?
Shouldn't this be completed with "crossed" checks, that is match a == b
against b != a, or a < b against b <= a, etc? Or is there some
canonicalization making that redundant?
I have given up determining whether these cases were already covered by
the test or not.
Mikael