&& INTEGRAL_TYPE_P (TREE_TYPE (@0)))
(cond @1 (convert @2) (convert @3))))
+/* PR123967: if (cond) A | CST1 : A & ~CST1
+
+ Make both bitops unconditional: (A & ~CST1) | (cond * CST1). */
+(for cmp (simple_comparison)
+ (simplify
+ (cond (cmp@4 @5 @6) (bit_ior @0 INTEGER_CST@1) (bit_and@3 @0 INTEGER_CST@2))
+ (if (INTEGRAL_TYPE_P (type)
+ && INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ && (TYPE_UNSIGNED (TREE_TYPE (@1)) || tree_int_cst_sgn (@1) > 0)
+ && TYPE_PRECISION (type) <= BITS_PER_WORD
+ && wi::to_wide (@1) == ~wi::to_wide (@2))
+ (bit_ior @3 (mult (convert:type @4) (convert:type @1))))))
+
/* Simplification moved from fold_cond_expr_with_comparison. It may also
be extended. */
/* This pattern implements two kinds simplification:
--- /dev/null
+/* { dg-additional-options -O2 } */
+/* { dg-additional-options -fdump-tree-optimized } */
+
+unsigned f1 (unsigned x, unsigned m)
+{
+ if (x)
+ m |= 0x3;
+ else
+ m = m & ~0x3;
+
+ return m + 1;
+}
+
+unsigned f2 (unsigned x, int m)
+{
+ int mask = 0x3;
+
+ if (x)
+ m |= mask;
+ else
+ m = m & ~mask;
+
+ return m + 1;
+}
+/* { dg-final { scan-tree-dump-times " \\\| 3" 0 optimized } } */
--- /dev/null
+/* { dg-do run } */
+/* { dg-additional-options -O2 } */
+
+void abort(void);
+
+/* Macro adapted from builtin-object-size-common.h */
+#define FAIL() \
+ do { \
+ __builtin_printf ("Failure at line: %d\n", __LINE__); \
+ abort(); \
+ } while (0)
+
+unsigned f1 (unsigned x, int m)
+{
+ int mask = 0x3;
+
+ if (x)
+ m |= mask;
+ else
+ m = m & ~mask;
+
+ return m + 1;
+}
+
+unsigned f2 (unsigned x, int m)
+{
+ if (x)
+ m |= 0x3;
+ else
+ m = m & ~0x8;
+
+ return m + 1;
+}
+
+int main (void)
+{
+ if (f1 (0, 7) != 5)
+ FAIL ();
+ if (f1 (1, 7) != 8)
+ FAIL ();
+
+ if (f2 (0, 8) != 1)
+ FAIL ();
+ if (f2 (1, 8) != 12)
+ FAIL ();
+
+ return 0;
+}
--- /dev/null
+/* { dg-additional-options -O2 } */
+/* { dg-additional-options -fdump-tree-optimized } */
+
+/* Code taken from Perlbench */
+
+typedef long unsigned int size_t;
+typedef long int ssize_t;
+typedef size_t STRLEN;
+typedef struct cop COP;
+typedef struct sv SV;
+typedef struct p5rx REGEXP;
+typedef struct magic MAGIC;
+typedef unsigned char U8;
+typedef int I32;
+typedef unsigned int U32;
+
+typedef int boolean;
+
+struct sv
+{
+ void *sv_any;
+ U32 sv_flags;
+ union
+ {
+ SV *svu_rv;
+ } sv_u;
+};
+struct p5rx
+{
+ union
+ {
+ struct regexp *svu_rx;
+ } sv_u;
+};
+typedef struct regexp
+{
+ U32 extflags;
+} regexp;
+typedef struct
+{
+ char *ganch;
+} regmatch_info;
+struct cop
+{
+ U32 cop_hints;
+};
+struct magic
+{
+ U8 mg_flags;
+ ssize_t mg_len;
+};
+MAGIC *Perl_mg_find_mglob (SV * sv);
+extern COP *PL_curcop;
+extern STRLEN S_MgBYTEPOS (MAGIC *mg, SV *sv, const char *s, STRLEN len) ;
+
+static struct regexp *
+S_ReANY (const REGEXP *const re)
+{
+ return re->sv_u.svu_rx;
+}
+
+
+I32
+Perl_regexec_flags (REGEXP *const rx, char *stringarg, char *strend,
+ char *strbeg, ssize_t minend, SV *sv, void *data,
+ U32 flags)
+{
+ char *startpos;
+ ssize_t minlen;
+ MAGIC *mg;
+
+ const boolean
+ utf8_target =
+ (((((sv)->sv_flags & 0x20000000)
+ && !(((PL_curcop)->cop_hints + 0) & 0x00000008))) ? 1 : 0);
+ regmatch_info reginfo_buf;
+ regmatch_info *const reginfo = ®info_buf;
+
+ startpos = stringarg;
+
+ reginfo->ganch =
+ (flags & 0x08)
+ ? stringarg
+ : ((mg = Perl_mg_find_mglob (sv)) && mg->mg_len >= 0)
+ ? strbeg + S_MgBYTEPOS (mg, sv, strbeg, strend - strbeg) : strbeg;
+
+ if ((startpos + minlen) > strend || startpos < strbeg)
+ return 0;
+
+ ((utf8_target)
+ ? (((S_ReANY ((const REGEXP *) (rx)))->extflags) |=
+ (1U << (((0 + 12) + 2) + 6)))
+ : (((S_ReANY ((const REGEXP *) (rx)))->extflags) &=
+ ~(1U << (((0 + 12) + 2) + 6))));
+
+}
+/* { dg-final { scan-tree-dump-times " \\\| 1048576" 0 optimized } } */