Hello!

> This patch implements what I understood from Joseph's
> https://gcc.gnu.org/ml/gcc/2013-10/msg00280.html
> and also adds clang compatible builtins (which implement
> small subset of the typegeneric ones).
>
> Besides the clang compatibility builtins, there are 3 new
> type-generic builtins, __builtin_{add,sub,mul}_overflow, which
> have 3 arguments, two arbitrary integral arguments, and pointer
> to some integer type.  These builtins extend both arguments
> to infinite precision signed arguments, perform {+,-,*} operations
> in the infinite precision and finally cast the result to the type
> pointed by the third argument and store the result there (modulo
> 2^precision of the type).  If the infinite precision result is equal
> to the stored value, the built-ins return false (no overflow), otherwise
> they return true.
>
> The built-ins are folded immediately into internal functions that return
> both results (integer result and boolean overflow flag) as _Complex integer
> result, so that the integer result doesn't have to be addressable.
> It partly reuses code to emit -fsanitize=signed-integer-overflow internal
> functions, for signed overflows on e.g. i?86 will use jo/jno/seto/setno
> instructions after the arithmetic instructions; for imsogmed arithmetic
> overflow, combiner manages to transform what is emitted into
> jc/jnc/setc/setnc where possible.
>
> After discussions with Richard on IRC, the internal functions have
> arbitrary integral arguments, which can have different or same signs,
> different or same precisions, and the result type is _Complex integer
> derived from the call's third argument.  gimple-fold.c and tree-vrp.c
> is tought to perform some optimizations on these, and most of the smarts
> are performed during expansion (many of the 16 different +/-
> signarg1/signarg2/signresult cases require different code, and for *
> there are also a couple of different cases).
> If somebody can come up with some shorter sequence how to test for the
> less common cases, I'd appreciate hints (internal-fn.c has big comments
> which explain how it now computes the integral result and especially
> the overflow flag).
>
> Bootstrapped/regtested on x86_64-linux and i686-linux (on top of the ICF
> gimple_call fix I've mailed a few minutes ago), ok for trunk?
>
> 2014-11-10  Jakub Jelinek  <ja...@redhat.com>
>
> PR c/59708
> * builtin-attrs.def (ATTR_NOTHROW_TYPEGENERIC_LEAF): New attribute.
> * builtins.c (fold_builtin_arith_overflow): New function.
> (fold_builtin_3): Use it.
> * builtins.def (BUILT_IN_ADD_OVERFLOW, BUILT_IN_SUB_OVERFLOW,
> BUILT_IN_MUL_OVERFLOW, BUILT_IN_SADD_OVERFLOW,
> BUILT_IN_SADDL_OVERFLOW, BUILT_IN_SADDLL_OVERFLOW,
> BUILT_IN_SSUB_OVERFLOW, BUILT_IN_SSUBL_OVERFLOW,
> BUILT_IN_SSUBLL_OVERFLOW, BUILT_IN_SMUL_OVERFLOW,
> BUILT_IN_SMULL_OVERFLOW, BUILT_IN_SMULLL_OVERFLOW,
> BUILT_IN_UADDL_OVERFLOW, BUILT_IN_UADDLL_OVERFLOW,
> BUILT_IN_USUB_OVERFLOW, BUILT_IN_USUBL_OVERFLOW,
> BUILT_IN_USUBLL_OVERFLOW, BUILT_IN_UMUL_OVERFLOW,
> BUILT_IN_UMULL_OVERFLOW, BUILT_IN_UMULLL_OVERFLOW): New built-in functions.
> * builtin-types.def (BT_PTR_UINT, BT_PTR_ULONG, BT_PTR_LONGLONG,
> BT_FN_BOOL_INT_INT_INTPTR, BT_FN_BOOL_LONG_LONG_LONGPTR,
> BT_FN_BOOL_LONGLONG_LONGLONG_LONGLONGPTR,
> BT_FN_BOOL_UINT_UINT_UINTPTR, BT_FN_BOOL_ULONG_ULONG_ULONGPTR,
> BT_FN_BOOL_ULONGLONG_ULONGLONG_ULONGLONGPTR, BT_FN_BOOL_VAR): New.
> * expr.c (write_complex_part): Remove prototype, no longer static.
> * expr.h (write_complex_part): New prototype.
> * function.c (aggregate_value_p): For internal functions return 0.
> * gimple-fold.c (arith_overflowed_p, find_non_realpart_uses): New functions.
> (gimple_fold_call): Fold {ADD,SUB,MUL}_OVERFLOW internal calls.
> * gimple-fold.h (arith_overflowed_p): New prototype.
> * gimplify.c (gimplify_call_expr): Handle gimplification of internal calls 
> with lhs.
> * internal-fn.c (get_range_pos_neg, get_min_precision,
> expand_arith_overflow_result_store): New functions.
> (ubsan_expand_si_overflow_addsub_check): Renamed to ...
> (expand_addsub_overflow): ... this.  Add LOC, LHS, ARG0, ARG1,
> UNSR_P, UNS0_P, UNS1_P, IS_UBSAN arguments, remove STMT argument.
> Handle ADD_OVERFLOW and SUB_OVERFLOW expansion.
> (ubsan_expand_si_overflow_neg_check): Renamed to ...
> (expand_neg_overflow): ... this.  Add LOC, LHS, ARG1, IS_UBSAN
> arguments, remove STMT argument.  Handle SUB_OVERFLOW with
> 0 as first argument expansion.
> (ubsan_expand_si_overflow_mul_check): Renamed to ...
> (expand_mul_overflow): ... this.  Add LOC, LHS, ARG0, ARG1,
> UNSR_P, UNS0_P, UNS1_P, IS_UBSAN arguments, remove STMT argument.
> Handle MUL_OVERFLOW expansion.
> (expand_UBSAN_CHECK_ADD): Use expand_addsub_overflow, prepare
> arguments for it.
> (expand_UBSAN_CHECK_SUB): Use expand_addsub_overflow or
> expand_neg_overflow, prepare arguments for it.
> (expand_UBSAN_CHECK_MUL): Use expand_mul_overflow, prepare arguments
> for it.
> (expand_arith_overflow, expand_ADD_OVERFLOW, expand_SUB_OVERFLOW,
> expand_MUL_OVERFLOW): New functions.
> * internal-fn.def (ADD_OVERFLOW, SUB_OVERFLOW, MUL_OVERFLOW): New
> internal functions.
> * tree-vrp.c (check_for_binary_op_overflow): New function.
> (extract_range_basic): Handle {REAL,IMAG}PART_EXPR if the operand
> is SSA_NAME set by {ADD,SUB,MUL}_OVERFLOW internal functions.
> (simplify_internal_call_using_ranges): Handle {ADD,SUB,MUL}_OVERFLOW
> internal functions.
> * optabs.def (umulv4_optab): New optab.
> * config/i386/i386.md (umulv<mode>4, <u>mulvqi4): New define_expands.
> (*umulv<mode>4, *<u>mulvqi4): New define_insns.
> * doc/extend.texi (Integer Overflow Builtins): Document
> __builtin_*_overflow.
> c-family/
> * c-common.c (check_builtin_function_arguments): Handle
> BUILT_IN_{ADD,SUB,MUL}_OVERFLOW.
> testsuite/
> * c-c++-common/builtin-arith-overflow-1.c: New test.
> * c-c++-common/torture/builtin-arith-overflow-10.c: New test.
> * c-c++-common/torture/builtin-arith-overflow-11.c: New test.
> * c-c++-common/torture/builtin-arith-overflow-12.c: New test.
> * c-c++-common/torture/builtin-arith-overflow-12.h: New file.
> * c-c++-common/torture/builtin-arith-overflow-13.c: New test.
> * c-c++-common/torture/builtin-arith-overflow-14.c: New test.
> * c-c++-common/torture/builtin-arith-overflow-15.c: New test.
> * c-c++-common/torture/builtin-arith-overflow-16.c: New test.
> * c-c++-common/torture/builtin-arith-overflow-17.c: New test.
> * c-c++-common/torture/builtin-arith-overflow-18.c: New test.
> * c-c++-common/torture/builtin-arith-overflow-1.c: New test.
> * c-c++-common/torture/builtin-arith-overflow-1.h: New file.
> * c-c++-common/torture/builtin-arith-overflow-2.c: New test.
> * c-c++-common/torture/builtin-arith-overflow-3.c: New test.
> * c-c++-common/torture/builtin-arith-overflow-4.c: New test.
> * c-c++-common/torture/builtin-arith-overflow-5.c: New test.
> * c-c++-common/torture/builtin-arith-overflow-6.c: New test.
> * c-c++-common/torture/builtin-arith-overflow-7.c: New test.
> * c-c++-common/torture/builtin-arith-overflow-8.c: New test.
> * c-c++-common/torture/builtin-arith-overflow-9.c: New test.
> * c-c++-common/torture/builtin-arith-overflow.h: New file.
> * gcc.dg/builtin-arith-overflow-1.c: New test.
> * gcc.dg/builtin-arith-overflow-2.c: New test.

x86 part is OK.

Thanks,
Uros.

Reply via email to