+2018-06-20 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2018-01-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/83623
+ * expmed.c (expand_shift_1): For 2-byte rotates by BITS_PER_UNIT,
+ check for bswap in mode rather than HImode and use that in expand_unop
+ too.
+
+ 2017-09-26 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2017-09-20 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/82264
+ * tree-ssa-sccvn.c (vn_phi_eq): Use safe_dyn_cast to check
+ for GIMPLE_CONDs.
+ (vn_phi_lookup): Likewise.
+ (vn_phi_insert): Likewise.
+ * is-a.h (safe_dyn_cast): New.
+
+ 2017-09-25 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/82285
+ * tree-vect-patterns.c (vect_recog_bool_pattern): Also handle
+ enumeral types.
+
+ 2017-11-24 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/82402
+ * tree-vect-loop-manip.c (create_lcssa_for_virtual_phi): Properly
+ set SSA_NAME_OCCURS_IN_ABNORMAL_PHI.
+
+ 2017-10-24 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/82697
+ * tree-ssa-phiopt.c (cond_store_replacement): Use alias-set
+ zero for conditional load and unconditional store.
+
+ 2017-11-02 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/82765
+ * varasm.c (decode_addr_const): Make offset HOST_WIDE_INT.
+ Truncate ARRAY_REF index and element size.
+
+ 2018-01-08 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/83713
+ * convert.c (do_narrow): Properly guard TYPE_OVERFLOW_WRAPS checks.
+
2018-06-19 Max Filippov <jcmvbkbc@gmail.com>
Backport from mainline
type in case the operation in outprec precision
could overflow. Otherwise, we would introduce
signed-overflow undefinedness. */
- || ((!TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0))
- || !TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1)))
+ || ((!(INTEGRAL_TYPE_P (TREE_TYPE (arg0))
+ && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0)))
+ || !(INTEGRAL_TYPE_P (TREE_TYPE (arg1))
+ && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1))))
&& ((TYPE_PRECISION (TREE_TYPE (arg0)) * 2u
> outprec)
|| (TYPE_PRECISION (TREE_TYPE (arg1)) * 2u
&& CONST_INT_P (op1)
&& INTVAL (op1) == BITS_PER_UNIT
&& GET_MODE_SIZE (scalar_mode) == 2
- && optab_handler (bswap_optab, HImode) != CODE_FOR_nothing)
- return expand_unop (HImode, bswap_optab, shifted, NULL_RTX,
- unsignedp);
+ && optab_handler (bswap_optab, mode) != CODE_FOR_nothing)
+ return expand_unop (mode, bswap_optab, shifted, NULL_RTX, unsignedp);
if (op1 == const0_rtx)
return shifted;
Note that we have converted two sets of assertions in the calls to varpool
into safe and efficient use of a variable.
+TYPE safe_dyn_cast <TYPE> (pointer)
+
+ Like dyn_cast <TYPE> (pointer), except that it accepts null pointers
+ and returns null results for them.
+
If you use these functions and get a 'inline function not defined' or a
'missing symbol' error message for 'is_a_helper<....>::test', it means that
return static_cast <T> (0);
}
+/* Similar to dyn_cast, except that the pointer may be null. */
+
+template <typename T, typename U>
+inline T
+safe_dyn_cast (U *p)
+{
+ return p ? dyn_cast <T> (p) : 0;
+}
+
#endif /* GCC_IS_A_H */
+2018-06-20 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2018-01-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/83623
+ * gcc.dg/pr83623.c: New test.
+
+ 2017-09-26 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2017-09-20 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/82264
+ * gcc.dg/torture/pr82264.c: New testcase.
+
+ 2017-09-25 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/82285
+ * gcc.dg/torture/pr82285.c: New testcase.
+
+ 2017-11-24 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/82402
+ * gcc.dg/torture/pr82402.c: New testcase.
+
+ 2017-10-24 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/82697
+ * gcc.dg/torture/pr82697.c: New testcase.
+
+ 2017-11-02 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/82765
+ * gcc.dg/pr82765.c: New testcase.
+
+ 2018-01-08 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/83713
+ * g++.dg/torture/pr83713.C: New testcase.
+
2018-06-09 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/85138
--- /dev/null
+// { dg-do compile }
+
+class a
+{
+ char b;
+ void c ();
+};
+void
+a::c ()
+{
+ &b + ((long long) &b & 0);
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-Os -w" } */
+
+int a[1][1];
+int main() { int *b[] = {a, a[1820408606019012862278468], a, a, a}; }
--- /dev/null
+/* PR middle-end/83623 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-mmovbe" { target i?86-*-* x86_64-*-* } } */
+
+unsigned short __attribute__ ((__vector_size__ (16))) x;
+
+void
+foo (void)
+{
+ x = x << 8 | x >> 8;
+}
--- /dev/null
+/* { dg-do compile } */
+
+char a;
+int c;
+unsigned b ();
+unsigned
+setjmp ()
+{
+}
+static void
+d ()
+{
+ if (b ())
+ c = 3;
+}
+void
+e ()
+{
+ d ();
+ a && ({ setjmp (); });
+}
--- /dev/null
+/* { dg-do run } */
+
+enum tst { first = 0, second = 1 };
+
+int
+main ()
+{
+ enum tst data[16];
+
+ for (unsigned i = 0; i < 16; i++)
+ data[i] = (i < 5 ? second : first);
+
+ if (data[2] != second)
+ __builtin_abort ();
+ return 0;
+}
--- /dev/null
+/* { dg-do compile } */
+
+typedef int jmp_buf[1];
+
+extern void exit(int) __attribute__((__noreturn__));
+extern int setjmpx(jmp_buf) __attribute__((__returns_twice__));
+
+jmp_buf jbAnagram;
+int a[6];
+int d;
+int b () { exit (1); }
+int c () { b (); }
+int e ()
+{
+ int f = 0;
+ for (; f < 6; f++)
+ a[f] = d;
+ c ();
+ setjmpx (jbAnagram);
+}
--- /dev/null
+/* { dg-do run } */
+
+__attribute__((noinline,noclone))
+void test(int *pi, long *pl, int f)
+{
+ *pl = 0;
+
+ *pi = 1;
+
+ if (f)
+ *pl = 2;
+}
+
+int main()
+{
+ void *p = __builtin_malloc(sizeof (long));
+
+ test(p, p, 0);
+
+ if (*(int *)p != 1)
+ __builtin_abort ();
+ return 0;
+}
if (ref->ref)
{
tree base = ref->ref;
+ tree innermost_dropped_array_ref = NULL_TREE;
if (handled_component_p (base))
{
tree saved_lhs0 = NULL_TREE;
TREE_OPERAND (base, 0) = saved_base0;
if (res)
break;
+ /* Remember if we drop an array-ref that we need to
+ double-check not being at struct end. */
+ if (TREE_CODE (base) == ARRAY_REF
+ || TREE_CODE (base) == ARRAY_RANGE_REF)
+ innermost_dropped_array_ref = base;
/* Otherwise drop handled components of the access. */
base = saved_base0;
}
TREE_OPERAND (lhs, 0) = saved_lhs0;
}
/* Finally check if the lhs has the same address and size as the
- base candidate of the access. */
- if (lhs == base
- || (((TYPE_SIZE (TREE_TYPE (lhs))
- == TYPE_SIZE (TREE_TYPE (base)))
- || (TYPE_SIZE (TREE_TYPE (lhs))
- && TYPE_SIZE (TREE_TYPE (base))
- && operand_equal_p (TYPE_SIZE (TREE_TYPE (lhs)),
- TYPE_SIZE (TREE_TYPE (base)), 0)))
- && operand_equal_p (lhs, base, OEP_ADDRESS_OF)))
+ base candidate of the access. Watch out if we have dropped
+ an array-ref that was at struct end, this means ref->ref may
+ be outside of the TYPE_SIZE of its base. */
+ if ((! innermost_dropped_array_ref
+ || ! array_at_struct_end_p (innermost_dropped_array_ref))
+ && (lhs == base
+ || (((TYPE_SIZE (TREE_TYPE (lhs))
+ == TYPE_SIZE (TREE_TYPE (base)))
+ || (TYPE_SIZE (TREE_TYPE (lhs))
+ && TYPE_SIZE (TREE_TYPE (base))
+ && operand_equal_p (TYPE_SIZE (TREE_TYPE (lhs)),
+ TYPE_SIZE (TREE_TYPE (base)),
+ 0)))
+ && operand_equal_p (lhs, base,
+ OEP_ADDRESS_OF
+ | OEP_MATCH_SIDE_EFFECTS))))
return true;
}
gsi_remove (&gsi, true);
release_defs (assign);
+ /* Make both store and load use alias-set zero as we have to
+ deal with the case of the store being a conditional change
+ of the dynamic type. */
+ lhs = unshare_expr (lhs);
+ tree *basep = &lhs;
+ while (handled_component_p (*basep))
+ basep = &TREE_OPERAND (*basep, 0);
+ if (TREE_CODE (*basep) == MEM_REF
+ || TREE_CODE (*basep) == TARGET_MEM_REF)
+ TREE_OPERAND (*basep, 1)
+ = fold_convert (ptr_type_node, TREE_OPERAND (*basep, 1));
+ else
+ *basep = build2 (MEM_REF, TREE_TYPE (*basep),
+ build_fold_addr_expr (*basep),
+ build_zero_cst (ptr_type_node));
+
/* 2) Insert a load from the memory of the store to the temporary
on the edge which did not contain the store. */
- lhs = unshare_expr (lhs);
name = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
new_stmt = gimple_build_assign (name, lhs);
gimple_set_location (new_stmt, locus);
return false;
/* Verify the controlling stmt is the same. */
- gimple *last1 = last_stmt (idom1);
- gimple *last2 = last_stmt (idom2);
- if (gimple_code (last1) != GIMPLE_COND
- || gimple_code (last2) != GIMPLE_COND)
+ gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1));
+ gcond *last2 = safe_dyn_cast <gcond *> (last_stmt (idom2));
+ if (! last1 || ! last2)
return false;
bool inverted_p;
- if (! cond_stmts_equal_p (as_a <gcond *> (last1),
- vp1->cclhs, vp1->ccrhs,
- as_a <gcond *> (last2),
- vp2->cclhs, vp2->ccrhs,
+ if (! cond_stmts_equal_p (last1, vp1->cclhs, vp1->ccrhs,
+ last2, vp2->cclhs, vp2->ccrhs,
&inverted_p))
return false;
vp1.ccrhs = NULL_TREE;
basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1.block);
if (EDGE_COUNT (idom1->succs) == 2)
- if (gcond *last1 = dyn_cast <gcond *> (last_stmt (idom1)))
+ if (gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1)))
{
vp1.cclhs = vn_valueize (gimple_cond_lhs (last1));
vp1.ccrhs = vn_valueize (gimple_cond_rhs (last1));
vp1->ccrhs = NULL_TREE;
basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
if (EDGE_COUNT (idom1->succs) == 2)
- if (gcond *last1 = dyn_cast <gcond *> (last_stmt (idom1)))
+ if (gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1)))
{
vp1->cclhs = vn_valueize (gimple_cond_lhs (last1));
vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1));
gimple *stmt;
use_operand_p use_p;
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_vop)
+ = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (vop);
add_phi_arg (new_phi, vop, exit_e, UNKNOWN_LOCATION);
gimple_phi_set_result (new_phi, new_vop);
FOR_EACH_IMM_USE_STMT (stmt, imm_iter, vop)
rhs_code = gimple_assign_rhs_code (last_stmt);
if (CONVERT_EXPR_CODE_P (rhs_code))
{
- if (TREE_CODE (TREE_TYPE (lhs)) != INTEGER_TYPE
+ if (! INTEGRAL_TYPE_P (TREE_TYPE (lhs))
|| TYPE_PRECISION (TREE_TYPE (lhs)) == 1)
return NULL;
vectype = get_vectype_for_scalar_type (TREE_TYPE (lhs));
decode_addr_const (tree exp, struct addr_const *value)
{
tree target = TREE_OPERAND (exp, 0);
- int offset = 0;
+ HOST_WIDE_INT offset = 0;
rtx x;
while (1)
else if (TREE_CODE (target) == ARRAY_REF
|| TREE_CODE (target) == ARRAY_RANGE_REF)
{
- offset += (tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (target)))
- * tree_to_shwi (TREE_OPERAND (target, 1)));
+ /* Truncate big offset. */
+ offset += (TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (target)))
+ * TREE_INT_CST_LOW (TREE_OPERAND (target, 1)));
target = TREE_OPERAND (target, 0);
}
else if (TREE_CODE (target) == MEM_REF