Changeset: 003e2634d3bf for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/003e2634d3bf Modified Files: gdk/gdk_aggr.c gdk/gdk_calc_private.h gdk/gdk_join.c Branch: nilmask Log Message:
Checkpoint: use builtins to check for unsigned overflow. diffs (truncated from 364 to 300 lines): diff --git a/gdk/gdk_aggr.c b/gdk/gdk_aggr.c --- a/gdk/gdk_aggr.c +++ b/gdk/gdk_aggr.c @@ -440,9 +440,9 @@ dofsum(const void *restrict values, oid TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) { \ x = vals[ci->seq + i - seqb]; \ ADDI_WITH_CHECK(x, sum, \ - TYPE2, sum, \ - GDK_##TYPE2##_max, \ - goto overflow); \ + TYPE2, sum, \ + GDK_##TYPE2##_max, \ + goto overflow); \ } \ TIMEOUT_CHECK(qry_ctx, \ GOTO_LABEL_TIMEOUT_HANDLER(bailout, qry_ctx)); \ @@ -458,9 +458,9 @@ dofsum(const void *restrict values, oid } \ } else { \ ADDI_WITH_CHECK(x, sum, \ - TYPE2, sum, \ - GDK_##TYPE2##_max, \ - goto overflow); \ + TYPE2, sum, \ + GDK_##TYPE2##_max, \ + goto overflow); \ seenval = true; \ } \ } \ @@ -486,9 +486,9 @@ dofsum(const void *restrict values, oid } \ } else { \ ADDI_WITH_CHECK(x, sum, \ - TYPE2, sum, \ - GDK_##TYPE2##_max, \ - goto overflow); \ + TYPE2, sum, \ + GDK_##TYPE2##_max, \ + goto overflow); \ seenval = true; \ } \ } \ @@ -715,7 +715,7 @@ dofsum(const void *restrict values, oid sum = 0; \ TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) { \ x = vals[ci->seq + i - seqb]; \ - ADD_WITH_CHECK(x, sum, \ + ADDU_WITH_CHECK(x, sum, \ TYPE2, sum, \ GDK_##TYPE2##_max, \ goto overflow); \ @@ -730,10 +730,10 @@ dofsum(const void *restrict values, oid sum = 0; \ TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) { \ x = vals[canditer_next(ci) - seqb]; \ - ADD_WITH_CHECK(x, sum, \ - TYPE2, sum, \ - GDK_##TYPE2##_max, \ - goto overflow); \ + ADDU_WITH_CHECK(x, sum, \ + TYPE2, sum, \ + GDK_##TYPE2##_max, \ + goto overflow); \ } \ TIMEOUT_CHECK(qry_ctx, \ GOTO_LABEL_TIMEOUT_HANDLER(bailout, qry_ctx)); \ @@ -746,7 +746,7 @@ dofsum(const void *restrict values, oid (gids[i] >= min && gids[i] <= max)) { \ gid = gids ? gids[i] - min : (oid) i; \ x = vals[ci->seq + i - seqb]; \ - ADD_WITH_CHECK( \ + ADDU_WITH_CHECK( \ x, \ sums[gid], \ TYPE2, \ @@ -766,7 +766,7 @@ dofsum(const void *restrict values, oid (gids[i] >= min && gids[i] <= max)) { \ gid = gids ? gids[i] - min : (oid) i; \ x = vals[i]; \ - ADD_WITH_CHECK( \ + ADDU_WITH_CHECK( \ x, \ sums[gid], \ TYPE2, \ @@ -1560,7 +1560,7 @@ BATsum(void *res, int tp, BAT *b, BAT *s else \ gid = (oid) i; \ } \ - MUL4_WITH_CHECK( \ + MULU4_WITH_CHECK( \ vals[i], \ prods[gid], \ TYPE2, prods[gid], \ @@ -3895,9 +3895,9 @@ BATgroupavg3combine(BAT *avg, BAT *rem, if (is_##TYPE##_nil(x)) \ continue; \ ADDI_WITH_CHECK(x, sum, \ - lng_hge, sum, \ - GDK_##lng_hge##_max, \ - goto overflow##TYPE); \ + lng_hge, sum, \ + GDK_##lng_hge##_max, \ + goto overflow##TYPE); \ /* don't count value until after overflow check */ \ n++; \ } \ @@ -3951,10 +3951,10 @@ BATgroupavg3combine(BAT *avg, BAT *rem, TIMEOUT_LOOP(ci.ncand, qry_ctx) { \ i = canditer_next(&ci) - b->hseqbase; \ x = ((const TYPE *) src)[i]; \ - ADD_WITH_CHECK(x, sum, \ - lng_hge, sum, \ - GDK_##lng_hge##_max, \ - goto overflow##TYPE); \ + ADDU_WITH_CHECK(x, sum, \ + lng_hge, sum, \ + GDK_##lng_hge##_max, \ + goto overflow##TYPE); \ /* don't count value until after overflow check */ \ n++; \ } \ diff --git a/gdk/gdk_calc_private.h b/gdk/gdk_calc_private.h --- a/gdk/gdk_calc_private.h +++ b/gdk/gdk_calc_private.h @@ -44,6 +44,12 @@ on_overflow; \ } \ } while (0) +#define UOP_WITH_CHECK(lft, rgt, dst, op, max, on_overflow) \ + do { \ + if (__builtin_##op##_overflow(lft, rgt, &(dst))) { \ + on_overflow; \ + } \ + } while (0) #endif #endif @@ -71,11 +77,21 @@ /* integer version using Gnu CC builtin function for overflow check */ #define ADDI_WITH_CHECK(lft, rgt, TYPE3, dst, max, on_overflow) \ OP_WITH_CHECK(lft, rgt, dst, add, max, on_overflow) +#define ADDU_WITH_CHECK(lft, rgt, TYPE3, dst, max, on_overflow) \ + UOP_WITH_CHECK(lft, rgt, dst, add, max, on_overflow) #else /* integer version using generic version */ #define ADDI_WITH_CHECK(lft, rgt, TYPE3, dst, max, on_overflow) \ ADD_WITH_CHECK(lft, rgt, TYPE3, dst, max, on_overflow) -#endif /* HAVE___BUILTIN_ADD_OVERFLOW */ +#define ADDU_WITH_CHECK(lft, rgt, TYPE3, dst, max, on_overflow) \ + do { \ + if ((max) - (rgt) < (lft)) { \ + on_overflow; \ + } else { \ + (dst) = (TYPE3) (lft) + (rgt); \ + } \ + } while (0) +#endif /* floating point version using generic version */ #define ADDF_WITH_CHECK(lft, rgt, TYPE3, dst, max, on_overflow) \ @@ -105,11 +121,21 @@ /* integer version using Gnu CC builtin function for overflow check */ #define SUBI_WITH_CHECK(lft, rgt, TYPE3, dst, max, on_overflow) \ OP_WITH_CHECK(lft, rgt, dst, sub, max, on_overflow) +#define SUBU_WITH_CHECK(lft, rgt, TYPE3, dst, max, on_overflow) \ + UOP_WITH_CHECK(lft, rgt, dst, sub, max, on_overflow) #else /* integer version using generic version */ #define SUBI_WITH_CHECK(lft, rgt, TYPE3, dst, max, on_overflow) \ SUB_WITH_CHECK(lft, rgt, TYPE3, dst, max, on_overflow) -#endif /* HAVE___BUILTIN_ADD_OVERFLOW */ +#define SUBU_WITH_CHECK(lft, rgt, TYPE3, dst, max, on_overflow) \ + do { \ + if ((rgt) > (lft)) { \ + on_overflow; \ + } else { \ + (dst) = (TYPE3) (lft) - (rgt); \ + } \ + } while (0) +#endif /* floating point version using generic version */ #define SUBF_WITH_CHECK(lft, rgt, TYPE3, dst, max, on_overflow) \ @@ -132,21 +158,37 @@ /* integer version using Gnu CC builtin function for overflow check */ #define MULI4_WITH_CHECK(lft, rgt, TYPE3, dst, max, TYPE4, on_overflow) \ OP_WITH_CHECK(lft, rgt, dst, mul, max, on_overflow) +#define MULU4_WITH_CHECK(lft, rgt, TYPE3, dst, max, TYPE4, on_overflow) \ + OP_WITH_CHECK(lft, rgt, dst, mul, max, on_overflow) #define LNGMUL_CHECK(lft, rgt, dst, max, on_overflow) \ OP_WITH_CHECK(lft, rgt, dst, mul, max, on_overflow) #else /* integer version using generic version */ #define MULI4_WITH_CHECK(lft, rgt, TYPE3, dst, max, TYPE4, on_overflow) \ MUL4_WITH_CHECK(lft, rgt, TYPE3, dst, max, TYPE4, on_overflow) +#define MULU4_WITH_CHECK(lft, rgt, TYPE3, dst, max, TYPE4, on_overflow) \ + do { \ + TYPE4 c = (TYPE4) (lft) * (rgt); \ + if (c > (TYPE4) (max)) { \ + on_overflow; \ + } else { \ + (dst) = (TYPE3) c; \ + } \ + } while (0) #ifdef HAVE_HGE #define LNGMUL_CHECK(lft, rgt, dst, max, on_overflow) \ MULI4_WITH_CHECK(lft, rgt, lng, dst, max, hge, on_overflow) +#define LNGMULU_CHECK(lft, rgt, dst, max, on_overflow) \ + MULU4_WITH_CHECK(lft, rgt, lng, dst, max, hge, on_overflow) #elif defined(HAVE___INT128) #define LNGMUL_CHECK(lft, rgt, dst, max, on_overflow) \ MULI4_WITH_CHECK(lft, rgt, lng, dst, max, __int128, on_overflow) +#define LNGMULU_CHECK(lft, rgt, dst, max, on_overflow) \ + MULU4_WITH_CHECK(lft, rgt, lng, dst, max, hge, on_overflow) #elif defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER) #include <intrin.h> #pragma intrinsic(_mul128) +#pragma intrinsic(_umul128) #define LNGMUL_CHECK(lft, rgt, dst, max, on_overflow) \ do { \ __int64 clo, chi; \ @@ -158,6 +200,16 @@ on_overflow; \ } \ } while (0) +#define LNGMULU_CHECK(lft, rgt, dst, max, on_overflow) \ + do { \ + unsigned __int64 clo, chi; \ + clo = _umul128((unsigned __int64) (lft), (unsigned __int64) (rgt), &chi); \ + if (chi == 0 /*&& clo <= (max)*/) { \ + (dst) = (ulng) clo; \ + } else { \ + on_overflow; \ + } \ + } while (0) #else #define LNGMUL_CHECK(lft, rgt, dst, max, on_overflow) \ do { \ @@ -188,6 +240,26 @@ on_overflow; \ } \ } while (0) +#define LNGMULU_CHECK(lft, rgt, dst, max, on_overflow) \ + do { \ + ulng a = (lft), b = (rgt); \ + unsigned int a1, a2, b1, b2; \ + ulng c; \ + \ + a1 = (unsigned int) (a >> 32); \ + a2 = (unsigned int) a; \ + b1 = (unsigned int) (b >> 32); \ + b2 = (unsigned int) b; \ + /* result = (a1*b1<<64) + (a1*b2+a2*b1<<32) + a2*b2 */ \ + if ((a1 == 0 || b1 == 0) && \ + ((c = (ulng) a1 * b2 + (ulng) a2 * b1) & (~(ulng)0 << 31)) == 0 && \ + (((c = (c << 32) + (ulng) a2 * b2) & ((ulng) 1 << 63)) == 0 && \ + (c) <= (ulng) (max))) { \ + (dst) = (ulng) c; \ + } else { \ + on_overflow; \ + } \ + } while (0) #endif /* HAVE_HGE */ #endif #define MULF4_WITH_CHECK(lft, rgt, TYPE3, dst, max, TYPE4, on_overflow) \ @@ -227,7 +299,7 @@ on_overflow; \ } \ } while (0) -#endif /* HAVE___BUILTIN_ADD_OVERFLOW */ +#endif #endif /* HAVE_HGE */ #define AVERAGE_ITER(TYPE, x, a, r, n) \ diff --git a/gdk/gdk_join.c b/gdk/gdk_join.c --- a/gdk/gdk_join.c +++ b/gdk/gdk_join.c @@ -4872,19 +4872,19 @@ BATbandjoin(BAT **r1p, BAT **r2p, BAT *l continue; lng v1, v2; SUBI_WITH_CHECK(*(const lng *)vr, - *(const lng *)c1, - lng, v1, - GDK_lng_max, - do{if(*(const lng*)c1<0)goto nolmatch;else goto lmatch1;}while(false)); + *(const lng *)c1, + lng, v1, + GDK_lng_max, + do{if(*(const lng*)c1<0)goto nolmatch;else goto lmatch1;}while(false)); if (*(const lng *)vl <= v1 && (!linc || *(const lng *)vl != v1)) continue; lmatch1: - ADDI_WITH_CHECK(*(const lng *)vr, - *(const lng *)c2, - lng, v2, - GDK_lng_max, - do{if(*(const lng*)c2>0)goto nolmatch;else goto lmatch2;}while(false)); + ADDI_WITH_CHECK(*(const lng *)vr, + *(const lng *)c2, _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org