Hi!

I've backported some fixes I've committed (plus one support change from
Jason and one fix from Marek) to 4.8 branch in the last year or so to
4.7 branch, after bootstrapping/regtesting them on x86_64-linux and
i686-linux.
Sorry for the delay.

        Jakub
2014-05-07  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-06-27  Jakub Jelinek  <ja...@redhat.com>

        PR target/57623
        * config/i386/i386.md (bmi2_bzhi_<mode>3): Swap AND arguments
        to match RTL canonicalization.  Swap predicates and
        constraints of operand 1 and 2.

        * gcc.target/i386/bmi2-bzhi-1.c: New test.

--- gcc/config/i386/i386.md     (revision 200477)
+++ gcc/config/i386/i386.md     (revision 200478)
@@ -12174,9 +12174,9 @@ (define_insn "*bmi_blsr_<mode>"
 ;; BMI2 instructions.
 (define_insn "bmi2_bzhi_<mode>3"
   [(set (match_operand:SWI48 0 "register_operand" "=r")
-       (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
-                  (lshiftrt:SWI48 (const_int -1)
-                                  (match_operand:SWI48 2 
"nonimmediate_operand" "rm"))))
+       (and:SWI48 (lshiftrt:SWI48 (const_int -1)
+                                  (match_operand:SWI48 2 "register_operand" 
"r"))
+                  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_BMI2"
   "bzhi\t{%2, %1, %0|%0, %1, %2}"
--- gcc/testsuite/gcc.target/i386/bmi2-bzhi-1.c (revision 0)
+++ gcc/testsuite/gcc.target/i386/bmi2-bzhi-1.c (revision 200478)
@@ -0,0 +1,31 @@
+/* PR target/57623 */
+/* { dg-do assemble { target bmi2 } } */
+/* { dg-options "-O2 -mbmi2" } */
+
+#include <x86intrin.h>
+
+unsigned int
+f1 (unsigned int x, unsigned int *y)
+{
+  return _bzhi_u32 (x, *y);
+}
+
+unsigned int
+f2 (unsigned int *x, unsigned int y)
+{
+  return _bzhi_u32 (*x, y);
+}
+
+#ifdef  __x86_64__
+unsigned long long
+f3 (unsigned long long x, unsigned long long *y)
+{
+  return _bzhi_u64 (x, *y);
+}
+
+unsigned long long
+f4 (unsigned long long *x, unsigned long long y)
+{
+  return _bzhi_u64 (*x, y);
+}
+#endif
2014-05-07  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-06-27  Jakub Jelinek  <ja...@redhat.com>

        PR target/57623
        * config/i386/i386.md (bmi_bextr_<mode>): Swap predicates and
        constraints of operand 1 and 2.

        * gcc.target/i386/bmi-bextr-3.c: New test.

--- gcc/config/i386/i386.md     (revision 200479)
+++ gcc/config/i386/i386.md     (revision 200480)
@@ -12077,8 +12077,8 @@
 
 (define_insn "bmi_bextr_<mode>"
   [(set (match_operand:SWI48 0 "register_operand" "=r")
-        (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
-                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
+        (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
+                       (match_operand:SWI48 2 "register_operand" "r")]
                        UNSPEC_BEXTR))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_BMI"
--- gcc/testsuite/gcc.target/i386/bmi-bextr-3.c (revision 0)
+++ gcc/testsuite/gcc.target/i386/bmi-bextr-3.c (revision 200480)
@@ -0,0 +1,31 @@
+/* PR target/57623 */
+/* { dg-do assemble { target bmi } } */
+/* { dg-options "-O2 -mbmi" } */
+
+#include <x86intrin.h>
+
+unsigned int
+f1 (unsigned int x, unsigned int *y)
+{
+  return __bextr_u32 (x, *y);
+}
+
+unsigned int
+f2 (unsigned int *x, unsigned int y)
+{
+  return __bextr_u32 (*x, y);
+}
+
+#ifdef  __x86_64__
+unsigned long long
+f3 (unsigned long long x, unsigned long long *y)
+{
+  return __bextr_u64 (x, *y);
+}
+
+unsigned long long
+f4 (unsigned long long *x, unsigned long long y)
+{
+  return __bextr_u64 (*x, y);
+}
+#endif
2014-05-07  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-07-03  Jakub Jelinek  <ja...@redhat.com>

        PR target/57777
        * config/i386/predicates.md (vsib_address_operand): Disallow
        SYMBOL_REF or LABEL_REF in parts.disp if TARGET_64BIT && flag_pic.

        * gcc.target/i386/pr57777.c: New test.

--- gcc/config/i386/predicates.md       (revision 200649)
+++ gcc/config/i386/predicates.md       (revision 200650)
@@ -835,19 +835,28 @@ (define_predicate "vsib_address_operand"
     return false;
 
   /* VSIB addressing doesn't support (%rip).  */
-  if (parts.disp && GET_CODE (parts.disp) == CONST)
+  if (parts.disp)
     {
-      disp = XEXP (parts.disp, 0);
-      if (GET_CODE (disp) == PLUS)
-       disp = XEXP (disp, 0);
-      if (GET_CODE (disp) == UNSPEC)
-       switch (XINT (disp, 1))
-         {
-         case UNSPEC_GOTPCREL:
-         case UNSPEC_PCREL:
-         case UNSPEC_GOTNTPOFF:
-           return false;
-         }
+      disp = parts.disp;
+      if (GET_CODE (disp) == CONST)
+       {
+         disp = XEXP (disp, 0);
+         if (GET_CODE (disp) == PLUS)
+           disp = XEXP (disp, 0);
+         if (GET_CODE (disp) == UNSPEC)
+           switch (XINT (disp, 1))
+             {
+             case UNSPEC_GOTPCREL:
+             case UNSPEC_PCREL:
+             case UNSPEC_GOTNTPOFF:
+               return false;
+             }
+       }
+      if (TARGET_64BIT
+         && flag_pic
+         && (GET_CODE (disp) == SYMBOL_REF
+             || GET_CODE (disp) == LABEL_REF))
+       return false;
     }
 
   return true;
--- gcc/testsuite/gcc.target/i386/pr57777.c     (revision 0)
+++ gcc/testsuite/gcc.target/i386/pr57777.c     (revision 200650)
@@ -0,0 +1,13 @@
+/* PR target/57777 */
+/* { dg-do assemble { target avx2 } } */
+/* { dg-options "-O3 -mavx2" } */
+/* { dg-additional-options "-fpic" { target fpic } } */
+
+void
+foo (unsigned long *x, int *y)
+{
+  static unsigned long b[2] = { 0x0UL, 0x9908b0dfUL };
+  int c;
+  for (c = 0; c < 512; c++)
+    x[c] = b[x[c] & 1UL];
+}
2014-05-07  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-08-23  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/58209
        * tree-tailcall.c (find_tail_calls): Give up for pointer result types
        if m or a is non-NULL.

        * gcc.c-torture/execute/pr58209.c: New test.

--- gcc/tree-tailcall.c (revision 201936)
+++ gcc/tree-tailcall.c (revision 201937)
@@ -574,6 +574,11 @@ find_tail_calls (basic_block bb, struct
   if (!tail_recursion && (m || a))
     return;
 
+  /* For pointers don't allow additions or multiplications.  */
+  if ((m || a)
+      && POINTER_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl))))
+    return;
+
   nw = XNEW (struct tailcall);
 
   nw->call_gsi = gsi;
--- gcc/testsuite/gcc.c-torture/execute/pr58209.c       (revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr58209.c       (revision 201937)
@@ -0,0 +1,32 @@
+/* PR tree-optimization/58209 */
+
+extern void abort (void);
+typedef __INTPTR_TYPE__ T;
+T buf[1024];
+
+T *
+foo (T n)
+{
+  if (n == 0)
+    return (T *) buf;
+  T s = (T) foo (n - 1);
+  return (T *) (s + sizeof (T));
+}
+
+T *
+bar (T n)
+{
+  if (n == 0)
+    return buf;
+  return foo (n - 1) + 1;
+}
+
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 27; i++)
+    if (foo (i) != buf + i || bar (i) != buf + i)
+      abort ();
+  return 0;
+}
2014-05-07  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-08-30  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/58277
        * tree-ssa-strlen.c (strlen_enter_block): If do_invalidate gave up
        after seeing too many stmts with vdef in between dombb and current
        bb, invalidate everything.

        * gcc.c-torture/execute/pr58277-1.c: New test.
        * gcc.c-torture/execute/pr58277-2.c: New test.

--- gcc/tree-ssa-strlen.c       (revision 202104)
+++ gcc/tree-ssa-strlen.c       (revision 202105)
@@ -1896,6 +1896,29 @@ strlen_enter_block (struct dom_walk_data
                  int count_vdef = 100;
                  do_invalidate (dombb, phi, visited, &count_vdef);
                  BITMAP_FREE (visited);
+                 if (count_vdef == 0)
+                   {
+                     /* If there were too many vdefs in between immediate
+                        dominator and current bb, invalidate everything.
+                        If stridx_to_strinfo has been unshared, we need
+                        to free it, otherwise just set it to NULL.  */
+                     if (!strinfo_shared ())
+                       {
+                         unsigned int i;
+                         strinfo si;
+
+                         for (i = 1;
+                              VEC_iterate (strinfo, stridx_to_strinfo, i, si);
+                              ++i)
+                           {
+                             free_strinfo (si);
+                             VEC_replace (strinfo, stridx_to_strinfo,
+                                          i, NULL);
+                           }
+                       }
+                     else
+                       stridx_to_strinfo = NULL;
+                   }
                  break;
                }
            }
--- gcc/testsuite/gcc.c-torture/execute/pr58277-1.c     (revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr58277-1.c     (revision 202105)
@@ -0,0 +1,102 @@
+/* PR tree-optimization/58277 */
+
+extern void abort (void);
+static int a[2];
+int b, c, d, *e, f, g, h, **i = &e, k, l = 1, n, o, p;
+static int **volatile j = &e;
+const int m;
+char u;
+
+int
+bar ()
+{
+  u = 0;
+  return m;
+}
+
+__attribute__((noinline, noclone)) void
+baz ()
+{
+  asm ("");
+}
+
+static int
+foo ()
+{
+  int t1;
+  g = bar ();
+  if (l)
+    ;
+  else
+    for (;; h++)
+      {
+       *i = 0;
+       o = *e = 0;
+       if (p)
+         {
+           f = 0;
+           return 0;
+         }
+       for (;; k++)
+         {
+           int *t2 = 0;
+           int *const *t3[] = {
+             0, 0, 0, 0, 0, 0, 0, 0, 0, &t2, 0, 0, &t2, &t2, &t2,
+             &t2, &t2, 0, 0, 0, 0, 0, 0, 0, &t2, 0, 0, 0, 0, 0, 0,
+             0, 0, 0, 0, &t2, 0, 0, 0, 0, 0, 0, 0, &t2, &t2,
+             &t2, &t2, &t2, 0, 0, 0, 0, 0, 0, 0, &t2, 0, 0, 0,
+             &t2, 0, 0, 0, &t2, 0, &t2, 0, 0, &t2, 0, 0, 0, 0,
+             0, &t2, 0, 0, 0, 0, &t2, &t2, 0, 0, 0, 0, &t2, 0,
+             0, 0, 0, 0, 0, 0, &t2, 0, 0, 0, 0, 0, &t2, 0, 0, 0,
+             &t2, &t2
+           };
+           int *const **t4[] = {&t3[0]};
+           **i = 0;
+           if (**j)
+             break;
+           u = 0;
+         }
+       *i = *j;
+       t1 = 0;
+       for (; t1 < 5; t1++)
+         *i = *j;
+      }
+  *j = 0;
+  return 1;
+}
+
+int
+main ()
+{
+  int t5;
+  a[0] = 1;
+  {
+    int *t6[6] = {&d, &d};
+    for (n = 1; n; n--)
+      if (foo())
+       {
+         int *t7[] = {0};
+         d = 0;
+         for (; u < 1; u++)
+           *i = *j;
+         *i = 0;
+         *i = 0;
+         int t8[5] = {0};
+         *i = &t8[0];
+         int *const *t9 = &t6[0];
+         int *const **t10 = &t9;
+         *t10 = &t7[0];
+       }
+  }
+  u = 0;
+  for (; b; b++)
+    for (t5 = 0; t5 < 10; t5++)
+      c = a[a[a[a[a[a[a[a[c]]]]]]]];
+
+  baz ();
+
+  if (!a[a[a[a[a[a[a[a[a[a[a[a[a[a[a[u]]]]]]]]]]]]]]])
+    abort ();
+
+  return 0;
+}
--- gcc/testsuite/gcc.c-torture/execute/pr58277-2.c     (revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr58277-2.c     (revision 202105)
@@ -0,0 +1,98 @@
+/* PR tree-optimization/58277 */
+
+extern void abort (void);
+static int a[1], b, c, e, i, j, k, m, q[] = { 1, 1 }, t;
+int volatile d;
+int **r;
+static int ***volatile s = &r;
+int f, g, o, x;
+static int *volatile h = &f, *p;
+char n;
+
+static void
+fn1 ()
+{
+  b = a[a[a[a[a[a[a[a[b]]]]]]]];
+  b = a[a[a[a[a[a[a[a[b]]]]]]]];
+  b = a[a[b]];
+  b = a[a[a[a[a[a[a[a[b]]]]]]]];
+  b = a[a[a[a[a[a[a[a[b]]]]]]]];
+}
+
+static int
+fn2 ()
+{
+  n = 0;
+  for (; g; t++)
+    {
+      for (;; m++)
+       {
+         d;
+         int *u;
+         int **v[] = {
+           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+           0, 0, 0, 0, 0, &u, 0, 0, 0, 0, &u, &u, &u, &u, &u, &u, &u, 0,
+           &u, 0, &u, &u, &u, 0, &u, &u, 0, &u, &u, &u, &u, 0, &u, &u, &u,
+           &u, &u, 0, &u, &u, 0, &u, 0, &u, &u, 0, &u, &u, &u, &u, &u, 0,
+           &u, 0, 0, 0, &u, &u, &u, 0, 0, &u, &u, &u, 0, &u, 0, &u, &u
+         };
+         int ***w[] = { &v[0] };
+         if (*p)
+           break;
+         return 0;
+       }
+      *h = 0;
+    }
+  return 1;
+}
+
+static void
+fn3 ()
+{
+  int *y[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+  for (; i; i++)
+    x = 0;
+  if (fn2 ())
+    {
+      int *z[6] = { };
+      for (; n < 1; n++)
+       *h = 0;
+      int t1[7];
+      for (; c; c++)
+       o = t1[0];
+      for (; e; e--)
+       {
+         int **t2 = &y[0];
+         int ***t3 = &t2;
+         *t3 = &z[0];
+       }
+    }
+  *s = 0;
+  for (n = 0;; n = 0)
+    {
+      int t4 = 0;
+      if (q[n])
+       break;
+      *r = &t4;
+    }
+}
+
+int
+main ()
+{
+  for (; j; j--)
+    a[0] = 0;
+  fn3 ();
+  for (; k; k++)
+    fn1 ();
+  fn1 ();
+ 
+  if (n)
+    abort ();
+
+  return 0;
+}
2014-05-07  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-09-09  Jakub Jelinek  <ja...@redhat.com>

        PR c++/58325
        * init.c (build_vec_delete): Call mark_rvalue_use on base.

        * g++.dg/warn/Wunused-var-21.C: New test.

--- gcc/cp/init.c       (revision 202411)
+++ gcc/cp/init.c       (revision 202412)
@@ -4064,6 +4064,7 @@ build_vec_delete (tree base, tree maxind
       tree cookie_addr;
       tree size_ptr_type = build_pointer_type (sizetype);
 
+      base = mark_rvalue_use (base);
       if (TREE_SIDE_EFFECTS (base))
        {
          base_init = get_target_expr (base);
--- gcc/testsuite/g++.dg/warn/Wunused-var-21.C  (revision 0)
+++ gcc/testsuite/g++.dg/warn/Wunused-var-21.C  (revision 202412)
@@ -0,0 +1,31 @@
+// PR c++/58325
+// { dg-do compile }
+// { dg-options "-Wunused" }
+
+void
+f1 ()
+{
+  int *volatile a = new int[1];
+  delete[] a;
+}
+
+void
+f2 ()
+{
+  int *b = new int[1];
+  delete[] b;
+}
+
+void
+f3 ()
+{
+  int *volatile c = new int;
+  delete c;
+}
+
+void
+f4 ()
+{
+  int *d = new int;
+  delete d;
+}
2014-05-07  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-09-10  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/58365
        * cfgcleanup.c (merge_memattrs): Also clear MEM_READONLY_P
        resp. MEM_NOTRAP_P if they differ, or set MEM_VOLATILE_P if
        it differs.

        * gcc.c-torture/execute/pr58365.c: New test.

--- gcc/cfgcleanup.c    (revision 202434)
+++ gcc/cfgcleanup.c    (revision 202435)
@@ -927,6 +927,24 @@ merge_memattrs (rtx x, rtx y)
          set_mem_align (y, MEM_ALIGN (x));
        }
     }
+  if (code == MEM)
+    {
+      if (MEM_READONLY_P (x) != MEM_READONLY_P (y))
+       {
+         MEM_READONLY_P (x) = 0;
+         MEM_READONLY_P (y) = 0;
+       }
+      if (MEM_NOTRAP_P (x) != MEM_NOTRAP_P (y))
+       {
+         MEM_NOTRAP_P (x) = 0;
+         MEM_NOTRAP_P (y) = 0;
+       }
+      if (MEM_VOLATILE_P (x) != MEM_VOLATILE_P (y))
+       {
+         MEM_VOLATILE_P (x) = 1;
+         MEM_VOLATILE_P (y) = 1;
+       }
+    }
 
   fmt = GET_RTX_FORMAT (code);
   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
--- gcc/testsuite/gcc.c-torture/execute/pr58365.c       (revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr58365.c       (revision 202435)
@@ -0,0 +1,35 @@
+/* PR rtl-optimization/58365 */
+
+extern void abort (void);
+
+struct S
+{
+  volatile int a;
+  int b, c, d, e;
+} f;
+static struct S g, h;
+int i = 1;
+
+char
+foo (void)
+{
+  return i;
+}
+
+static struct S
+bar (void)
+{
+  if (foo ())
+    return f;
+  return g;
+}
+
+int
+main ()
+{
+  h = bar ();
+  f.b = 1;
+  if (h.b != 0)
+    abort ();
+  return 0;
+}
2014-05-07  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-09-30  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/58564
        * fold-const.c (fold_ternary_loc): For A < 0 : <sign bit of A> : 0
        optimization, punt if sign_bit_p looked through any zero extension.

        * gcc.c-torture/execute/pr58564.c: New test.

--- gcc/fold-const.c    (revision 203042)
+++ gcc/fold-const.c    (revision 203043)
@@ -14085,14 +14085,29 @@ fold_ternary_loc (location_t loc, enum t
          && integer_zerop (op2)
          && (tem = sign_bit_p (TREE_OPERAND (arg0, 0), arg1)))
        {
+         /* sign_bit_p looks through both zero and sign extensions,
+            but for this optimization only sign extensions are
+            usable.  */
+         tree tem2 = TREE_OPERAND (arg0, 0);
+         while (tem != tem2)
+           {
+             if (TREE_CODE (tem2) != NOP_EXPR
+                 || TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (tem2, 0))))
+               {
+                 tem = NULL_TREE;
+                 break;
+               }
+             tem2 = TREE_OPERAND (tem2, 0);
+           }
          /* sign_bit_p only checks ARG1 bits within A's precision.
             If <sign bit of A> has wider type than A, bits outside
             of A's precision in <sign bit of A> need to be checked.
             If they are all 0, this optimization needs to be done
             in unsigned A's type, if they are all 1 in signed A's type,
             otherwise this can't be done.  */
-         if (TYPE_PRECISION (TREE_TYPE (tem))
-             < TYPE_PRECISION (TREE_TYPE (arg1))
+         if (tem
+             && TYPE_PRECISION (TREE_TYPE (tem))
+                < TYPE_PRECISION (TREE_TYPE (arg1))
              && TYPE_PRECISION (TREE_TYPE (tem))
                 < TYPE_PRECISION (type))
            {
--- gcc/testsuite/gcc.c-torture/execute/pr58564.c       (revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr58564.c       (revision 203043)
@@ -0,0 +1,14 @@
+/* PR middle-end/58564 */
+
+extern void abort (void);
+int a, b;
+short *c, **d = &c;
+
+int
+main ()
+{
+  b = (0, 0 > ((&c == d) & (1 && (a ^ 1)))) | 0U;
+  if (b != 0)
+    abort ();
+  return 0;
+}
2014-05-07  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-11-14  Jakub Jelinek  <ja...@redhat.com>
                    Uros Bizjak  <ubiz...@gmail.com>

        PR target/59101
        * config/i386/i386.md (*anddi_2): Only allow CCZmode if
        operands[2] satisfies_constraint_Z that might have bit 31 set.

        * gcc.c-torture/execute/pr59101.c: New test.

--- gcc/config/i386/i386.md     (revision 204774)
+++ gcc/config/i386/i386.md     (revision 204775)
@@ -8000,7 +8000,18 @@ (define_insn "*anddi_2"
         (const_int 0)))
    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
        (and:DI (match_dup 1) (match_dup 2)))]
-  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
+  "TARGET_64BIT
+   && ix86_match_ccmode
+       (insn,
+        /* If we are going to emit andl instead of andq, and the operands[2]
+           constant might have the SImode sign bit set, make sure the sign
+           flag isn't tested, because the instruction will set the sign flag
+           based on bit 31 rather than bit 63.  If it isn't CONST_INT,
+           conservatively assume it might have bit 31 set.  */
+        (satisfies_constraint_Z (operands[2])
+         && (!CONST_INT_P (operands[2])
+             || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
+        ? CCZmode : CCNOmode)
    && ix86_binary_operator_ok (AND, DImode, operands)"
   "@
    and{l}\t{%k2, %k0|%k0, %k2}
--- gcc/testsuite/gcc.c-torture/execute/pr59101.c       (revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr59101.c       (revision 204775)
@@ -0,0 +1,15 @@
+/* PR target/59101 */
+
+__attribute__((noinline, noclone)) int
+foo (int a)
+{
+  return (~a & 4102790424LL) > 0 | 6;
+}
+
+int
+main ()
+{
+  if (foo (0) != 7)
+    __builtin_abort ();
+  return 0;
+}
2014-05-07  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-11-27  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/59014
        * gcc.c-torture/execute/pr59014-2.c: New test.

        2013-11-26  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/59014
        * tree-vrp.c (register_edge_assert_for_1): Don't look
        through conversions from non-integral types or through
        narrowing conversions.

        * gcc.c-torture/execute/pr59014.c: New test.

--- gcc/tree-vrp.c      (revision 205455)
+++ gcc/tree-vrp.c      (revision 205456)
@@ -5271,9 +5271,13 @@ register_edge_assert_for_1 (tree op, enu
     }
   else if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (op_def)))
     {
-      /* Recurse through the type conversion.  */
-      retval |= register_edge_assert_for_1 (gimple_assign_rhs1 (op_def),
-                                           code, e, bsi);
+      /* Recurse through the type conversion, unless it is a narrowing
+        conversion or conversion from non-integral type.  */
+      tree rhs = gimple_assign_rhs1 (op_def);
+      if (INTEGRAL_TYPE_P (TREE_TYPE (rhs))
+         && (TYPE_PRECISION (TREE_TYPE (rhs))
+             <= TYPE_PRECISION (TREE_TYPE (op))))
+       retval |= register_edge_assert_for_1 (rhs, code, e, bsi);
     }
 
   return retval;
--- gcc/testsuite/gcc.c-torture/execute/pr59014.c       (revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr59014.c       (revision 205456)
@@ -0,0 +1,25 @@
+/* PR tree-optimization/59014 */
+
+int a = 2, b, c, d;
+
+int
+foo ()
+{
+  for (;; c++)
+    if ((b > 0) | (a & 1))
+      ;
+    else
+      {
+       d = a;
+       return 0;
+      }
+}
+
+int
+main ()
+{
+  foo ();
+  if (d != 2)
+    __builtin_abort ();
+  return 0;
+}
--- gcc/testsuite/gcc.c-torture/execute/pr59014-2.c     (revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr59014-2.c     (revision 205457)
@@ -0,0 +1,23 @@
+/* PR tree-optimization/59014 */
+
+__attribute__((noinline, noclone)) long long int
+foo (long long int x, long long int y)
+{
+  if (((int) x | (int) y) != 0)
+    return 6;
+  return x + y;
+}
+
+int
+main ()
+{
+  if (sizeof (long long) == sizeof (int))
+    return 0;
+  int shift_half = sizeof (int) * __CHAR_BIT__ / 2;
+  long long int x = (3LL << shift_half) << shift_half;
+  long long int y = (5LL << shift_half) << shift_half;
+  long long int z = foo (x, y);
+  if (z != ((8LL << shift_half) << shift_half))
+    __builtin_abort ();
+  return 0;
+}
2014-05-07  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-11-28  Jakub Jelinek  <ja...@redhat.com>

        PR c++/59297
        * semantics.c (finish_omp_atomic): Call finish_expr_stmt
        rather than add_stmt.

        * g++.dg/gomp/pr59297.C: New test.

        2013-05-31  Jason Merrill  <ja...@redhat.com>

        PR c++/56930
        * semantics.c (potential_constant_expression_1): Handle OMP_ATOMIC*.

--- gcc/cp/semantics.c  (revision 205500)
+++ gcc/cp/semantics.c  (revision 205501)
@@ -4977,7 +4977,7 @@ finish_omp_atomic (enum tree_code code,
        }
       stmt = build2 (OMP_ATOMIC, void_type_node, integer_zero_node, stmt);
     }
-  add_stmt (stmt);
+  finish_expr_stmt (stmt);
 }
 
 void
@@ -8594,6 +8594,12 @@ potential_constant_expression_1 (tree t,
        }
       return false;
 
+    case OMP_ATOMIC:
+    case OMP_ATOMIC_READ:
+    case OMP_ATOMIC_CAPTURE_OLD:
+    case OMP_ATOMIC_CAPTURE_NEW:
+      return false;
+
     default:
       sorry ("unexpected AST of kind %s", tree_code_name[TREE_CODE (t)]);
       gcc_unreachable();
--- gcc/testsuite/g++.dg/gomp/pr59297.C (revision 0)
+++ gcc/testsuite/g++.dg/gomp/pr59297.C (revision 205501)
@@ -0,0 +1,25 @@
+// PR c++/59297
+// { dg-do compile }
+// { dg-options "-fopenmp" }
+
+template <typename T>
+struct A
+{
+  ~A ();
+  const T &operator[] (int) const;
+};
+
+struct B
+{
+  int &operator () (A <int>);
+};
+
+void
+foo (B &x, int &z)
+{
+  A<A<int> > y;
+  #pragma omp atomic
+  x (y[0]) += 1;
+  #pragma omp atomic
+  z += x(y[1]);
+}
2014-05-07  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-12-03  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/59011
        * gimplify.c (nonlocal_vla_vars): New variable.
        (gimplify_var_or_parm_decl): Put VAR_DECLs for VLAs into
        nonlocal_vla_vars chain.
        (gimplify_body): Call declare_vars on nonlocal_vla_vars chain
        if outer_bind has DECL_INITIAL (current_function_decl) block.

        * gcc.dg/pr59011.c: New test.

--- gcc/gimplify.c      (revision 205621)
+++ gcc/gimplify.c      (revision 205622)
@@ -2060,6 +2060,9 @@ gimplify_conversion (tree *expr_p)
 /* Nonlocal VLAs seen in the current function.  */
 static struct pointer_set_t *nonlocal_vlas;
 
+/* The VAR_DECLs created for nonlocal VLAs for debug info purposes.  */
+static tree nonlocal_vla_vars;
+
 /* Gimplify a VAR_DECL or PARM_DECL.  Return GS_OK if we expanded a
    DECL_VALUE_EXPR, and it's worth re-examining things.  */
 
@@ -2106,14 +2109,13 @@ gimplify_var_or_parm_decl (tree *expr_p)
            ctx = ctx->outer_context;
          if (!ctx && !pointer_set_insert (nonlocal_vlas, decl))
            {
-             tree copy = copy_node (decl), block;
+             tree copy = copy_node (decl);
 
              lang_hooks.dup_lang_specific_decl (copy);
              SET_DECL_RTL (copy, 0);
              TREE_USED (copy) = 1;
-             block = DECL_INITIAL (current_function_decl);
-             DECL_CHAIN (copy) = BLOCK_VARS (block);
-             BLOCK_VARS (block) = copy;
+             DECL_CHAIN (copy) = nonlocal_vla_vars;
+             nonlocal_vla_vars = copy;
              SET_DECL_VALUE_EXPR (copy, unshare_expr (value_expr));
              DECL_HAS_VALUE_EXPR_P (copy) = 1;
            }
@@ -8261,6 +8263,21 @@ gimplify_body (tree fndecl, bool do_parm
 
   if (nonlocal_vlas)
     {
+      if (nonlocal_vla_vars)
+       {
+         /* tree-nested.c may later on call declare_vars (..., true);
+            which relies on BLOCK_VARS chain to be the tail of the
+            gimple_bind_vars chain.  Ensure we don't violate that
+            assumption.  */
+         if (gimple_bind_block (outer_bind)
+             == DECL_INITIAL (current_function_decl))
+           declare_vars (nonlocal_vla_vars, outer_bind, true);
+         else
+           BLOCK_VARS (DECL_INITIAL (current_function_decl))
+             = chainon (BLOCK_VARS (DECL_INITIAL (current_function_decl)),
+                        nonlocal_vla_vars);
+         nonlocal_vla_vars = NULL_TREE;
+       }
       pointer_set_destroy (nonlocal_vlas);
       nonlocal_vlas = NULL;
     }
--- gcc/testsuite/gcc.dg/pr59011.c      (revision 0)
+++ gcc/testsuite/gcc.dg/pr59011.c      (revision 205783)
@@ -0,0 +1,22 @@
+/* PR middle-end/59011 */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+void
+foo (int m)
+{
+  int a[m];
+  void
+  bar (void)
+  {
+    {
+      int
+      baz (void)
+      {
+       return a[0];
+      }
+    }
+    a[0] = 42;
+  }
+  bar ();
+}
2014-05-07  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-10-21  Marek Polacek  <pola...@redhat.com>

        PR middle-end/58809
        * fold-const.c (fold_range_test): Return 0 if the type is not
        an integral type.

        * gcc.dg/gomp/pr58809.c: New test.

--- gcc/fold-const.c    (revision 206963)
+++ gcc/fold-const.c    (revision 206964)
@@ -4921,12 +4921,16 @@ fold_range_test (location_t loc, enum tr
   int in0_p, in1_p, in_p;
   tree low0, low1, low, high0, high1, high;
   bool strict_overflow_p = false;
-  tree lhs = make_range (op0, &in0_p, &low0, &high0, &strict_overflow_p);
-  tree rhs = make_range (op1, &in1_p, &low1, &high1, &strict_overflow_p);
-  tree tem;
+  tree tem, lhs, rhs;
   const char * const warnmsg = G_("assuming signed overflow does not occur "
                                  "when simplifying range test");
 
+  if (!INTEGRAL_TYPE_P (type))
+    return 0;
+
+  lhs = make_range (op0, &in0_p, &low0, &high0, &strict_overflow_p);
+  rhs = make_range (op1, &in1_p, &low1, &high1, &strict_overflow_p);
+
   /* If this is an OR operation, invert both sides; we will invert
      again at the end.  */
   if (or_op)
--- gcc/testsuite/gcc.dg/gomp/pr58809.c (revision 0)
+++ gcc/testsuite/gcc.dg/gomp/pr58809.c (revision 206964)
@@ -0,0 +1,13 @@
+/* PR middle-end/58809 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -O" } */
+
+int i;
+#pragma omp threadprivate (i)
+
+void foo()
+{
+  _Complex int j;
+#pragma omp parallel copyin (i) reduction (&&:j)
+  ;
+}

Reply via email to