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 -- [email protected]
To unsubscribe send an email to [email protected]
