On Tue, Jul 28, 2015 at 2:08 PM, Tom de Vries <tom_devr...@mentor.com> wrote: > On 28/07/15 09:59, Richard Biener wrote: >> >> On Fri, Jul 24, 2015 at 4:39 PM, Tom de Vries <tom_devr...@mentor.com> >> wrote: >>> >>> Hi, >>> >>> this patch allows parallelization and vectorization of reduction >>> operators >>> that are guaranteed to not overflow (such as min and max operators), >>> independent of the overflow behaviour of the type. >>> >>> Bootstrapped and reg-tested on x86_64. >>> >>> OK for trunk? >> >> >> Hmm, I don't like that no_overflow_tree_code function. We have a much >> more >> clear understanding which codes may overflow or trap. Thus please add >> a operation specific variant of TYPE_OVERFLOW_{TRAPS,WRAPS,UNDEFINED} like >> > > Done. > >> bool >> operation_overflow_traps (tree type, enum tree_code code) >> { >> if (!ANY_INTEGRAL_TYPE_P (type) > > > I've changed this test into a gcc_checking_assert. > > >> || !TYPE_OVERFLOW_TRAPS (type)) >> return false; >> switch (code) >> { >> case PLUS_EXPR: >> case MINUS_EXPR: >> case MULT_EXPR: >> case LSHIFT_EXPR: >> /* Can overflow in various ways */ >> case TRUNC_DIV_EXPR: >> case EXACT_DIV_EXPR: >> case FLOOR_DIV_EXPR: >> case CEIL_DIV_EXPR: >> /* For INT_MIN / -1 */ >> case NEGATE_EXPR: >> case ABS_EXPR: >> /* For -INT_MIN */ >> return true; >> default: >> return false; >> } >> } >> >> and similar variants for _wraps and _undefined. I think we decided at >> some point >> the compiler should not take advantage of the fact that lshift or >> *_div have undefined >> behavior on signed integer overflow, similar we only take advantage of >> integral-type >> overflow behavior, not vector or complex. So we could reduce the >> number of cases >> the functions return true if we document that it returns true only for >> the cases where >> the compiler needs to / may assume wrapping behavior does not take place. >> As for _traps for example we only have optabs and libfuncs for >> plus,minus,mult,negate >> and abs. > > > I've tried to capture all of this in the three new functions: > - operation_overflows_and_traps > - operation_no_overflow_or_wraps > - operation_overflows_and_undefined (unused atm) > > I've also added the graphite bit. > > OK for trunk, if bootstrap and reg-test succeeds?
+/* Returns true if CODE operating on operands of type TYPE can overflow, and + fwrapv generates trapping insns for CODE. */ ftrapv +bool +operation_overflows_and_traps (tree type, enum tree_code code) +{ operation_overflow_traps is better wording. Meaning that when the operation overflows then it traps. + /* We don't take advantage of integral type overflow behaviour for complex and + vector types. */ We don't generate instructions that trap on overflow for complex or vector types + if (!INTEGRAL_TYPE_P (type)) + return true; + switch (code) + { + case PLUS_EXPR: + case MINUS_EXPR: + case MULT_EXPR: + case LSHIFT_EXPR: + /* Can overflow in various ways. */ we don't have a trapping optab for lshift + case TRUNC_DIV_EXPR: + case EXACT_DIV_EXPR: + case FLOOR_DIV_EXPR: + case CEIL_DIV_EXPR: nor division. See optabs.c:optab_for_tree_code. I suggest to only return true for those. +/* Returns true if CODE operating on operands of type TYPE cannot overflow, or + wraps on overflow. */ + +bool +operation_no_overflow_or_wraps (tree type, enum tree_code code) +{ + gcc_checking_assert (ANY_INTEGRAL_TYPE_P (type)); operation_overflow_wraps () is still my preferred name. +bool +operation_overflow_and_undefined (tree type, enum tree_code code) +{ + gcc_checking_assert (ANY_INTEGRAL_TYPE_P (type)); + operation_overflow_undefined () If you like to keep an explicit operation_can_overflow then there is the opportunity to split out the switch statement from operation_overflow_wraps and operation_overflow_undefined. Thanks, Richard. > Thanks, > - Tom