+2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
+ Alan Hayward <alan.hayward@arm.com>
+ David Sherwood <david.sherwood@arm.com>
+
+ * match.pd: Handle bit operations involving three constants
+ and try to fold one pair.
+
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
* tree-vect-loop-manip.c: Include gimple-fold.h.
(for bitop (bit_and bit_ior bit_xor)
(simplify
(bitop (bitop @0 CONSTANT_CLASS_P@1) CONSTANT_CLASS_P@2)
- (bitop @0 (bitop @1 @2))))
+ (if (!CONSTANT_CLASS_P (@0))
+ /* This is the canonical form regardless of whether (bitop @1 @2) can be
+ folded to a constant. */
+ (bitop @0 (bitop @1 @2))
+ /* In this case we have three constants and (bitop @0 @1) doesn't fold
+ to a constant. This can happen if @0 or @1 is a POLY_INT_CST and if
+ the values involved are such that the operation can't be decided at
+ compile time. Try folding one of @0 or @1 with @2 to see whether
+ that combination can be decided at compile time.
+
+ Keep the existing form if both folds fail, to avoid endless
+ oscillation. */
+ (with { tree cst1 = const_binop (bitop, type, @0, @2); }
+ (if (cst1)
+ (bitop @1 { cst1; })
+ (with { tree cst2 = const_binop (bitop, type, @1, @2); }
+ (if (cst2)
+ (bitop @0 { cst2; }))))))))
/* Try simple folding for X op !X, and X op X with the help
of the truth_valued_p and logical_inverted_value predicates. */