From e3cc64dec20832769406aa38cde83c7dd4194bf4 Mon Sep 17 00:00:00 2001 From: Ben Cheng Date: Tue, 22 Apr 2014 13:33:12 -0700 Subject: [4.9] GCC 4.9.0 official release refresh Change-Id: Ic99a7da8b44b789a48aeec93b33e93944d6e6767 --- gcc-4.9/gcc/gimple-fold.c | 84 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 12 deletions(-) (limited to 'gcc-4.9/gcc/gimple-fold.c') diff --git a/gcc-4.9/gcc/gimple-fold.c b/gcc-4.9/gcc/gimple-fold.c index 267c1fdad..6402cce2f 100644 --- a/gcc-4.9/gcc/gimple-fold.c +++ b/gcc-4.9/gcc/gimple-fold.c @@ -1186,13 +1186,56 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace) else if (gimple_call_builtin_p (stmt, BUILT_IN_MD)) changed |= targetm.gimple_fold_builtin (gsi); } - else if (gimple_call_internal_p (stmt) - && gimple_call_internal_fn (stmt) == IFN_BUILTIN_EXPECT) + else if (gimple_call_internal_p (stmt)) { - tree result = fold_builtin_expect (gimple_location (stmt), - gimple_call_arg (stmt, 0), - gimple_call_arg (stmt, 1), - gimple_call_arg (stmt, 2)); + enum tree_code subcode = ERROR_MARK; + tree result = NULL_TREE; + switch (gimple_call_internal_fn (stmt)) + { + case IFN_BUILTIN_EXPECT: + result = fold_builtin_expect (gimple_location (stmt), + gimple_call_arg (stmt, 0), + gimple_call_arg (stmt, 1), + gimple_call_arg (stmt, 2)); + break; + case IFN_UBSAN_CHECK_ADD: + subcode = PLUS_EXPR; + break; + case IFN_UBSAN_CHECK_SUB: + subcode = MINUS_EXPR; + break; + case IFN_UBSAN_CHECK_MUL: + subcode = MULT_EXPR; + break; + default: + break; + } + if (subcode != ERROR_MARK) + { + tree arg0 = gimple_call_arg (stmt, 0); + tree arg1 = gimple_call_arg (stmt, 1); + /* x = y + 0; x = y - 0; x = y * 0; */ + if (integer_zerop (arg1)) + result = subcode == MULT_EXPR + ? build_zero_cst (TREE_TYPE (arg0)) + : arg0; + /* x = 0 + y; x = 0 * y; */ + else if (subcode != MINUS_EXPR && integer_zerop (arg0)) + result = subcode == MULT_EXPR + ? build_zero_cst (TREE_TYPE (arg0)) + : arg1; + /* x = y - y; */ + else if (subcode == MINUS_EXPR && operand_equal_p (arg0, arg1, 0)) + result = build_zero_cst (TREE_TYPE (arg0)); + /* x = y * 1; x = 1 * y; */ + else if (subcode == MULT_EXPR) + { + if (integer_onep (arg1)) + result = arg0; + else if (integer_onep (arg0)) + result = arg1; + } + } if (result) { if (!update_call_from_tree (gsi, result)) @@ -2688,15 +2731,32 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree)) default: return NULL_TREE; } - tree op0 = (*valueize) (gimple_call_arg (stmt, 0)); - tree op1 = (*valueize) (gimple_call_arg (stmt, 1)); + tree arg0 = gimple_call_arg (stmt, 0); + tree arg1 = gimple_call_arg (stmt, 1); + tree op0 = (*valueize) (arg0); + tree op1 = (*valueize) (arg1); if (TREE_CODE (op0) != INTEGER_CST || TREE_CODE (op1) != INTEGER_CST) - return NULL_TREE; - tree res = fold_binary_loc (loc, subcode, - TREE_TYPE (gimple_call_arg (stmt, 0)), - op0, op1); + { + switch (subcode) + { + case MULT_EXPR: + /* x * 0 = 0 * x = 0 without overflow. */ + if (integer_zerop (op0) || integer_zerop (op1)) + return build_zero_cst (TREE_TYPE (arg0)); + break; + case MINUS_EXPR: + /* y - y = 0 without overflow. */ + if (operand_equal_p (op0, op1, 0)) + return build_zero_cst (TREE_TYPE (arg0)); + break; + default: + break; + } + } + tree res + = fold_binary_loc (loc, subcode, TREE_TYPE (arg0), op0, op1); if (res && TREE_CODE (res) == INTEGER_CST && !TREE_OVERFLOW (res)) -- cgit v1.2.3